詳細解讀簡單的lstm的實例


http://blog.csdn.net/zjm750617105/article/details/51321889


本文是初學keras這兩天來,自己仿照addition_rnn.py,寫的一個實例,數據處理稍微有些不同,但是准確性相比addition_rnn.py 差一點,下面直接貼代碼,
解釋和注釋都在代碼里邊。

[python]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-family: Arial, Helvetica, sans-serif;">#coding:utf-8</span>  
[python]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
    1. from keras.models import  Sequential  
    2. from keras.layers.recurrent import LSTM  
    3. from utils import  log  
    4. from numpy import random  
    5. import numpy as np  
    6. from  keras.layers.core import RepeatVector, TimeDistributedDense, Activation  
    7.   
    8. ''''' 
    9. 先用lstm實現一個計算加法的keras版本, 根據addition_rnn.py改寫 
    10. size: 500 
    11. 10次: test_acu = 0.3050  base_acu= 0.3600 
    12. 30次: rest_acu = 0.3300  base_acu= 0.4250 
    13. size: 50000 
    14. 10次: test_acu: loss: 0.4749 - acc: 0.8502 - val_loss: 0.4601 - val_acc: 0.8539 
    15.       base_acu: loss: 0.3707 - acc: 0.9008 - val_loss: 0.3327 - val_acc: 0.9135 
    16. 20次: test_acu: loss: 0.1536 - acc: 0.9505 - val_loss: 0.1314 - val_acc: 0.9584 
    17.       base_acu: loss: 0.0538 - acc: 0.9891 - val_loss: 0.0454 - val_acc: 0.9919 
    18. 30次: test_acu: loss: 0.0671 - acc: 0.9809 - val_loss: 0.0728 - val_acc: 0.9766 
    19.       base_acu: loss: 0.0139 - acc: 0.9980 - val_loss: 0.0502 - val_acc: 0.9839 
    20. '''  
    21.   
    22. log = log()  
    23. #defination the global variable  
    24. training_size = 50000  
    25. hidden_size = 128  
    26. batch_size = 128  
    27. layers = 1  
    28.   
    29. maxlen = 7  
    30. single_digit = 3  
    31.   
    32.   
    33. def generate_data():  
    34.     log.info("generate the questions and answers")  
    35.     questions = []  
    36.     expected = []  
    37.     seen = set()  
    38.     while len(seen) < training_size:  
    39.         num1 = random.randint(1, 999) #generate a num [1,999]  
    40.         num2 = random.randint(1, 999)  
    41.         #用set來存儲又有排序,來保證只有不同數據和結果  
    42.         key  = tuple(sorted((num1,num2)))  
    43.         if key in seen:  
    44.             continue  
    45.         seen.add(key)  
    46.         q = '{}+{}'.format(num1,num2)  
    47.         query = q + ' ' * (maxlen - len(q))  
    48.         ans = str(num1 + num2)  
    49.         ans = ans + ' ' * (single_digit + 1 - len(ans))  
    50.         questions.append(query)  
    51.         expected.append(ans)  
    52.     return questions, expected  
    53.   
    54. class CharacterTable():  
    55.     ''''' 
    56.     encode: 將一個str轉化為一個n維數組 
    57.     decode: 將一個n為數組轉化為一個str 
    58.     輸入輸出分別為 
    59.     character_table =  [' ', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] 
    60.     如果一個question = [' 123+23'] 
    61.     那個改question對應的數組就是(7,12): 
    62.     同樣expected最大是一個四位數[' 146']: 
    63.     那么ans對應的數組就是[4,12] 
    64.     '''  
    65.     def __init__(self, chars, maxlen):  
    66.         self.chars = sorted(set(chars))  
    67.         ''''' 
    68.         >>> b = [(c, i) for i, c in enumerate(a)] 
    69.         >>> dict(b) 
    70.         {' ': 0, '+': 1, '1': 3, '0': 2, '3': 5, '2': 4, '5': 7, '4': 6, '7': 9, '6': 8, '9': 11, '8': 10} 
    71.         得出的結果是無序的,但是下面這種方式得出的結果是有序的 
    72.         '''  
    73.         self.char_index = dict((c, i) for i, c in enumerate(self.chars))  
    74.         self.index_char = dict((i, c) for i, c in enumerate(self.chars))  
    75.         self.maxlen = maxlen  
    76.   
    77.     def encode(self, C, maxlen):  
    78.         X = np.zeros((maxlen, len(self.chars)))  
    79.         for i, c in enumerate(C):  
    80.             X[i, self.char_index[c]] = 1  
    81.         return X  
    82.   
    83.     def decode(self, X, calc_argmax=True):  
    84.         if calc_argmax:  
    85.             X = X.argmax(axis=-1)  
    86.         return ''.join(self.index_char[x] for x in X)  
    87.   
    88. chars = '0123456789 +'  
    89. character_table = CharacterTable(chars,len(chars))  
    90.   
    91. questions , expected = generate_data()  
    92.   
    93. log.info('Vectorization...') #失量化  
    94. inputs = np.zeros((len(questions), maxlen, len(chars))) #(5000, 7, 12)  
    95. labels = np.zeros((len(expected), single_digit+1, len(chars))) #(5000, 4, 12)  
    96.   
    97. log.info("encoding the questions and get inputs")  
    98. for i, sentence in enumerate(questions):  
    99.     inputs[i] = character_table.encode(sentence, maxlen=len(sentence))  
    100. #print("questions is ", questions[0])  
    101. #print("X is ", inputs[0])  
    102. log.info("encoding the expected and get labels")  
    103. for i, sentence in enumerate(expected):  
    104.     labels[i] = character_table.encode(sentence, maxlen=len(sentence))  
    105. #print("expected is ", expected[0])  
    106. #print("y is ", labels[0])  
    107.   
    108. log.info("total inputs is %s"%str(inputs.shape))  
    109. log.info("total labels is %s"%str(labels.shape))  
    110.   
    111. log.info("build model")  
    112. model = Sequential()  
    113. ''''' 
    114. LSTM(output_dim, init='glorot_uniform', inner_init='orthogonal', 
    115.                  forget_bias_init='one', activation='tanh', 
    116.                  inner_activation='hard_sigmoid', 
    117.                  W_regularizer=None, U_regularizer=None, b_regularizer=None, 
    118.                  dropout_W=0., dropout_U=0., **kwargs) 
    119. output_dim: 輸出層的維數,或者可以用output_shape 
    120. init: 
    121.     uniform(scale=0.05) :均勻分布,最常用的。Scale就是均勻分布的每個數據在-scale~scale之間。此處就是-0.05~0.05。scale默認值是0.05; 
    122.     lecun_uniform:是在LeCun在98年發表的論文中基於uniform的一種方法。區別就是lecun_uniform的scale=sqrt(3/f_in)。f_in就是待初始化權值矩陣的行。 
    123.     normal:正態分布(高斯分布)。 
    124.     Identity :用於2維方陣,返回一個單位陣. 
    125.     Orthogonal:用於2維方陣,返回一個正交矩陣. lstm默認 
    126.     Zero:產生一個全0矩陣。 
    127.     glorot_normal:基於normal分布,normal的默認 sigma^2=scale=0.05,而此處sigma^2=scale=sqrt(2 / (f_in+ f_out)),其中,f_in和f_out是待初始化矩陣的行和列。 
    128.     glorot_uniform:基於uniform分布,uniform的默認scale=0.05,而此處scale=sqrt( 6 / (f_in +f_out)) ,其中,f_in和f_out是待初始化矩陣的行和列。 
    129. W_regularizer , b_regularizer  and activity_regularizer: 
    130.     官方文檔: http://keras.io/regularizers/ 
    131.     from keras.regularizers import l2, activity_l2 
    132.     model.add(Dense(64, input_dim=64, W_regularizer=l2(0.01), activity_regularizer=activity_l2(0.01))) 
    133.  
    134.     加入規則項主要是為了在小樣本數據下過擬合現象的發生,我們都知道,一半在訓練過程中解決過擬合現象的方法主要中兩種,一種是加入規則項(權值衰減), 第二種是加大數據量 
    135.     很顯然,加大數據量一般是不容易的,而加入規則項則比較容易,所以在發生過擬合的情況下,我們一般都采用加入規則項來解決這個問題. 
    136.  
    137. '''  
    138. model.add(LSTM(hidden_size, input_shape=(maxlen, len(chars)))) #(7,12) 輸入層  
    139. ''''' 
    140. keras.layers.core.RepeatVector(n) 
    141.        把1維的輸入重復n次。假設輸入維度為(nb_samples, dim),那么輸出shape就是(nb_samples, n, dim) 
    142.        inputshape: 任意。當把這層作為某個模型的第一層時,需要用到該參數(元組,不包含樣本軸)。 
    143.        outputshape:(nb_samples,nb_input_units) 
    144. '''  
    145. model.add(RepeatVector(single_digit + 1))  
    146. #表示有多少個隱含層  
    147. for _ in range(layers):  
    148.     model.add(LSTM(hidden_size, return_sequences=True))  
    149. ''''' 
    150. TimeDistributedDense: 
    151. 官方文檔:http://keras.io/layers/core/#timedistributeddense 
    152.  
    153. keras.layers.core.TimeDistributedDense(output_dim,init='glorot_uniform', activation='linear', weights=None 
    154. W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None, 
    155. input_dim=None, input_length=None) 
    156. 這是一個基於時間維度的全連接層。主要就是用來構建RNN(遞歸神經網絡)的,但是在構建RNN時需要設置return_sequences=True。 
    157. for example: 
    158. # input shape: (nb_samples, timesteps,10) 
    159. model.add(LSTM(5, return_sequences=True, input_dim=10)) # output shape: (nb_samples, timesteps, 5) 
    160. model.add(TimeDistributedDense(15)) # output shape:(nb_samples, timesteps, 15) 
    161. W_constraint: 
    162.     from keras.constraints import maxnorm 
    163.     model.add(Dense(64, W_constraint =maxnorm(2))) #限制權值的各個參數不能大於2 
    164. '''  
    165. model.add(TimeDistributedDense(len(chars)))  
    166. model.add(Activation('softmax'))  
    167. ''''' 
    168. 關於目標函數和優化函數,參考另外一片博文: http://blog.csdn.net/zjm750617105/article/details/51321915 
    169. '''  
    170. model.compile(loss='categorical_crossentropy',  
    171.               optimizer='adam',  
    172.               metrics=['accuracy'])  
    173.   
    174. # Train the model each generation and show predictions against the validation dataset  
    175. for iteration in range(1, 3):  
    176.     print()  
    177.     print('-' * 50)  
    178.     print('Iteration', iteration)  
    179.     model.fit(inputs, labels, batch_size=batch_size, nb_epoch=2,  
    180.               validation_split = 0.1)  
    181.     # Select 10 samples from the validation set at random so we can visualize errors  
    182. model.get_config()  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM