自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

簡述表征句子的3種無監(jiān)督深度學(xué)習(xí)方法

開發(fā) 開發(fā)工具
本文介紹了三種用于表征句子的無監(jiān)督深度學(xué)習(xí)方法:自編碼器、語言模型和 Skip-Thought 向量模型,并與基線模型 Average Word2Vec 進(jìn)行了對比。

近年來,由于用連續(xù)向量表示詞語(而不是用稀疏的 one-hot 編碼向量(Word2Vec))技術(shù)的發(fā)展,自然語言處理領(lǐng)域的性能獲得了重大提升。

Word2Vec 示例

盡管 Word2Vec 性能不錯,并且創(chuàng)建了很不錯的語義,例如 King - Man + Woman = Queen,但是我們有時(shí)候并不在意單詞的表征,而是句子的表征。

本文將介紹幾個用于句子表征的無監(jiān)督深度學(xué)習(xí)方法,并分享相關(guān)代碼。我們將展示這些方法在特定文本分類任務(wù)中作為預(yù)處理步驟的效果。

分類任務(wù)

用來展示不同句子表征方法的數(shù)據(jù)基于從萬維網(wǎng)抓取的 10000 篇新聞類文章。分類任務(wù)是將每篇文章歸類為 10 個可能的主題之一(數(shù)據(jù)具備主題標(biāo)簽,所以這是一個有監(jiān)督的任務(wù))。為了便于演示,我會使用一個 logistic 回歸模型,每次使用不同的預(yù)處理表征方法處理文章標(biāo)題。

基線模型——Average Word2Vec

我們從一個簡單的基線模型開始。我們會通過對標(biāo)題單詞的 Word2Vec 表征求平均來表征文章標(biāo)題。正如之前提及的,Word2Vec 是一種將單詞表征為向量的機(jī)器學(xué)習(xí)方法。Word2Vec 模型是通過使用淺層神經(jīng)網(wǎng)絡(luò)來預(yù)測與目標(biāo)詞接近的單詞來訓(xùn)練的。你可以閱讀更多內(nèi)容來了解這個算法是如何運(yùn)行的:http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/。

我們可以使用 Gensim 訓(xùn)練我們自己的 Word2Vec 模型,但是在這個例子中我們會使用一個 Google 預(yù)訓(xùn)練 Word2Vec 模型,它基于 Google 的新聞數(shù)據(jù)而建立。在將每一個單詞表征為向量后,我們會將一個句子(文章標(biāo)題)表征為其單詞(向量)的均值,然后運(yùn)行 logistic 回歸對文章進(jìn)行分類。

  1. #load data and Word2vec model 
  2. df = pd.read_csv("news_dataset.csv") 
  3. data = df[['body','headline','category']] 
  4. w2v = gensim.models.KeyedVectors.load_word2vec_format('/GoogleNews-vectors-negative300.bin', binary=True
  5. #Build X and Y 
  6. x = np.random.rand(len(data),300) 
  7. for i in range(len(data)): 
  8.     k = 0 
  9.     non = 0 
  10.     values = np.zeros(300) 
  11.     for j in data['headline'].iloc[i].split(' '): 
  12.         if j in w2v: 
  13.             values+= w2v[j] 
  14.             k+=1 
  15.     if k > 0: 
  16.         x[i,:]=values/k 
  17.     else: non+=1 
  18. y = LabelEncoder().fit_transform(data['category'].values) 
  19. msk = np.random.rand(len(data)) < 0.8 
  20. X_train,y_train,X_test,y_test = x[msk],y[msk],x[~msk],y[~msk] 
  21. #Train the model 
  22. lr = LogisticRegression().fit(X_train,y_train) 
  23. lr.score(X_test,y_test) 

我們的基線 average Word2Vec 模型達(dá)到了 68% 的準(zhǔn)確率。這很不錯了,那么讓我們來看一看能不能做得更好。

average Word2Vec 方法有兩個弱點(diǎn):它是詞袋模型(bag-of-words model),與單詞順序無關(guān),所有單詞都具備相同的權(quán)重。為了進(jìn)行句子表征,我們將在下面的方法中使用 RNN 架構(gòu)解決這些問題。

自編碼器

自編碼器是一種無監(jiān)督深度學(xué)習(xí)模型,它試圖將自己的輸入復(fù)制到輸出。自編碼器的技巧在于中間隱藏層的維度要低于輸入數(shù)據(jù)的維度。所以這種神經(jīng)網(wǎng)絡(luò)必須以一種聰明、緊湊的方式來表征輸入,以完成成功的重建。在很多情況下,使用自編碼器進(jìn)行特征提取被證明是非常有效的。

我們的自編碼器是一個簡單的序列到序列結(jié)構(gòu),由一個輸入層、一個嵌入層、一個 LSTM 層,以及一個 softmax 層組成。整個結(jié)構(gòu)的輸入和輸出都是標(biāo)題,我們將使用 LSTM 的輸出來表征標(biāo)題。在得到自編碼器的表征之后,我們將使用 logistics 回歸來預(yù)測類別。為了得到更多的數(shù)據(jù),我們會使用文章中所有句子來訓(xùn)練自編碼器,而不是僅僅使用文章標(biāo)題。

  1. #parse all sentences 
  2. sentenses = [] 
  3. for i in data['body'].values: 
  4.     for j in nltk.sent_tokenize(i): 
  5.         sentenses.append(j) 
  6. #preprocess for keras 
  7. num_words=2000 
  8. maxlen=20 
  9. tokenizer = Tokenizer(num_wordsnum_words = num_words, split=' '
  10. tokenizer.fit_on_texts(sentenses) 
  11. seqs = tokenizer.texts_to_sequences(sentenses) 
  12. pad_seqs = [] 
  13. for i in seqs: 
  14.     if len(i)>4: 
  15.         pad_seqs.append(i) 
  16. pad_seqs = pad_sequences(pad_seqs,maxlen) 
  17. #The model 
  18. embed_dim = 150 
  19. latent_dim = 128 
  20. batch_size = 64 
  21. #### Encoder Model #### 
  22. encoder_inputs = Input(shape=(maxlen,), name='Encoder-Input'
  23. emb_layer = Embedding(num_words, embed_dim,input_length = maxlenname='Body-Word-Embedding'mask_zero=False
  24. # Word embeding for encoder (ex: Issue Body) 
  25. x = emb_layer(encoder_inputs) 
  26. state_h = GRU(latent_dim, name='Encoder-Last-GRU')(x) 
  27. encoder_model = Model(inputs=encoder_inputsoutputs=state_hname='Encoder-Model'
  28. seq2seq_encoder_out = encoder_model(encoder_inputs) 
  29. #### Decoder Model #### 
  30. decoded = RepeatVector(maxlen)(seq2seq_encoder_out) 
  31. decoder_gru = GRU(latent_dim, return_sequences=Truename='Decoder-GRU-before'
  32. decoder_grudecoder_gru_output = decoder_gru(decoded) 
  33. decoder_dense = Dense(num_words, activation='softmax'name='Final-Output-Dense-before'
  34. decoder_outputs = decoder_dense(decoder_gru_output) 
  35. #### Seq2Seq Model #### 
  36. #seq2seq_decoder_out = decoder_model([decoder_inputs, seq2seq_encoder_out]) 
  37. seq2seq_Model = Model(encoder_inputs,decoder_outputs ) 
  38. seq2seq_Model.compile(optimizer=optimizers.Nadam(lr=0.001), loss='sparse_categorical_crossentropy'
  39. history = seq2seq_Model.fit(pad_seqs, np.expand_dims(pad_seqs, -1), 
  40.           batch_sizebatch_size=batch_size, 
  41.           epochs=5
  42.           validation_split=0.12) 
  43. #Feature extraction 
  44. headlines = tokenizer.texts_to_sequences(data['headline'].values) 
  45. headlines = pad_sequences(headlines,maxlenmaxlen=maxlen)x = encoder_model.predict(headlines) 
  46. #classifier 
  47. X_train,y_train,X_test,y_test = x[msk],y[msk],x[~msk],y[~msk] 
  48. lr = LogisticRegression().fit(X_train,y_train) 
  49. lr.score(X_test,y_test) 

我們實(shí)現(xiàn)了 60% 的準(zhǔn)確率,比基線模型要差一些。我們可能通過優(yōu)化超參數(shù)、增加訓(xùn)練 epoch 數(shù)量或者在更多的數(shù)據(jù)上訓(xùn)練模型,來改進(jìn)該分?jǐn)?shù)。

語言模型

我們的第二個方法是訓(xùn)練語言模型來表征句子。語言模型描述的是某種語言中一段文本存在的概率。例如,「我喜歡吃香蕉」(I like eating bananas)這個句子會比「我喜歡吃卷積」(I like eating convolutions)這個句子具備更高的存在概率。我們通過分割 n 個單詞組成的窗口以及預(yù)測文本中的下一個單詞來訓(xùn)練語言模型。你可以在這里了解到更多基于 RNN 的語言模型的內(nèi)容:http://karpathy.github.io/2015/05/21/rnn-effectiveness/。通過構(gòu)建語言模型,我們理解了「新聞英語」(journalistic English)是如何建立的,并且模型應(yīng)該聚焦于重要的單詞及其表征。

[[226923]]

我們的架構(gòu)和自編碼器的架構(gòu)是類似的,但是我們只預(yù)測一個單詞,而不是一個單詞序列。輸入將包含由新聞文章中的 20 個單詞組成的窗口,標(biāo)簽是第 21 個單詞。在訓(xùn)練完語言模型之后,我們將從 LSTM 的輸出隱藏狀態(tài)中得到標(biāo)題表征,然后運(yùn)行 logistics 回歸模型來預(yù)測類別。

  1. #Building X and Y 
  2. num_words=2000 
  3. maxlen=20 
  4. tokenizer = Tokenizer(num_wordsnum_words = num_words, split=' '
  5. tokenizer.fit_on_texts(df['body'].values) 
  6. seqs = tokenizer.texts_to_sequences(df['body'].values) 
  7. seq = [] 
  8. for i in seqs: 
  9.     seq+=i 
  10.  
  11. X = [] 
  12. Y = [] 
  13. for i in tqdm(range(len(seq)-maxlen-1)): 
  14.     X.append(seq[i:i+maxlen]) 
  15.     Y.append(seq[i+maxlen+1]) 
  16. X = pd.DataFrame(X) 
  17. Y = pd.DataFrame(Y) 
  18. Y[0]=Y[0].astype('category') 
  19. Y =pd.get_dummies(Y) 
  20. #Buidling the network 
  21. embed_dim = 150 
  22. lstm_out = 128 
  23. batch_size128 
  24. model = Sequential() 
  25. model.add(Embedding(num_words, embed_dim,input_length = maxlen)) 
  26. model.add(Bidirectional(LSTM(lstm_out))) 
  27. model.add(Dense(Y.shape[1],activation='softmax')) 
  28. adam = Adam(lr=0.001, beta_1=0.7, beta_2=0.99, epsilon=Nonedecay=0.0, amsgrad=False
  29. model.compile(loss = 'categorical_crossentropy'optimizer=adam
  30. model.summary() 
  31. print('fit') 
  32. model.fit(X, Y, batch_sizebatch_size =batch_size,validation_split=0.1, epochs = 5,  verbose = 1
  33. #Feature extraction 
  34. headlines = tokenizer.texts_to_sequences(data['headline'].values) 
  35. headlines = pad_sequences(headlines,maxlenmaxlen=maxlen) 
  36. inp = model.input                                           
  37. outputs = [model.layers[1].output]       
  38. functor = K.function([inp]+ [K.learning_phase()], outputs ) 
  39. x = functor([headlines, 1.])[0] 
  40. #classifier 
  41. X_train,y_train,X_test,y_test = x[msk],y[msk],x[~msk],y[~msk] 
  42. lr = LogisticRegression().fit(X_train,y_train) 
  43. lr.score(X_test,y_test) 

這一次我們得到了 72% 的準(zhǔn)確率,要比基線模型好一些,那我們能否讓它變得更好呢?

Skip-Thought 向量模型

在 2015 年關(guān)于 skip-thought 的論文《Skip-Thought Vectors》中,作者從語言模型中獲得了同樣的直覺知識。然而,在 skip-thought 中,我們并沒有預(yù)測下一個單詞,而是預(yù)測之前和之后的句子。這給模型關(guān)于句子的更多語境,所以,我們可以構(gòu)建更好的句子表征。您可以閱讀這篇博客

(https://medium.com/@sanyamagarwal/my-thoughts-on-skip-thoughts-a3e773605efa),了解關(guān)于這個模型的更多信息。

skip-thought 論文中的例子(https://arxiv.org/abs/1506.06726)

我們將構(gòu)造一個類似于自編碼器的序列到序列結(jié)構(gòu),但是它與自編碼器有兩個主要的區(qū)別。***,我們有兩個 LSTM 輸出層:一個用于之前的句子,一個用于下一個句子;第二,我們會在輸出 LSTM 中使用教師強(qiáng)迫(teacher forcing)。這意味著我們不僅僅給輸出 LSTM 提供了之前的隱藏狀態(tài),還提供了實(shí)際的前一個單詞(可在上圖和輸出***一行中查看輸入)。

  1. #Build x and y 
  2. num_words=2000 
  3. maxlen=20 
  4. tokenizer = Tokenizer(num_wordsnum_words = num_words, split=' '
  5. tokenizer.fit_on_texts(sentenses) 
  6. seqs = tokenizer.texts_to_sequences(sentenses) 
  7. pad_seqs = pad_sequences(seqs,maxlen) 
  8. x_skip = [] 
  9. y_before = [] 
  10. y_after = [] 
  11. for i in tqdm(range(1,len(seqs)-1)): 
  12.     if len(seqs[i])>4: 
  13.         x_skip.append(pad_seqs[i].tolist()) 
  14.         y_before.append(pad_seqs[i-1].tolist()) 
  15.         y_after.append(pad_seqs[i+1].tolist()) 
  16. x_before = np.matrix([[0]+i[:-1] for i in y_before]) 
  17. x_after =np.matrix([[0]+i[:-1] for i in y_after]) 
  18. x_skip = np.matrix(x_skip) 
  19. y_before = np.matrix(y_before) 
  20. y_after = np.matrix(y_after) 
  21. #Building the model 
  22.  
  23. embed_dim = 150 
  24. latent_dim = 128 
  25. batch_size = 64 
  26. #### Encoder Model #### 
  27. encoder_inputs = Input(shape=(maxlen,), name='Encoder-Input'
  28. emb_layer = Embedding(num_words, embed_dim,input_length = maxlenname='Body-Word-Embedding'mask_zero=False
  29. x = emb_layer(encoder_inputs) 
  30. _, state_h = GRU(latent_dim, return_state=Truename='Encoder-Last-GRU')(x) 
  31. encoder_model = Model(inputs=encoder_inputsoutputs=state_hname='Encoder-Model'
  32. seq2seq_encoder_out = encoder_model(encoder_inputs) 
  33. #### Decoder Model #### 
  34. decoder_inputs_before = Input(shape=(None,), name='Decoder-Input-before')  # for teacher forcing 
  35. dec_emb_before = emb_layer(decoder_inputs_before) 
  36. decoder_gru_before = GRU(latent_dim, return_state=Truereturn_sequences=Truename='Decoder-GRU-before'
  37. decoder_gru_output_before, _ = decoder_gru_before(dec_emb_before, initial_state=seq2seq_encoder_out
  38. decoder_dense_before = Dense(num_words, activation='softmax'name='Final-Output-Dense-before'
  39. decoder_outputs_before = decoder_dense_before(decoder_gru_output_before) 
  40. decoder_inputs_after = Input(shape=(None,), name='Decoder-Input-after')  # for teacher forcing 
  41. dec_emb_after = emb_layer(decoder_inputs_after) 
  42. decoder_gru_after = GRU(latent_dim, return_state=Truereturn_sequences=Truename='Decoder-GRU-after'
  43. decoder_gru_output_after, _ = decoder_gru_after(dec_emb_after, initial_state=seq2seq_encoder_out
  44. decoder_dense_after = Dense(num_words, activation='softmax'name='Final-Output-Dense-after'
  45. decoder_outputs_after = decoder_dense_after(decoder_gru_output_after) 
  46. #### Seq2Seq Model #### 
  47. seq2seq_Model = Model([encoder_inputs, decoder_inputs_before,decoder_inputs_after], [decoder_outputs_before,decoder_outputs_after]) 
  48. seq2seq_Model.compile(optimizer=optimizers.Nadam(lr=0.001), loss='sparse_categorical_crossentropy'
  49. seq2seq_Model.summary() 
  50. history = seq2seq_Model.fit([x_skip,x_before, x_after], [np.expand_dims(y_before, -1),np.expand_dims(y_after, -1)], 
  51.           batch_sizebatch_size=batch_size, 
  52.           epochs=10
  53.           validation_split=0.12) 
  54. #Feature extraction 
  55. headlines = tokenizer.texts_to_sequences(data['headline'].values) 
  56. headlines = pad_sequences(headlines,maxlenmaxlen=maxlen)x = encoder_model.predict(headlines) 
  57. #classifier 
  58. X_train,y_train,X_test,y_test = x[msk],y[msk],x[~msk],y[~msk] 
  59. lr = LogisticRegression().fit(X_train,y_train) 
  60. lr.score(X_test,y_test) 

這一次我們達(dá)到了 74% 的準(zhǔn)確率。這是目前得到的***準(zhǔn)確率。

總結(jié)

本文中,我們介紹了三個使用 RNN 創(chuàng)建句子向量表征的無監(jiān)督方法,并且在解決一個監(jiān)督任務(wù)的過程中展現(xiàn)了它們的效率。自編碼器的結(jié)果比我們的基線模型要差一些(這可能是因?yàn)樗玫臄?shù)據(jù)集相對較小的緣故)。skip-thought 向量模型語言模型都利用語境來預(yù)測句子表征,并得到了***結(jié)果。

能夠提升我們所展示的方法性能的可用方法有:調(diào)節(jié)超參數(shù)、訓(xùn)練更多 epoch 次數(shù)、使用預(yù)訓(xùn)練嵌入矩陣、改變神經(jīng)網(wǎng)絡(luò)架構(gòu)等等。理論上,這些高級的調(diào)節(jié)工作或許能夠在一定程度上改變結(jié)果。但是,我認(rèn)為每一個預(yù)處理方法的基本直覺知識都能使用上述分享示例實(shí)現(xiàn)。

原文鏈接:

https://blog.myyellowroad.com/unsupervised-sentence-representation-with-deep-learning-104b90079a93

【本文是51CTO專欄機(jī)構(gòu)“機(jī)器之心”的原創(chuàng)譯文,微信公眾號“機(jī)器之心( id: almosthuman2014)”】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2019-07-10 05:47:37

GAN無監(jiān)督表征學(xué)習(xí)機(jī)器學(xué)習(xí)

2017-06-12 14:04:45

深度學(xué)習(xí)人工智能

2018-09-06 11:25:46

機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)人工智能

2021-11-12 15:16:32

深度學(xué)習(xí)數(shù)據(jù)合成人工智能

2024-10-08 08:19:19

2017-12-01 17:35:02

2021-07-01 15:56:42

深度學(xué)習(xí)人工智能互聯(lián)網(wǎng)

2020-11-11 09:00:00

機(jī)器學(xué)習(xí)技術(shù)人工智能

2023-11-23 15:54:01

人工智能監(jiān)督學(xué)習(xí)無監(jiān)督學(xué)習(xí)

2016-09-30 15:33:02

集成學(xué)習(xí)機(jī)器學(xué)習(xí)算法

2018-03-15 15:40:39

廣告點(diǎn)擊率PaddlePaddlTensorflow

2018-03-26 20:28:24

深度學(xué)習(xí)

2022-02-17 09:00:00

深度學(xué)習(xí)人工智能表征學(xué)習(xí)

2023-03-09 14:04:00

谷歌研究

2009-09-28 10:40:28

.NET學(xué)習(xí)

2020-04-28 17:26:04

監(jiān)督學(xué)習(xí)無監(jiān)督學(xué)習(xí)機(jī)器學(xué)習(xí)

2009-09-08 09:25:46

思科認(rèn)證學(xué)習(xí)方法思科認(rèn)證

2010-05-04 17:48:53

2009-09-16 10:16:29

CCNA學(xué)習(xí)方法CCNA

2018-05-28 15:33:09

無監(jiān)督學(xué)習(xí)算法Python
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號