详细解读简单的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()  
posted @ 2017-04-24 13:05  Django's blog  阅读(3281)  评论(0编辑  收藏  举报