美文网首页
keras学习-RNN

keras学习-RNN

作者: 锦绣拾年 | 来源:发表于2020-09-08 15:51 被阅读0次

    keras-RNN

    参考《python深度学习》

    关于RNN

    questions : 每次 RNN神经元个数代表什么,输入又代表什么? 输入的是一个RNN的词数? 具体详细的描述:https://zhuanlan.zhihu.com/p/47412782 可以这么理解。

    首先,RNN也不过是一个普通的全连接网络,RNN神经元的个数,代表着全连接网络的一层,这一层可以有很多神经元 如:

    model.add(LSTM(hidden_featrue, input_shape=(timestamp, input_feature)))
    

    hidden_featrue:就是全连接的一层,即units 个数。 timestamp :一句话,有多少个单词(或填充后的长度) input_feature :可以理解为词向量的长度。然后它本身这个全连接网络,会遍历timestamp中每一个维度进行迭代。 相当于它的输入其实是input_feature,然后遍历timestamp次。 然后遍历完一句话得到一个输出。

    堆多层,只是堆两个全连接层里的层罢了,想要时序反过来(比如双向LSTM)就需要专门的另一个设置

    以下:RNN的numpy实现

    import numpy as np
    
    timesteps = 100 # 输入序列的时间步数
    input_features = 32 #输入特征空间的维度
    output_features = 64 #输出特征空间的维度
    
    inputs = np.random.random((timesteps,input_features)) # 100×32
    
    state_t = np.zeros((output_features,))
    
    # 以下是权重矩阵
    W = np.random.random((output_features,input_features))#全连接层的权重
    U = np.random.random((output_features,output_features))#输出输出的迭代
    b = np.random.random((output_features,))#全连接层
    
    successive_outputs = []
    for input_t in inputs:
        output_t = np.tanh(np.dot(W,input_t)+np.dot(U,state_t)+b)
        
        successive_outputs.append(output_t) #隐状态输出
        state_t = output_t
    final_output_sequence = np.stack(successive_outputs, axis=0)#时间步个output
    #不过keras呢?
    '''
    本例中,最终输出是一个形状为 (timesteps, output_features) 的二维张量,其中
    每个时间步是循环在 t 时刻的输出。输出张量中的每个时间步 t 包含输入序列中时间步
    0 ~ t 的信息,即关于全部过去的信息。因此,在多数情况下,你并不需要这个所有输出
    组成的序列,你只需要最后一个输出(循环结束时的 output_t ),因为它已经包含了整
    个序列的信息。
    '''
    

    使用keras RNN

    二者有一点小小的区别: SimpleRNN 层能够像其他 Keras 层一样处理序列批量,而不是 像 Numpy 示例那样只能处理单个序列。因此,它接收形状为 (batch_size, timesteps, input_features) 的输入,而不是 (timesteps, input_features) 与 Keras 中的所有循环层一样, SimpleRNN 可以在两种不同的模式下运行:一种是返回每 个时间步连续输出的完整序列,即形状为 (batch_size, timesteps, output_features) 的三维张量;另一种是只返回每个输入序列的最终输出,即形状为 (batch_size, output_ features) 的二维张量。 这两种模式由 return_sequences 这个构造函数参数来控制。

    from keras.models import Sequential
    from keras.layers import Embedding, SimpleRNN
    model = Sequential()
    model.add(Embedding(10000,32)) # 10000个词,32维
    #embedding_layer = Embedding(vocab_size, W2V_SIZE, weights=[embedding_matrix], input_length=SEQUENCE_LENGTH, trainable=False)
    #↑之前写的一个代码的参考
    model.add(SimpleRNN(32))
    model.summary()
    # 注意下面:输出了一个32维的,就是32个神经元(类比全连接层32个神经元)的结果
    
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding (Embedding)        (None, None, 32)          320000    
    _________________________________________________________________
    simple_rnn (SimpleRNN)       (None, 32)                2080      
    =================================================================
    Total params: 322,080
    Trainable params: 322,080
    Non-trainable params: 0
    _________________________________________________________________
    
    #如果返回完整的呢?
    model = Sequential()
    model.add(Embedding(10000,32,input_length=100))
    model.add(SimpleRNN(32,return_sequences=True))
    model.summary()
    #注意输出就是100个32个神经元。100就是时序
    
    Model: "sequential_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding_2 (Embedding)      (None, 100, 32)           320000    
    _________________________________________________________________
    simple_rnn_1 (SimpleRNN)     (None, 100, 32)           2080      
    =================================================================
    Total params: 322,080
    Trainable params: 322,080
    Non-trainable params: 0
    _________________________________________________________________
    

    为了提高网络的表示能力,将多个循环层逐个堆叠有时也是很有用的。在这种情况下,你需要让所有中间层都返回完整的输出序列。 参数计算:https://zhuanlan.zhihu.com/p/52618361

    model = Sequential()
    model.add(Embedding(10000, 32,input_length=100))
    model.add(SimpleRNN(32, return_sequences=True))
    model.add(SimpleRNN(32, return_sequences=True))
    model.add(SimpleRNN(32, return_sequences=True))
    model.add(SimpleRNN(32))
    model.summary()
    
    Model: "sequential_3"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding_3 (Embedding)      (None, 100, 32)           320000    
    _________________________________________________________________
    simple_rnn_2 (SimpleRNN)     (None, 100, 32)           2080      
    _________________________________________________________________
    simple_rnn_3 (SimpleRNN)     (None, 100, 32)           2080      
    _________________________________________________________________
    simple_rnn_4 (SimpleRNN)     (None, 100, 32)           2080      
    _________________________________________________________________
    simple_rnn_5 (SimpleRNN)     (None, 32)                2080      
    =================================================================
    Total params: 328,320
    Trainable params: 328,320
    Non-trainable params: 0
    

    双向RNN

    model = Sequential()
    model.add(layers.Embedding(max_features, 32))
    model.add(layers.Bidirectional(layers.LSTM(32)))
    model.add(layers.Dense(1, activation='sigmoid'))
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
    history = model.fit(x_train, y_train,epochs=10,batch_size=128,validation_split=0.2)
    

    Tips:

    1. 关于评估方法的选择,对于不平衡数据问题:比如分类,90%A,10%B,都预测A就会有90%的准确率,因此一个好的模型应该>90%。
      比如预测温度,这里可以考虑预测后一天温度=今天,这种情况下,得到的结果为 0.29,因为温度数据被标准化成均值为 0、标准差为 1,所以无法直接对这个值进行解释。它转化成温度的平均绝对误差为 0.29× temperature_std 摄氏度,即 2.57℃。因此好的模型得到的结果应该比这个好。
      遇到新问题时,最好首先为你选择的指标建立一个基于常识的基准。如果没有需要打败的基准,那么就无法分辨是否取得了真正的进步
      2.是否使用双向RNN或更深层的RNN要考虑问题内容,GRU 层通常更善于记住最近的数据,而不是久远的数据,与更早的数据点相比,更靠后的天气数据点对问题自然具有更高的预测能力(这也是基于常识的基准方法非常强大的原因)。因此,按时间正序的模型必然会优于时间逆序的模型。重要的是,对许多其他问题(包括自然语言)而言,情况并不是这样:直觉上来看,一个单词对理解句子的重要性通常并不取决于它在句子中的位置。这时,正序和逆序的效果相似。

    相关文章

      网友评论

          本文标题:keras学习-RNN

          本文链接:https://www.haomeiwen.com/subject/xefjektx.html