一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

漫談四種神經(jīng)網(wǎng)絡序列解碼模型【附示例代碼】 | 刻骨銘心

 htxu91 2016-11-02

以下為漫談,即瞎聊,利用通俗的語言來談談神經(jīng)網(wǎng)絡模型中4種序列解碼模型,主要是從整體概念和思路上進行通俗解釋幫助理解。預警,以下可能為了偷懶就不貼公式了,一些細節(jié)也被略過了,感興趣的可以直接去閱讀原文[1][2][3]。

[1] Sequence to Sequence Learning with Neural Networks
[2] Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation
[3] Neural Machine Translation by Jointly Learning to Align and Translate

利用神經(jīng)網(wǎng)絡進行序列編碼的模型主要為RNN,目前比較火的一些變種模型有LSTM和GRU,只是cell單元不同而已。以下統(tǒng)統(tǒng)用RNN來代表。

編碼模型比較簡單,如下圖所示,輸入文本{X1-X6}經(jīng)過循環(huán)迭代編碼,在每個時刻得到當前時刻的一個隱層狀態(tài),最后序列結束后進行特征融合得到句子的表示。注意,一種比較常用的方式是將編碼模型最后一個時刻的隱層狀態(tài)做為整個序列的編碼表示,但是實際應用中這種效果并不太好,因而我們的圖例中直接采用了整個序列隱層編碼進行求和平均的方式得到序列的編碼向量。

早期的一些任務主要是做一些主題分類、情感檢測等等分類任務,那么在編碼向量上面添加一個softmax就可以解決問題。但是對于機器翻譯和語音識別等問題則需要進行序列化解碼。

注意到,編碼時RNN每個時刻除了自己上一時刻的隱層狀態(tài)編碼外,還有當前時刻的輸入字符,而解碼時則沒有這種輸入。那么,一種比較直接的方式是把編碼端得到的編碼向量做為解碼模型的每時刻輸入特征。如下圖所示:

簡單直觀而且解碼模型和編碼模型并沒有任何區(qū)別,然而學者感覺該模型并不優(yōu)雅,那么接下來我們就來介紹一些精巧點的吧。

=============此處開始轉(zhuǎn)入瞎聊模式==============

我們用考試作弊來做為一個通俗的例子來解釋一下模型。

首先我們假設輸入文本是所學課本,編碼端則是對課本的理解所整理的課堂筆記。解碼端的隱層神經(jīng)網(wǎng)絡則是我們的大腦,而每一時刻的輸出則是考試時要寫在卷子上的答案。在上面最簡單的解碼模型中,可以考慮成是考試時一邊寫答案一邊翻看課堂筆記。如果這是一般作弊學生的做法,學霸則不需要翻書,他們有一個強大的大腦神經(jīng)網(wǎng)絡,可以記住自己的課堂筆記。解碼時只需要回顧一下自己前面寫過什么,然后依次認真的把答案寫在答卷上,就是下面這種模型了[1]:

還有很多學弱,他們不只需要作弊,而且翻看筆記的時候還需要回顧自己上一時刻寫在答卷上的答案(學弱嘛,簡直弱到連自己上一時刻寫在答卷上的文字都記不住了),就是下面的答題模式了[2]:

