選自adeshpande3
機器之心編譯
每隔幾周,加利福尼亞大學洛杉磯分校(UCLA)的 Adit Deshpande 就會在其博客上發(fā)表一篇深度解讀的深度學習研究回顧博客。今天這篇是 Adit 的這一系列的第三篇博客,將主要介紹深度學習在自然語言處理當中的應用。
自然語言處理簡介
自然語言處理(NLP)是創(chuàng)造能夠處理或是「理解」語言以完成特定的任務(wù)的系統(tǒng)。這些任務(wù)可能包括:
問答系統(tǒng)(也就是Siri、 Alexa和小娜所做的事情)
情感分析(判斷一句話隱含的積極或消極意義)
圖片題注(為輸入的圖像生成一個標題)
機器翻譯(將一段文本翻譯成另一種語言)
語音識別
詞性標注
命名實體識別
傳統(tǒng)的自然語言處理方法涉及到了很多語言學本身的知識。理解諸如音素(phonemes)和語素(morphemes)等術(shù)語都是非常必須的,為了學習這些專業(yè)知識,還要學習完整的語言學課程。接下來讓我們看一些傳統(tǒng)的自然語言處理是如何理解下面這一單詞的。
假設(shè)我們的目標是要收集關(guān)于這一單詞的一些信息(描述它的情感、尋找它的定義等)。利用我們在語言上的專業(yè)知識,我們把這個單詞分為三部分。
我們知道這個單詞的前綴「un」表示的是一種相對立的或是相反的概念,「ed」能夠限定這個單詞的時態(tài)(過去時)。通過對這個單詞主干部分「interest」的理解,我們能夠很容易地推斷出整個單詞的意思和情感??雌饋硎遣皇欠浅5睾唵??但是,當你要考慮到英語中所有不同的前綴和后綴的時候,可能就需要一位非常有技巧的語言學家才能理解所有可能的組合和意義。
如何將深度學習應用其中
深度學習,從其最基本的層面來說,是表征學習(representation learning)的一種方法。利用卷積神經(jīng)網(wǎng)絡(luò),我們可以看到用來對事物進行分類的不同過濾器的組成。在這里,我們將要采取一種類似的方法,利用大數(shù)據(jù)集為詞匯創(chuàng)造表征。
本文概述
這篇文章中,首先我們將了解為自然語言處理建立深度網(wǎng)絡(luò)的基本構(gòu)建模塊,之后將對最近研究論文的一些應用進行討論。大多數(shù)人都不明確了解為什么我們要使用循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)或者是長短期記憶(LSTM)為什么會有用,但是我希望在我們討論完研究論文之后,你可以對為什么深度學習會為自然語言處理提供這么大的幫助有更好的理解。
詞向量
因為深度學習和數(shù)學密不可分,我們將要把每一個單詞都表征為一個d維向量。我們將d設(shè)定為6。
現(xiàn)在讓我們想一想該如何填寫值。我們希望填寫值的方式可以讓向量表征詞,以及詞的語境、意思或語義。一種方法就是建立一個共生矩陣(coocurence matrix)。以下面這一句話為例。
在這一句話中,我們想要給每一個詞都建立一個詞向量。
共生矩陣中包含了在語料庫(或是訓練集)中每一個詞出現(xiàn)在其他詞語旁邊的次數(shù)。讓我們看看下面這個矩陣。
將這個矩陣的行提取出來能夠讓我們對詞向量有一個簡單的初始化。
注意,通過這個簡單的矩陣,我們將能收獲非常有用的見解。例如,注意「love」和「like」,這兩個詞與名詞(NLP 和dogs)相連的次數(shù)都是1。和「I」相連的次數(shù)也是1,所以這表明這兩個單詞一定是動詞。如果說我們擁有更大的數(shù)據(jù)集,而不是簡單的一句話,你可以想象,這種相似性就會變得越來越明顯,就像是「love」和「like」一樣,其它的一些同義詞也會開始擁有相似的詞向量,因為它們一般都會在相似的語境下使用。
現(xiàn)在,雖然我們的起點很好,但是我們也注意到每一個詞的維度都會隨著語料庫的擴大直線上升。如果我們有100萬個詞(在自然語言處理的標準中不算多),我們就會有100萬乘以100萬大小的矩陣,而且這一矩陣會非常的稀疏(有很多的0)。從存儲效率來看這一定不是最好的。在尋找表征這些詞向量的最優(yōu)方法中也存在著很多的先進技術(shù)。其中最著名的就是Word2Vec。
Word2Vec
詞向量初始化技術(shù)的基本思路就是要在詞向量中儲存盡可能多的信息,同時也要將維度控制在一個可以管理的范圍之內(nèi)(25 – 1000維是理想的)。Word2Vec讓我們可以預測每一個單詞周圍的單詞。還是以我們之前提到的句子「I love NLP and I like dogs.」為例。我們首先來看一看這句話的前三個單詞,因此我們就要把我們的窗口大小m設(shè)置為3.
現(xiàn)在,我們的目標是提取中心詞「love」,然后預測可能在這個詞之前或之后出現(xiàn)的詞。我們應該怎么做呢?通過將一個函數(shù)最大化/最優(yōu)化!一般來說,我們的函數(shù)都會將現(xiàn)有中心詞的上下文單詞的對數(shù)概率最大化。
讓我們再做一些更深入的了解。上文中的成本函數(shù)基本上是在說我們要增加「I」和「love」以及「NLP」和「love」的對數(shù)概率(love在兩種情形當中都是中心詞)。變量T代表的是訓練句子的數(shù)量。讓我們再來了解一下對數(shù)概率。
Vc是中心詞的詞向量。每一個單詞都有兩次向量表征(Uo 和 Uw),其中一個是當單詞作為中心詞時,另一個是當單詞用作外部詞語時。這些向量都經(jīng)過隨機梯度下降法的訓練。這一定是令人困惑的方程式之一,也是我們需要理解的,所以如果你還是難以想象正在發(fā)生的事情,你可以查看更多的資源加以了解。
一言以蔽之:在給定一個中心詞的情況下,Word2Vec 通過最大化上下文單詞的對數(shù)概率并通過隨機梯度下降(SGD)來修改向量,試圖找到不同詞的向量表征。
注:論文《Distributed Representations of Words and Phrases and their Compositionality》談到了更多細節(jié):常見詞的負采樣和子采樣能如何被用于獲取更精確的詞向量。)
Word2Vec 的最有趣的貢獻在于展現(xiàn)出不同詞向量之間的線性關(guān)系。訓練后,詞向量似乎捕捉到了不同語法和語義概念。
難以置信的是,這些線性關(guān)聯(lián)可以如何通過一個簡單的目標函數(shù)和優(yōu)化技巧得以形成。
福利:另一個很酷的詞向量初始化方式:GloVe(將共生矩陣與Word2Vec結(jié)合起來):http://nlp.stanford.edu/pubs/glove.pdf
循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)
現(xiàn)在我們已經(jīng)擁有詞向量了,然后看看它們是如何擬合循環(huán)神經(jīng)網(wǎng)絡(luò)的。循環(huán)神經(jīng)網(wǎng)絡(luò)現(xiàn)在已是大多數(shù)自然語言處理(NLP)的必需品。循環(huán)神經(jīng)網(wǎng)絡(luò)最大的優(yōu)點是它能有效地使用先前時間步驟的數(shù)據(jù)。這就是一小塊循環(huán)神經(jīng)網(wǎng)絡(luò)大概的樣子。
在底部我們有詞向量(xt,xt-1,xt+1)。每一個向量在同一時間步驟(ht, ht-1,ht+1)有一個隱藏狀態(tài)向量(hidden state vector)。我們稱這些為一個模塊。
循環(huán)神經(jīng)網(wǎng)絡(luò)每個模塊中的隱藏狀態(tài)是前一時間步驟(previous time step)的隱藏狀態(tài)向量和詞向量的函數(shù):
如果仔細看看上標,你會發(fā)現(xiàn)有一個權(quán)重矩陣Whx,我們會將Whx矩陣與輸入相乘,并且會有一個循環(huán)權(quán)重的矩陣(recurrent weight matrix)Whh乘以在前一時間步驟的隱藏狀態(tài)向量。切記這些循環(huán)權(quán)重矩陣在所有時間步驟都是相同的,這也是循環(huán)神經(jīng)網(wǎng)絡(luò)的關(guān)鍵點。仔細想想,這和傳統(tǒng)兩層神經(jīng)網(wǎng)絡(luò)有很大的不同。傳統(tǒng)情況下,我們每一層(W1和W2)通常會有不同的權(quán)重矩陣W,而這里的循環(huán)權(quán)重矩陣在整個網(wǎng)絡(luò)中都是相同的。
要得到特定模塊的輸出(Yhat),就需要將h乘以WS,這是另外一個權(quán)重矩陣。
現(xiàn)在我們退一步,了解循環(huán)神經(jīng)網(wǎng)絡(luò)的優(yōu)點在哪。與傳統(tǒng)神經(jīng)網(wǎng)絡(luò)最大的不同就是循環(huán)神經(jīng)網(wǎng)絡(luò)可以接收輸入序列(我們例子中的詞)。你可以將其與典型的卷積神經(jīng)網(wǎng)絡(luò)對比,其只能是將單一圖片作為輸入。然而使用循環(huán)神經(jīng)網(wǎng)絡(luò),輸入可以小到短句,大到有 5 個段落的文章。此外,該輸入的序列順序能極大地影響到權(quán)重矩陣和隱藏向量在訓練中如何改變。隱藏狀態(tài)在訓練后期望能從過去(前面的時間步驟)獲取信息。
門控循環(huán)單元(GRU)
現(xiàn)在讓我們看一個門控循環(huán)單元(gated recurrent unit/GRU)。這個單元的目標是提供一種更復雜的方法來計算我們在循環(huán)神經(jīng)網(wǎng)絡(luò)中的隱藏狀態(tài)向量(hidden state vectors )。這種方法將允許我們儲存信息并捕獲長距依賴性(long distance dependencies)。讓我們想象下為什么長期依賴性(long term dependencies)在傳統(tǒng)的循環(huán)神經(jīng)網(wǎng)絡(luò)構(gòu)架中存在問題。在反向傳播中,誤差將流經(jīng)循環(huán)神經(jīng)網(wǎng)絡(luò),從最近的時間步驟到最早的時間步驟。如果初始梯度是較小的數(shù)字(如小于0.25),那么在通過第三或第四模塊時,梯度實際上會消失(鏈式規(guī)則與梯度一起乘積),因此較早時間步驟的隱藏狀態(tài)將不會更新 。
在傳統(tǒng)循環(huán)神經(jīng)網(wǎng)絡(luò)中,隱藏狀態(tài)向量是通過該公式計算的:
GRU提供了一個不同的方式計算隱藏狀態(tài)向量h(t),該計算分為三個分量,一個更新門(update gate)、一個重置門(reset gate)和一個新的記憶存儲器(memory container)。兩個門都是輸入詞向量和在前時間步驟的隱藏狀態(tài)函數(shù):
關(guān)鍵區(qū)別是每個門使用不同的權(quán)重,這由不同上標來表示。 更新門(update gate)使用Wz和Uz,而重置門(reset gate)使用Wr和Ur。
現(xiàn)在,新的記憶存儲器(memory container)就是通過以下方式來計算的:
(空心點指的是Hadamard 積)
現(xiàn)在,如果仔細看看公式,你會發(fā)現(xiàn)如果重置門的值接近0,那么這整個項也會變成0,因此忽略了在先前時間步ht-1的信息。在這種情況下,計算單元僅僅只是新詞向量xt的函數(shù)。
h(t)的最終公式如下:
ht 是一個有三個部分的函數(shù):重置門、更新門以及記憶存儲器。理解這一點的最佳方式就是當 zt 接近1 以及 0 的時候,視覺化所發(fā)生的情況。當 zt 靠近1,新的隱藏層向量 ht 幾乎取決于之前的隱藏層,而且因為(1-zt) 變成 0,我們忽略了當前記憶存儲。當 zt 接近 0 時,新的隱藏層向量幾乎取決于當前記憶存儲,我們忽略了之前的隱藏層狀態(tài)。以一種直覺的方式觀察這三個組成部分,可以歸納為以下:
1.更新門(Update Gate):
如果zt趨向于1,ht就完全忽略現(xiàn)在的詞向量,僅僅只是復制前隱藏狀態(tài)(如果不是太理解,請查看ht方程并注意當zt趨向于1時,1-zt有什么改變)。
如果zt趨向于0,ht就完全忽略前一時間步驟的隱藏狀態(tài),僅僅只依賴于新的記憶存儲器。
此門控能讓模型控制前一隱藏狀態(tài)的信息多大程度上影響現(xiàn)在的隱藏狀態(tài)。
2.重置門(Reset Gate):
如果rt趨向于1,記憶存儲器將保持前一隱藏狀態(tài)的信息。
如果rt趨向于0,記憶存儲器將忽略前一隱藏狀態(tài)的信息。
此門控能允許模型在丟棄一些對未來不相干的信息。
3.記憶存儲器(Memory Container): 依賴于重置門。
一個通常用來說明 GRU 有效的例子如下:假設(shè)你遇到下面一段話
以及相關(guān)問題 What is the sum of the 2 numbers 。既然中間句子對手邊問題絕對沒有影響,但是,重置和刷新門會讓網(wǎng)絡(luò)在某種意義上“忘記”中間的句子,并學會只有特定信息(這個例子中的數(shù)字)才應修改隱藏狀態(tài)。
長短期記憶單元(LSTM)
如果你對GRU 已經(jīng)很了解了,那理解LSTM對你一定不會太難 。一個LSTM也是由一連串的門(gate)組成。
當然, 這里面涉及到更多的知識。 不過因為LSTM可以理解為GRU的衍生物,我將不會過多的分析,但如果你想更深入的了解每個門, 每個計算,你可以點擊查看Chris Olah 寫的一篇超棒的博文:http://colah.github.io/posts/2015-08-Understanding-LSTMs/ 。這篇文章是目前關(guān)于LSTM最受歡迎的教程,并且一定對你們這些想要知道其背后的工作原理的人提供很大的幫助。
比較和對比 LSTM 與 GRU
讓我們先從相似點出發(fā)。 兩者的單元組件都有一個能夠記錄長時間的詞與句子之間依賴關(guān)系的特殊函數(shù)。 這種長期依賴性, 指的是在一些情況下, 兩個詞或者詞組可能在不同的時間點出現(xiàn),但兩者間的關(guān)系對實現(xiàn)最終目標十分關(guān)鍵。 LSTM 和GRU 能夠通過一些門(gate)來忽略或者保留語句中的某種信息,從而捕捉這些依賴性。
兩者基本單元的不同處在于, 它們擁有的門(gate)的數(shù)量(GRU有兩個, LSTM有三個)。這一點將影響到輸入能夠傳遞的非線性關(guān)系個數(shù), 并且最終影響到總體的計算。 另外,GRU并沒有和LSTM的記憶單元(C_t)一樣的記憶單元。
在閱讀論文之前
這部分只是想快速做個提示:還有其它的深度模型對NLP有用。在實踐中有時使用循環(huán)神經(jīng)網(wǎng)絡(luò)和CNN,但卻不像RNN 這么流行,它是大部分深度學習NLP系統(tǒng)的支柱。現(xiàn)在,我們已經(jīng)對NLP與深度學習的關(guān)系有了足夠了解,接下來看幾篇論文。由于NLP領(lǐng)域有不同的問題(從機器翻譯到問答系統(tǒng)),所以圈內(nèi)有大量可以看的論文,但我在此文章中發(fā)現(xiàn)了3篇很有洞見的論文。2016年NLP領(lǐng)域有了極大的發(fā)展,但我們先從2015年的一篇論文開始說起。
記憶網(wǎng)絡(luò)(Memory Networks)
論文:https://arxiv.org/pdf/1410.3916v11.pdf
介紹
我們首先要討論的第一篇論文, 在問答系統(tǒng)這一子領(lǐng)域很有影響力。 這篇論文由Jason Weston, Sumit Chopra以及 Antoine Bordes撰寫,介紹了一類名為memory networks 記憶網(wǎng)絡(luò)的模型。
這一想法來自于當你想要精準地回答一個關(guān)于一篇文本的問題, 你必須要記住該文本大致的內(nèi)容。如果我來問你一個問題“RNN表示什么’”(在你已經(jīng)完全閱讀了這篇博文的前提下) 你就一定能告訴我答案。 這是因為你通過閱讀、存儲記憶,已經(jīng)吸收了這些知識。你只需要簡單的花幾秒鐘去定位這條信息, 然后把它用通順的語言表達出來。 目前, 我并不知道大腦是如何做到的, 但需要地方去存儲信息的這一想法一定是存在的。
這篇論文描述的記憶網(wǎng)絡(luò)有些特別,因為它含有一個聯(lián)想記憶(associative memory )。這種聯(lián)想記憶能夠讀寫。 值得注意的是我們在CNN或者Q網(wǎng)絡(luò)(用于強化學習)或者其它的傳統(tǒng)網(wǎng)絡(luò)中并不能找到這種類型的網(wǎng)絡(luò)。這有部分是因為問答任務(wù)很大程度上依賴于系統(tǒng)能夠建模或者追蹤長期的依賴關(guān)系,比如在一個完整的故事中記錄一個人物的進展,或者記錄時間軸上的重要事件。在CNN或者Q網(wǎng)絡(luò)中, 記憶模塊被植入在網(wǎng)絡(luò)的權(quán)重體系中,因為網(wǎng)絡(luò)需要能夠?qū)W習不同的濾波器或者將狀態(tài)映射到動作上。 初看, RNN和LSTM可能能用來實現(xiàn)這一記憶功能, 但它們通常不能記住來自過去的輸入, 而這對于問答系統(tǒng)是至關(guān)重要的。
網(wǎng)絡(luò)架構(gòu)
好的,讓我們看看這個網(wǎng)絡(luò)是如何處理給定的最初文本的。和幾乎所有的機器學習算法一樣,首先將輸入轉(zhuǎn)變成一個特性表征。這需要用到詞向量、詞性標注、解析等,這些是由程序員決定的。
下一步就是提出特征表征I(x),并允許我們的記憶 m 進行更新,從而反映出我們已經(jīng)接收到的新輸入 x。
你可以將記憶 m 視為由單個的記憶 mi 構(gòu)成的一個序列。這些單個記憶 mi 的每一個都能成為整個記憶 m 的一個函數(shù),特征表征 I(x),和\或其自身。函數(shù) G 能簡單到在單個記憶單元 mi 中僅存儲整個表征 I(x)。你能基于新輸入修改函數(shù) G ,更新過去的記憶。第三、四部包括根據(jù)問題讀取記憶,獲得一個特征表征 o, 然后將其解碼輸出一個最終答案。
函數(shù) R 可以是個 RNN,被用來將來自記憶的特征表征轉(zhuǎn)化為一個可讀的、準確的問題答案。
現(xiàn)在,進一步看看第三步。我們希望 O模塊能輸出一個特征表征,將可能的答案最好匹配給一個給定問題 x?,F(xiàn)在,這個問題會與每一單個的記憶單元進行比較,也會根據(jù)記憶單元能否好好支持問題來打分。
我們求評分函數(shù)的 argmax,找到能最好支持問題的輸出表征(你也可以取多個最高得分單元,不必限于1個)。評分函數(shù)就是計算不同問題嵌入和選中記憶單元之間的矩陣積。(欲知詳情,請閱讀論文)。當你乘以兩個詞向量以求其相似性時,你會想到這個。然后,這一輸出表征 o 會被輸入一個 RNN 或者 LSTM ,或者輸入另一個會輸出可讀結(jié)果的評分函數(shù)。
訓練方式是監(jiān)督訓練,訓練數(shù)據(jù)包括原始文本、問題、支撐句( supporting sentences)以及基底真實答案。這里是目標函數(shù)。
感興趣的讀者,下面這些論文談到了構(gòu)建這類記憶網(wǎng)絡(luò)的方法:
End to End Memory Networks (https://arxiv.org/pdf/1503.08895v5.pdf) (僅需監(jiān)督輸出,不支持句子)
Dynamic Memory Networks (https://arxiv.org/pdf/1506.07285v5.pdf)
Dynamic Coattention Networks (https://arxiv.org/pdf/1611.01604v2.pdf)(2個月前才發(fā)布,斯坦福問答數(shù)據(jù)組中獲最高得分
情感分析的樹LSTMs
論文:https://arxiv.org/pdf/1503.00075v3.pdf
介紹
下一篇論文分析了情感分析領(lǐng)域取得的進展,情感分析就是判定某個短語的語氣/意義是積極的還是消極的。更正式一點的說法,情感可以被定義為對某一狀況或時間的觀點或態(tài)度。這時,LSTMs就是情感分析網(wǎng)絡(luò)中最常用到的部件。這篇由Kai Sheng Tai, Richard Socher, and Christopher Manning 合作的論文介紹了一種將LSTMs 鏈入非線性結(jié)構(gòu)的有趣方法。
這種非線性安排背后的想法在于:自然語言具有這樣的特質(zhì),亦即單詞按某種順序排列后就變成短語。這些依據(jù)單詞順序構(gòu)成的短語所表達的意思和構(gòu)成短語的單詞的意思是不同的。為了能表征出這一特點,一個LSTM的網(wǎng)絡(luò)單元就必須被安排進一個樹結(jié)構(gòu),其中 ,不同的單元會受它們的子節(jié)點( children nodes)影響。
網(wǎng)絡(luò)架構(gòu)
Tree LSTM 和 標準 LSTM 的一個不同之處在于,后者隱藏狀態(tài)是一個關(guān)于當前輸入和之前時間步驟上的隱藏狀態(tài)的函數(shù)。不過,有了這個結(jié)構(gòu),它的隱藏狀態(tài)就是關(guān)于當前輸入及其子單元隱藏狀態(tài)的函數(shù)。
新的樹結(jié)構(gòu)會帶來一些數(shù)學上的變化,包括子單元忽略掉門。那些對細節(jié)感興趣的讀者,可以研讀這篇論文。不過我的焦點是理解這些模型會比線性的LSTM效果更好的原因。
一個Tree-LSTM,一個單獨的單元就可以吸收所有子節(jié)點的隱藏狀態(tài)。這很有趣,因為一個單元可以分別評估其子節(jié)點。訓練過程中,網(wǎng)絡(luò)能意識到一個特定的單詞(或許是情感分析中的“not”或者“very”)對句子整體情感分析的極端重要性。能給予那個節(jié)點更高一點的估值,這一能力讓網(wǎng)絡(luò)具有了很大的靈活性,也提升了網(wǎng)絡(luò)表現(xiàn)。
神經(jīng)機器翻譯
論文:https://arxiv.org/pdf/1609.08144v2.pdf
介紹
最后一篇論文講述了解決機器翻譯任務(wù)的方法。作者來自谷歌機器學習那些頗有遠見的學者們 :Jeff Dean、Greg Corrado、Orial Vinyals 等。這篇文章介紹了一種機器翻譯系統(tǒng),也是谷歌翻譯服務(wù)背后的支柱。較之谷歌之前使用的產(chǎn)品系統(tǒng),該系統(tǒng)平均降低了60%的翻譯誤差。
自動翻譯的傳統(tǒng)解決方案包括基于短語的變量匹配。這一方法需要大量語言領(lǐng)域的知識而且這一設(shè)計最終也被證實太脆弱也缺乏泛化能力。傳統(tǒng)解決方案的問題之一就是一點一點地翻譯輸入句子。結(jié)果,更有效的解決方法是一次翻譯整個句子,這種方法讓更廣泛的上下文以及更加自然的語詞再安排成為可能。
網(wǎng)絡(luò)架構(gòu)
該論文的作者介紹了一個深度 LSTM 網(wǎng)絡(luò),能夠用 8個解碼器和編碼器層進行端到端的訓練。我們能把該系統(tǒng)分解成3個組件:編碼器RNN、解碼器RNN、注意模塊。從高層級來看,編碼器要做的任務(wù)是將輸入語句轉(zhuǎn)換成向量表征,然后解碼器產(chǎn)生輸入表征,然后注意模塊提示解碼器在解碼的過程中應該注意什么(這是利用輸入語句全部語境的思路所在)。
論文的其他部分主要專注于規(guī)?;摲?wù)的挑戰(zhàn)上。計算資源量、時延、高容量部署這樣的話題都進行了長篇介紹。
結(jié)論
在此博客中,我們總結(jié)了深度學習如何幫助了自然語言處理任務(wù)。在我的認識中,該領(lǐng)域內(nèi)的一些未來目標包括:改進消費者服務(wù)聊天機器人、完美的機器翻譯,并且希望能讓問題回答系統(tǒng)掌握對無結(jié)構(gòu)文本或長文本(比如 wikipedia 文本頁)更深的理解能力。
聯(lián)系客服