更新時間:2024-05-20 10:13:37作者:佚名
在《卷積神經網絡》中我們探討了如何使用2D卷積神經網絡來處理2D圖像數據。 在之前的語言模型和文本分類任務中,我們將文本數據視為只有一維的時間序列網絡情感文章,很自然地使用遞歸神經網絡來表示此類數據。 事實上,我們也可以將文本視為一維圖像,這樣我們就可以使用一維卷積神經網絡來捕獲相鄰單詞之間的關聯。
目錄
介紹
它是一種利用卷積神經網絡對文本進行分類的算法,由 Yoon Kim 在《for》中提出。
結構圖:
第一層將單詞嵌入到低維向量中。 下一層使用多個過濾器大小對嵌入的詞向量執行卷積。 例如,一次滑動 3、4 或 5 個單詞。 接下來,將卷積層的結果 max-pool 為長特征向量,添加正則化,并使用 分類結果。 與傳統的圖像CNN網絡相比,網絡結構沒有變化(甚至更簡單)。 從圖中可以看出,實際上只有一層卷積,一層max-,最后輸出外接n個分類。
與圖像中的CNN網絡相比,最大的區別在于輸入數據的不同:圖像是二維數據,圖像的卷積核從左到右、從上到下滑動進行特征提取。 自然語言是一維數據。 雖然通過word-生成二維向量,但是通過從左向右滑動來對詞向量進行卷積是沒有意義的。 例如“今天”對應的向量為[0, 0, 0, 0, 1],根據1*2的窗口大小,從左向右滑動得到四個向量[0,0],[ 0,0]、[0,0]、[0, 1],分別對應“今天”這個詞匯,這個滑點沒有幫助。
成功并不是網絡結構的成功,而是引入已經訓練好的詞向量,在多個數據集上實現超越的性能,這進一步證明更好的構建是提高各種nlp任務的關鍵能力。
最大的優點是網絡結構簡單。 當模型網絡結構如此簡單的時候,引入已經訓練好的詞向量仍然有非常好的效果,超越了很多數據集。 網絡結構簡單,參數數量少,計算量小,訓練速度快。 在單卡v100機器上,訓練165萬個數據,迭代26萬步,半小時左右即可實現收斂。
過程
分詞構建詞向量
使用預先訓練的詞向量作為層。 對于數據集中的所有單詞,因為每個單詞都可以表示為一個向量,所以我們可以得到一個嵌入矩陣M,M中的每一行都是一個詞向量。 這個M可以是(),即固定的。 可以是非靜態的,即可以基于反向傳播進行更新。
如圖所示,第一段“今天天氣很好,出來玩”變成“今天的/天氣/很好/,/出來/玩”,將每個單詞映射成5維(維度可以自己指定)詞向量,如“今天”->[0,0,0,0,1],“天氣”->[0,0,0,1,0],“很好”- >[0 ,0,1,0,0] 等等。
這樣做的主要好處是將自然語言數字化,以方便后續處理。 從這里也可以看出,不同的映射方法會對最終的結果產生巨大的影響。 nlp中最熱門的研究方向是如何將自然語言映射成更好的詞向量。 構建完詞向量后,我們將所有詞向量連接起來形成一個 6*5 的二維矩陣作為初始輸入。
卷積
輸入一個句子,首先對句子進行分詞,假設有s個單詞。 對于每個單詞,連同句子嵌入矩陣M,可以獲得詞向量。 假設詞向量共有d維。 那么對于這句話,我們就可以得到s行d列的矩陣$AR^{stimes d}$。 我們可以將矩陣A視為圖像,并使用卷積神經網絡來提取特征。 由于句子中相鄰單詞之間的相關性總是很高,因此可以使用一維卷積。 卷積核的寬度是詞向量的d維,高度是可以設置的超參數。
假設有一個卷積核,它是一個寬度為d、高度為h的矩陣w,那么w有h*d個參數需要更新。 對于一個句子,經過層之后就可以得到矩陣$R^{stimes d}$。 $A[i:j]$表示A的第i行到第j行,那么卷積運算可以用下面的公式表示: $o_i = w cdot A[i:i+h-1 ]$
疊加偏置b并使用激活函數f激活它以獲得所需的特征。 公式如下:$c_i=f(o_i+b)$
對于一個卷積核,可以得到特征$cR^{s-h+1}$,總共$s?h+1$個特征。 我們可以使用更多不同高度的卷積核來獲得更豐富的特征表達。
卷積是一種數學運算符。我們用一個簡單的例子來說明
就是卷積后的輸出。 輸入的6*5矩陣通過卷積運算映射成3*1矩陣。 這個映射過程與特征提取的結果非常相似,所以最終的輸出稱為map。 一般來說,卷積之后會跟一個激活函數。 為了簡化這里的解釋,我們將激活函數設置為 f(x) = x
CNN經常提到一個詞。 圖中深紅色矩陣和淺紅色矩陣形成兩個卷積核。 從這張圖也可以看出,每一個并不一定要嚴格一樣。 每個4*5矩陣與輸入矩陣進行卷積運算,得到一張圖。 在計算機視覺中,由于彩色圖像中有R、G、B三種顏色英語作文,因此每種顏色代表一種顏色。 根據原論文作者的描述,最初引入它是希望防止過擬合(通過確保學習到的數據不會偏離輸入太多)以在小數據集上獲得更好的性能。 后來發現直接使用正則化效果更佳。 好的。 不過,與單次使用相比,每次都可以使用不同的單詞。 比如可以對詞向量進行no-(梯度可以反向傳播)的微調,使得詞向量更適合當前的訓練。 至于是否有用,從論文的實驗結果來看,Duo 并沒有顯著提高模型的分類能力。 七個數據集中有五個的表現優于 Duo。
這里我們也介紹一下論文中四種模型的區別:
池化
不同尺寸的卷積核得到的特征(圖)尺寸也不同,因此我們對每個圖使用池化函數,使它們具有相同的尺寸。 最常用的是1-max,提取地圖照片的最大值。 這樣網絡情感文章,每個卷積核得到的特征就是一個值。 所有卷積核都使用1-max,然后級聯得到最終的特征向量。 然后將該特征向量輸入到該層進行分類。 這里可以使用drop out來防止過擬合。
得到=[1,1,2]后,選擇一個最大值[2]作為輸出,即max-。 max-在保持主要特征的同時,大大減少了參數數量。 從圖中可以看出,地圖從三維變成了一維。 好處如下:
它本身不能帶來平移不變性(圖中有一個字母A,這個字母A無論出現在圖片的哪個位置,CNN網絡中都能被識別),只能共享卷積核的權值。 max-的原理主要是從多個值中選擇一個最大值,這是不能做到的。 CNN之所以能夠實現平移不變性,是因為在滑動卷積核時,所使用的卷積核的權重保持固定(權重共享)。 假設卷積核被訓練來識別字母A,當這個卷積核在整張圖像上滑動時,它當然可以識別整張圖像中的所有A。
使用k分類
如圖所示,我們將max-拼接起來,喂入其中,得到各個類別,比如標簽為1的概率和標簽為-1的概率。 如果是預測的話,整個過程就到這里了。 如果是訓練的話,會根據此時的預測標簽和實際標簽,以及函數、max-函數、激活函數和依次計算卷積核函數來更新它們。 四個函數中的參數完成一輪訓練。
總結
上述過程可以用下圖直觀地表示:
使用Keras構建卷積神經網絡進行情感分析
在自然語言領域,卷積的作用就是利用文本的局部特征。 一個詞前后的詞必須與該詞本身相關,它們構成了該詞所代表的詞組。 然后詞組將影響段落文本的含義并確定該段落是積極的還是消極的。 與傳統方法相比,使用詞袋、TF-IDF等,它們的思路是相似的。 但最大的區別在于,傳統方法是人為構造特征進行分類,而深度學習中的卷積則讓神經網絡來構造特征。 以上就是卷積在自然語言處理中廣泛應用的原因。 接下來,我們將介紹如何使用Keras構建卷積神經網絡來處理情感分析的分類問題。
以下代碼構建了卷積神經網絡的結構:
from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Conv1D, MaxPooling1D from keras.models import Sequential from keras.layers.embeddings import Embedding from keras.datasets import imdb import numpy as np from keras.preprocessing import sequence (X_train, y_train), (X_test, y_test) = imdb.load_data() max_word = 400 X_train = sequence.pad_sequences(X_train, maxlen=max_word) X_test = sequence.pad_sequences(X_test, maxlen=max_word) vocab_size = np.max([np.max(X_train[i]) for i in range(X_train.shape[0])]) + 1 # 這里1 代表空格,其索引被認為是0。 model = Sequential() model.add(Embedding(vocab_size, 64, input_length=max_word)) model.add(Conv1D(filters=64, kernel_size=3, padding='same', activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Dropout(0.25)) model.add(Conv1D(filters=128, kernel_size=3, padding='same', activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy']) print(model.summary()) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=100) scores = model.evaluate(X_test, y_test, verbose=1) print(scores)
整個模型的結構如下:
Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_1 (Embedding) (None, 400, 64) 5669568 _________________________________________________________________ conv1d_1 (Conv1D) (None, 400, 64) 12352 _________________________________________________________________ max_pooling1d_1 (MaxPooling1 (None, 200, 64) 0 _________________________________________________________________ dropout_1 (Dropout) (None, 200, 64) 0 _________________________________________________________________ conv1d_2 (Conv1D) (None, 200, 128) 24704 _________________________________________________________________ max_pooling1d_2 (MaxPooling1 (None, 100, 128) 0 _________________________________________________________________ dropout_2 (Dropout) (None, 100, 128) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 12800) 0 _________________________________________________________________ dense_1 (Dense) (None, 64) 819264 _________________________________________________________________ dense_2 (Dense) (None, 32) 2080 _________________________________________________________________ dense_3 (Dense) (None, 1) 33 ================================================================= Total params: 6,528,001 Trainable params: 6,528,001 Non-trainable params: 0 _________________________________________________________________
超參數調整
在只有一層卷積的最簡單結構中,以下超參數對模型性能有影響:
參考鏈接:
相關文章: 多層全連接神經網絡與情感分析 深度學習算法 卷積神經網絡(CNN) 機器學習算法 - Learn 中的異常檢測算法 機器學習算法 樸素貝葉斯