然而學渣渣也是存在的,他們不只需要作弊,不只需要回顧自己上一時刻卸載答卷上的答案,還需要老師在課本上畫出重點才能整理出自己的課題筆記(這就是一種注意力機制Attention,記筆記的時候一定要根據(jù)考題畫出重點啊?。?,真的很照顧渣渣了,他們的答題模式如下[3]:

可見,除了學霸以外,其他人都作弊了,在答題的時候翻看課堂筆記(很多文獻中叫這種解碼模型結構為peek(偷看),是不是很像在作弊?),而且學渣渣還去找過老師給畫過重點,有了清楚的重點之后就不用翻書偷看了,瞄一眼就可以了,文獻中叫glimpse(一瞥),是不是很像?

如果我們將他們的大腦網(wǎng)絡設定為同樣結構的話(將他們的IQ強制保持一致),肯定是作弊的同學得分最高了,學霸模式好吃虧啊。我們來簡單做一個模型測試。

測試數(shù)據(jù):

輸入序列文本 = ['1 2 3 4 5'
, '6 7 8 9 10'
, '11 12 13 14 15'
, '16 17 18 19 20'
, '21 22 23 24 25']
目標序列文本 = ['one two three four five'
, 'six seven eight nine ten'
, 'eleven twelve thirteen fourteen fifteen'
, 'sixteen seventeen eighteen nineteen twenty'
, 'twenty_one twenty_two twenty_three twenty_four twenty_five']

設定一些參數(shù)如下:
-
(‘Vocab size:’, 51, ‘unique words’)
(‘Input max length:’, 5, ‘words’)
(‘Target max length:’, 5, ‘words’)
(‘Dimension of hidden vectors:’, 20)
(‘Number of training stories:’, 5)
(‘Number of test stories:’, 5)
-

觀察訓練過程:


其中,第一種解碼模型為 普通作弊,第二種解碼模型為 學霸模式,第三種解碼模型為 學弱作弊,第四種解碼模型為 學渣作弊。

可以看到在IQ值(解碼模型的神經(jīng)網(wǎng)絡結構)相同的情況下,學渣作弊模式答題(訓練收斂速度)更快,而學霸模式答題最慢。

文章[1]中已經(jīng)提到過,想通過學霸模式達到一個好的性能需要模型隱層有4000個節(jié)點(學霸的IQ果然是高的,有一顆強大的大腦網(wǎng)絡)。

可以想想,在課本內(nèi)容很多很多時,學霸也會累的,而且學弱們你們確定課上能聽懂嗎?學渣就會笑啦,因而老師給他們畫重點了?。。?!

哈哈,娛樂而已。

好,學術一點,博主關注:對話與問答,信息檢索,深度學習等相關。歡迎學術討論。

博文出處:http:///?p=1852

附錄:

本博文中測試的示例代碼見【Github地址】:

Code   ViewCopyPrint
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. # -*- encoding:utf-8 -*-   
  2. “”"
  3.     測試Encoder-Decoder 2016/03/22  
  4. “”"  
  5. from keras.models import Sequential   
  6. from keras.layers.recurrent import LSTM   
  7. from keras.layers.embeddings import Embedding   
  8. from keras.layers.core import RepeatVector, TimeDistributedDense, Activation   
  9. from seq2seq.layers.decoders import LSTMDecoder, LSTMDecoder2, AttentionDecoder   
  10. import time  
  11. import numpy as np   
  12. import re  
  13.   
  14. __author__ = ’http://’   
  15.   
  16.   
  17. def pad_sequences(sequences, maxlen=None, dtype=’int32′,   
  18.                   padding=’pre’, truncating=’pre’, value=0.):   
  19.     ”’Pads each sequence to the same length:
  20.     the length of the longest sequence.  
  21.  
  22.     If maxlen is provided, any sequence longer  
  23.     than maxlen is truncated to maxlen.  
  24.     Truncation happens off either the beginning (default) or  
  25.     the end of the sequence.  
  26.  
  27.     Supports post-padding and pre-padding (default).  
  28.  
  29.     # Arguments  
  30.         sequences: list of lists where each element is a sequence  
  31.         maxlen: int, maximum length  
  32.         dtype: type to cast the resulting sequence.  
  33.         padding: ’pre’ or ’post’, pad either before or after each sequence.  
  34.         truncating: ’pre’ or ’post’, remove values from sequences larger than  
  35.             maxlen either in the beginning or in the end of the sequence  
  36.         value: float, value to pad the sequences to the desired value.  
  37.  
  38.     # Returns  
  39.         x: numpy array with dimensions (number_of_sequences, maxlen)  
  40.     ”’  
  41.     lengths = [len(s) for s in sequences]   
  42.   
  43.     nb_samples = len(sequences)   
  44.     if maxlen is None:   
  45.         maxlen = np.max(lengths)   
  46.   
  47.     # take the sample shape from the first non empty sequence   
  48.     # checking for consistency in the main loop below.   
  49.     sample_shape = tuple()   
  50.     for s in sequences:   
  51.         if len(s) > 0:   
  52.             sample_shape = np.asarray(s).shape[1:]   
  53.             break  
  54.   
  55.     x = (np.ones((nb_samples, maxlen) + sample_shape) * value).astype(dtype)   
  56.     for idx, s in enumerate(sequences):   
  57.         if len(s) == 0:   
  58.             continue  # empty list was found   
  59.         if truncating == ’pre’:   
  60.             trunc = s[-maxlen:]   
  61.         elif truncating == ’post’:   
  62.             trunc = s[:maxlen]   
  63.         else:   
  64.             raise ValueError(‘Truncating type ”%s” not understood’ % truncating)   
  65.   
  66.         # check `trunc` has expected shape   
  67.         trunc = np.asarray(trunc, dtype=dtype)   
  68.         if trunc.shape[1:] != sample_shape:   
  69.             raise ValueError(‘Shape of sample %s of sequence at position %s is different from expected shape %s’ %   
  70.                              (trunc.shape[1:], idx, sample_shape))   
  71.   
  72.         if padding == ’post’:   
  73.             x[idx, :len(trunc)] = trunc   
  74.         elif padding == ’pre’:   
  75.             x[idx, -len(trunc):] = trunc   
  76.         else:   
  77.             raise ValueError(‘Padding type ”%s” not understood’ % padding)   
  78.     return x   
  79.   
  80.   
  81. def vectorize_stories(input_list, tar_list, word_idx, input_maxlen, tar_maxlen, vocab_size):   
  82.     x_set = []   
  83.     Y = np.zeros((len(tar_list), tar_maxlen, vocab_size), dtype=np.bool)   
  84.     for _sent in input_list:   
  85.         x = [word_idx[w] for w in _sent]   
  86.         x_set.append(x)   
  87.     for s_index, tar_tmp in enumerate(tar_list):   
  88.         for t_index, token in enumerate(tar_tmp):   
  89.             Y[s_index, t_index, word_idx[token]] = 1   
  90.   
  91.     return pad_sequences(x_set, maxlen=input_maxlen), Y   
  92.   
  93.   
  94. def tokenize(sent):   
  95.     ”’Return the tokens of a sentence including punctuation.
  96.  
  97.     >>> tokenize(‘Bob dropped the apple. Where is the apple?’)  
  98.     ['Bob', 'dropped', 'the', 'apple', '.', 'Where', 'is', 'the', 'apple', '?']  
  99.     ”’  
  100.     return [x.strip() for x in re.split('(\W+)?', sent) if x.strip()]   
  101.   
  102.   
  103. def main():   
  104.     input_text = ['1 2 3 4 5'   
  105.                   , '6 7 8 9 10'   
  106.                   , '11 12 13 14 15'   
  107.                   , '16 17 18 19 20'   
  108.                   , '21 22 23 24 25']   
  109.     tar_text = ['one two three four five'   
  110.                 , 'six seven eight nine ten'   
  111.                 , 'eleven twelve thirteen fourteen fifteen'   
  112.                 , 'sixteen seventeen eighteen nineteen twenty'   
  113.                 , 'twenty_one twenty_two twenty_three twenty_four twenty_five']   
  114.   
  115.     input_list = []   
  116.     tar_list = []   
  117.   
  118.     for tmp_input in input_text:   
  119.         input_list.append(tokenize(tmp_input))   
  120.     for tmp_tar in tar_text:   
  121.         tar_list.append(tokenize(tmp_tar))   
  122.   
  123.     vocab = sorted(reduce(lambda x, y: x | y, (set(tmp_list) for tmp_list in input_list + tar_list)))   
  124.     # Reserve 0 for masking via pad_sequences   
  125.     vocab_size = len(vocab) + 1  # keras進行embedding的時候必須進行l(wèi)en(vocab)+1   
  126.     input_maxlen = max(map(len, (x for x in input_list)))   
  127.     tar_maxlen = max(map(len, (x for x in tar_list)))   
  128.     output_dim = vocab_size   
  129.     hidden_dim = 20   
  130.   
  131.     print(‘-’)   
  132.     print(‘Vocab size:’, vocab_size, ’unique words’)   
  133.     print(‘Input max length:’, input_maxlen, ’words’)   
  134.     print(‘Target max length:’, tar_maxlen, ’words’)   
  135.     print(‘Dimension of hidden vectors:’, hidden_dim)   
  136.     print(‘Number of training stories:’, len(input_list))   
  137.     print(‘Number of test stories:’, len(input_list))   
  138.     print(‘-’)   
  139.     print(‘Vectorizing the word sequences…’)   
  140.     word_to_idx = dict((c, i + 1) for i, c in enumerate(vocab))  # 編碼時需要將字符映射成數(shù)字index   
  141.     idx_to_word = dict((i + 1, c) for i, c in enumerate(vocab))  # 解碼時需要將數(shù)字index映射成字符   
  142.     inputs_train, tars_train = vectorize_stories(input_list, tar_list, word_to_idx, input_maxlen, tar_maxlen, vocab_size)   
  143.   
  144.     decoder_mode = 1  # 0 最簡單模式,1 [1]向后模式,2 [2] Peek模式,3 [3]Attention模式   
  145.     if decoder_mode == 3:   
  146.         encoder_top_layer = LSTM(hidden_dim, return_sequences=True)   
  147.     else:   
  148.         encoder_top_layer = LSTM(hidden_dim)   
  149.   
  150.     if decoder_mode == 0:   
  151.         decoder_top_layer = LSTM(hidden_dim, return_sequences=True)   
  152.         decoder_top_layer.get_weights()   
  153.     elif decoder_mode == 1:   
  154.         decoder_top_layer = LSTMDecoder(hidden_dim=hidden_dim, output_dim=hidden_dim   
  155.                                         , output_length=tar_maxlen, state_input=False, return_sequences=True)   
  156.     elif decoder_mode == 2:   
  157.         decoder_top_layer = LSTMDecoder2(hidden_dim=hidden_dim, output_dim=hidden_dim   
  158.                                          , output_length=tar_maxlen, state_input=False, return_sequences=True)   
  159.     elif decoder_mode == 3:   
  160.         decoder_top_layer = AttentionDecoder(hidden_dim=hidden_dim, output_dim=hidden_dim   
  161.                                              , output_length=tar_maxlen, state_input=False, return_sequences=True)   
  162.   
  163.     en_de_model = Sequential()   
  164.     en_de_model.add(Embedding(input_dim=vocab_size,   
  165.                               output_dim=hidden_dim,   
  166.                               input_length=input_maxlen))   
  167.     en_de_model.add(encoder_top_layer)   
  168.     if decoder_mode == 0:   
  169.         en_de_model.add(RepeatVector(tar_maxlen))   
  170.     en_de_model.add(decoder_top_layer)   
  171.   
  172.     en_de_model.add(TimeDistributedDense(output_dim))   
  173.     en_de_model.add(Activation(‘softmax’))   
  174.     print(‘Compiling…’)   
  175.     time_start = time.time()   
  176.     en_de_model.compile(loss=’categorical_crossentropy’, optimizer=’rmsprop’)   
  177.     time_end = time.time()   
  178.     print(‘Compiled, cost time:%fsecond!’ % (time_end - time_start))   
  179.     for iter_num in range(5000):   
  180.         en_de_model.fit(inputs_train, tars_train, batch_size=3, nb_epoch=1, show_accuracy=True)   
  181.         out_predicts = en_de_model.predict(inputs_train)   
  182.         for i_idx, out_predict in enumerate(out_predicts):   
  183.             predict_sequence = []   
  184.             for predict_vector in out_predict:   
  185.                 next_index = np.argmax(predict_vector)   
  186.                 next_token = idx_to_word[next_index]   
  187.                 predict_sequence.append(next_token)   
  188.             print(‘Target output:’, tar_text[i_idx])   
  189.             print(‘Predict output:’, predict_sequence)   
  190.   
  191.         print(‘Current iter_num is:%d’ % iter_num)   
  192.   
  193. if __name__ == ’__main__‘:   
  194.     main()   

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本女优一区二区三区免费| 欧美日韩少妇精品专区性色| 国产精品自拍杆香蕉视频| 亚洲视频一级二级三级| 亚洲一区二区精品久久av| 亚洲精选91福利在线观看 | 久久精品免费视看国产成人| 亚洲国产欧美久久精品| 色偷偷偷拍视频在线观看| 日本免费一级黄色录像| 好吊日视频这里都是精品| 中文字幕乱子论一区二区三区| 国产精品亚洲二区三区| 熟女少妇一区二区三区蜜桃| 东京热加勒比一区二区三区| 午夜福利视频六七十路熟女| 丰满人妻熟妇乱又伦精另类视频| 亚洲一区二区三区三州| 亚洲妇女作爱一区二区三区| 偷拍美女洗澡免费视频| 日韩精品一区二区毛片| 九九久久精品久久久精品| 亚洲国产精品一区二区毛片| 欧美不卡一区二区在线视频| 懂色一区二区三区四区| 高潮日韩福利在线观看| 成人免费视频免费观看| 精品香蕉国产一区二区三区| 亚洲婷婷开心色四房播播| 人妻精品一区二区三区视频免精| 国产日韩综合一区在线观看| 丰满少妇被粗大猛烈进出视频 | 十八禁日本一区二区三区| 伊人国产精选免费观看在线视频| 91播色在线免费播放| 欧美人妻一区二区三区| 日韩高清一区二区三区四区| 99热九九热这里只有精品| 伊人国产精选免费观看在线视频| 亚洲中文字幕人妻系列| 亚洲中文字幕乱码亚洲|