Task7 卷積神經(jīng)網(wǎng)絡(luò)

任務(wù):

  1. 卷積運算的定義休吠、動機(jī)(稀疏權(quán)重众弓、參數(shù)共享、等變表示)乓序。一維卷積運算和二維卷積運算寺酪。
  2. 反卷積(tf.nn.conv2d_transpose)
  3. 池化運算的定義、種類(最大池化替劈、平均池化等)寄雀、動機(jī)。
  4. Text-CNN的原理陨献。
  5. 利用Text-CNN模型來進(jìn)行文本分類盒犹。

文本分類實現(xiàn)數(shù)據(jù)集處理流程圖

  • 數(shù)據(jù)處理步驟+每一步處理的目的如下圖所示:


    文本分類實現(xiàn)數(shù)據(jù)集處理流程圖
  • 數(shù)據(jù)處理部分實現(xiàn)
  1. 讀數(shù)據(jù)
    其中數(shù)據(jù)是已經(jīng)jiebe分詞+去停用詞后的結(jié)果
def read_file(path):
    with open(path, 'r', encoding="UTF-8") as f:
        data = []
        labels = []
        for line in f:
            if line.split('\t')[1] == '':
                continue
            data.append(line.split('\t')[0])
            labels.append(line.split('\t')[1])
    return data, labels
# 讀文件
data, labels = read_file('E:/task6/merge.txt')
  1. 利用tokenizer將文字轉(zhuǎn)換為數(shù)字特征
  • 將文字轉(zhuǎn)換為數(shù)字特征要將整個數(shù)據(jù)集放入,這樣保證訓(xùn)練集眨业、驗證集急膀、測試集文字編碼一致
  • 其中同時返回對應(yīng)單詞和數(shù)字的映射關(guān)系,以便在轉(zhuǎn)化詞向量過程中獲取詞向量列表
def get_tokenizer(data):
    tokenizer = Tokenizer(num_words=None)
    tokenizer.fit_on_texts(data)
    text_seq = tokenizer.texts_to_sequences(data)
    # 對應(yīng)的單詞和數(shù)字的映射關(guān)系
    word_index = tokenizer.word_index 
    index_word = tokenizer.index_word
    return word_index, index_word, text_seq

# 利用tokenizer將文字轉(zhuǎn)換為數(shù)字特征
word_index, index_word, X_train_text_seq = get_tokenizer(data)
  1. FastText Embedding
def get_fasttext_voc(data, word_index):
    '''
        利用fasttext獲取詞向量
    '''
    fasttext_model = FastText([data], 
                              size=FASTEXT_SIZE,         # 需要學(xué)習(xí)的嵌入大小(默認(rèn)為100)
                              window=3,         # 上下文窗口大小(默認(rèn)5)
                              min_count=1,      # 忽略出現(xiàn)次數(shù)低于此值的單詞(默認(rèn)值5)
                              iter=10,          # epoch(默認(rèn)5)
                              min_n = 3,        # char ngram的最小長度(默認(rèn)值3)
                              max_n = 6,        # char ngram的最大長度(默認(rèn)值6)
                              word_ngrams = 0)  # 如果為1龄捡,使用子單詞(n-grams)信息豐富單詞向量卓嫂。如果是0,這就相當(dāng)于Word2Vec
    # 獲取詞向量列表
    wordEmbedding = np.zeros((len(word_index) + 1, FASTEXT_SIZE))
    for word, i in word_index.items():
        if word in fasttext_model:
            wordEmbedding[i] = fasttext_model[word]   
    return wordEmbedding

# fasttext embedding
wordEmbedding = get_fasttext_voc(data, word_index)
  1. 讓每個文本長度相同
# 讓每個文本長度相同
X_train_text_seq = pad_sequences(X_train_text_seq, maxlen=LEN_WORDS, padding='post', truncating='post')
  1. 劃分?jǐn)?shù)據(jù)集
# 劃分?jǐn)?shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X_train_text_seq, 
                                                    labels,
                                                    test_size = 0.2,
                                                    random_state=33)
  1. 對類別變量編碼
def get_label_num(data):
    data = [i.replace('\n', '') for i in data]
    y_labels = list(set(data))
    le = preprocessing.LabelEncoder()
    le.fit(y_labels)
    num_labels = len(y_labels)
    data_labels = to_categorical([le.transform([x])[0] for x in data], num_labels)
    return data_labels

# 對類別變量編碼
y_train_label = get_label_num(y_train)
y_test_label = get_label_num(y_test)

CNN

實現(xiàn)基礎(chǔ)版CNN:

LeNet-5 是卷積神經(jīng)網(wǎng)絡(luò)的作者Yann LeCun用于MNIST識別任務(wù)提出的模型聘殖。模型很簡單晨雳,就是卷積池化層的堆疊,最后加上幾層全連接層就斤。將其運用在文本分類任務(wù)中悍募。
其中模型結(jié)構(gòu)如下所示:


實現(xiàn)過程如下:

def model_CNN(X_train, X_test, y_train, y_test, index_word, embedding_matrix):
    '''
        模型結(jié)構(gòu):
            嵌入層:將詞編碼數(shù)據(jù)轉(zhuǎn)換為固定尺寸的稠密向量,同時把詞向量矩陣加載到Embedding層
            卷積池化層:256 * 3 * 3
            卷積池化層:128 * 3 * 3
            Dropout:0.1
            BatchNormalization: 批量標(biāo)準(zhǔn)化層洋机,在每一個批次的數(shù)據(jù)中標(biāo)準(zhǔn)化前一層的激活項
            全連接:256,'relu'
            分類器:2坠宴, 'softmax'
    '''
    model = Sequential()
    model.add(Embedding(len(index_word) + 1,             # imput_dim: 詞匯表大小,即最大整數(shù)index+1
                        FASTEXT_SIZE,                    # output_dim: 詞向量的維度
                        weights=[embedding_matrix],      # 加載詞向量矩陣
                        input_length=LEN_WORDS,           # input_lenth: 輸入序列的長度
                        trainable=False))                # 設(shè)置trainable=False使得這個編碼層不可再訓(xùn)練
    # filters:輸出空間的維度绷旗,kernel_size: 1D 卷積窗口的長度喜鼓,padding:"same" 表示填充輸入以使輸出具有與原始輸入相同的長度
    model.add(Conv1D(256, 3, padding='same'))   
    # pool_size:最大池化的窗口大小, strides:作為縮小比例的因數(shù)
    model.add(MaxPooling1D(3, 3, padding='same'))
    model.add(Conv1D(128, 3, padding='same'))
    model.add(MaxPooling1D(3, 3, padding='same'))
    model.add(Conv1D(64, 3, padding='same'))
    
    model.add(Flatten())
    # rate: 在 0 和 1 之間浮動副砍。需要丟棄的輸入比例
    model.add(Dropout(0.1))
    model.add(BatchNormalization())
    # units: 正整數(shù),輸出空間維度
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(2, activation='softmax'))
    # 配置訓(xùn)練模型
    model.compile(loss='categorical_crossentropy',          # 表示目標(biāo)應(yīng)該是分類格式的
                  optimizer='adam',                         # 隨機(jī)優(yōu)化的一種方法
                  metrics=['accuracy']                      # 模型評估標(biāo)準(zhǔn)
                  )
    # 給定數(shù)量的迭代訓(xùn)練模型
    model.summary()
    model.fit(X_train, y_train, 
              batch_size=32, 
              epochs=15, 
              validation_data=(X_test, y_test))  

Text-CNN

  1. 原理

Yoon Kim在2014年 “Convolutional Neural Networks for Sentence Classification” 論文中提出TextCNN(利用卷積神經(jīng)網(wǎng)絡(luò)對文本進(jìn)行分類的算法)論文翻譯版庄岖,其中網(wǎng)絡(luò)結(jié)構(gòu)如下所示:


假設(shè)我們有一些句子需要對其進(jìn)行分類豁翎。句子中每個詞是由n維詞向量組成的,也就是說輸入矩陣大小為m*n隅忿,其中m為句子長度心剥。CNN需要對輸入樣本進(jìn)行卷積操作,對于文本數(shù)據(jù)背桐,filter不再橫向滑動优烧,僅僅是向下移動,有點類似于N-gram在提取詞與詞間的局部相關(guān)性链峭。圖中共有三種步長策略畦娄,分別是2,3,4,每個步長都有兩個filter(實際訓(xùn)練時filter數(shù)量會很多)弊仪。在不同詞窗上應(yīng)用不同filter熙卡,最終得到6個卷積后的向量。然后對每一個向量進(jìn)行最大化池化操作并拼接各個池化值励饵,最終得到這個句子的特征表示驳癌,將這個句子向量丟給分類器進(jìn)行分類,至此完成整個流程役听。
其中每個層的作用喂柒,參照:https://blog.csdn.net/asialee_bird/article/details/88813385

模型結(jié)構(gòu)如下所示:


TextCNN網(wǎng)絡(luò)結(jié)構(gòu)

實現(xiàn)過程如下:

def model_TextCNN(X_train, X_test, y_train, y_test, index_word, embedding_matrix):
    '''
        模型結(jié)構(gòu):
            詞嵌入,
            卷積池化 * 3:256 * 3 * 4
            拼接三個模型的輸出向量禾嫉,
            全連接灾杰,
            Dropout,
            全連接
    '''
    # shape: 一個尺寸元組(整數(shù))表明期望的輸入是按批次的LEN_WORDS維向量
    main_input = Input(shape=(LEN_WORDS, ), dtype='float32')
    embed = Embedding(len(index_word) + 1,             
                        FASTEXT_SIZE,                    
                        weights=[embedding_matrix],      
                        input_length=LEN_WORDS,           
                        trainable=False)(main_input)
    # 詞窗大小分別為3熙参,4艳吠,5
    # strides指明卷積的步長
    cnn1 =  Conv1D(256, 3, padding='same', strides=1, activation='relu')(embed)
    cnn1 = MaxPooling1D(pool_size=4)(cnn1)
    cnn2 =  Conv1D(256, 4, padding='same', strides=1, activation='relu')(embed)
    cnn2 = MaxPooling1D(pool_size=4)(cnn2)
    cnn3 =  Conv1D(256, 5, padding='same', strides=1, activation='relu')(embed)
    cnn3 = MaxPooling1D(pool_size=4)(cnn3)  
    # 合并三個模型的輸出向量
    cnn = concatenate([cnn1,cnn2,cnn3], axis=-1)                 
    flat = Flatten()(cnn)
    drop = Dropout(0.1)(flat)
    main_output = Dense(2, activation='softmax')(drop)
    model = Model(inputs=main_input, output=main_output)
    # 配置訓(xùn)練模型
    model.compile(loss='categorical_crossentropy',          # 表示目標(biāo)應(yīng)該是分類格式的
                  optimizer='adam',                         # 隨機(jī)優(yōu)化的一種方法
                  metrics=['accuracy']                      # 模型評估標(biāo)準(zhǔn)
                  )
    # 給定數(shù)量的迭代訓(xùn)練模型
    model.summary()
    model.fit(X_train, y_train, 
              batch_size=32, 
              epochs=15, 
              validation_data=(X_test, y_test))

完整代碼見:github
參考資料:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市孽椰,隨后出現(xiàn)的幾起案子昭娩,更是在濱河造成了極大的恐慌,老刑警劉巖黍匾,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栏渺,死亡現(xiàn)場離奇詭異,居然都是意外死亡锐涯,警方通過查閱死者的電腦和手機(jī)磕诊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霎终,你說我怎么就攤上這事滞磺。” “怎么了莱褒?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵击困,是天一觀的道長。 經(jīng)常有香客問我广凸,道長阅茶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任谅海,我火速辦了婚禮目派,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胁赢。我一直安慰自己,他們只是感情好白筹,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布智末。 她就那樣靜靜地躺著,像睡著了一般徒河。 火紅的嫁衣襯著肌膚如雪系馆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天顽照,我揣著相機(jī)與錄音由蘑,去河邊找鬼。 笑死代兵,一個胖子當(dāng)著我的面吹牛尼酿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播植影,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼裳擎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了思币?” 一聲冷哼從身側(cè)響起鹿响,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谷饿,沒想到半個月后惶我,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡博投,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年绸贡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡恃轩,死狀恐怖结洼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叉跛,我是刑警寧澤松忍,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站筷厘,受9級特大地震影響鸣峭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酥艳,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一摊溶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧充石,春花似錦莫换、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惰爬,卻和暖如春喊暖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撕瞧。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工陵叽, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丛版。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓巩掺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親页畦。 傳聞我的和親對象是個殘疾皇子锌半,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容