美文网首页
初识循环神经网络

初识循环神经网络

作者: 元宝的技术日常 | 来源:发表于2020-05-06 15:03 被阅读0次

    1、循环神经网络-RNN的由来

    之前写到的CNN,用的领域在计算机视觉-CV;接下来介绍的RNN的主要作用的领域是自然语言处理-NLP。

    自然语言处理包括了现在最常见的领域:语音识别、语音模型、机器翻译、视频解说、文本分类和图片生成描述等等。为什么RNN能生效?

    要从输入开始说起,之前说到的CNN都是固定大小的输入和模型的输出值;但在自然语言处理领域内的输入和输出都不在是定长了。比方:图片生成描述,输入一张图片,输出为一个句子;文本分类,输入是一段文本,输出是一个类别等。

    现在要是还用之前CNN思想,要把变长的输入问题解决掉,怎么解决呢?

    因为NLP处理的是自然语言,像机器翻译,输入的是一段字符串,而对于网络来说,能处理的只有数字,所以输入必须经过一定的处理,才能给网络来计算,这个处理的步骤称作为embedding。提到embedding,先来个相似的在CNN常用的概念 -- one-hot编码,假设我们的词表有5个,“公主很漂亮”。基本样子如下:

    公 [0 0 0 0 1]
    主 [0 0 0 1 0]
    很 [0 0 1 0 0]
    漂 [0 1 0 0 0] 
    亮 [1 0 0 0 0]
    

    可以看出,将所有的词做成了一个词表,每个词在词表中的相应位置标记为了1。那如果用一个向量来表示“公主很漂亮”的话,则为[4,3,2,1,0],这种编码方式被称作为稀疏编码。

    针对稀疏编码来讲,如果要求输入的长度必须一致的话,当稀疏编码后的向量长度不够时,要引进padding的概念,也就是在稀疏编码后向量中添加某个值,补齐长度,这个值一般是自己定义的unknown word;而当稀疏编码后的长度过长时,则直接将过长的部分截断。

    在稀疏编码的基础上,如果将每个词映射到一个向量上,而不是直接的取该词在词表中的索引,像:

    公主 [ 1.0  0.25  1.0]
    王妃 [ 0.6  0.75  1.0]
    

    这种方式的编码,称作为dense_embedding,常在RNN中简称为embedding,密集编码。

    针对密集编码来讲,如果要求输入的长度必须一致的话,采用的方法是合并。n个词语依次embedding,假设embedding向量的长度为10,那么结果组合就为 n * 10 矩阵,对于全连接的输入大小是固定的,所以用global_avg_pooling,将横向的维度消掉,变为长度为10 的向量。

    而稀疏编码和密集编码这两种方式的缺点:
    1、信息丢失:

    • 多个embedding合并后 有pad噪音 因为参与了avg_pooling计算 噪音过多 将原来的意思稀释
    • 即时没有pad 直接合并 没有句子中主次之分 像文本分类中更倾向的表达情感的词语 主语、连接词并不太重要 真实意思被稀释掉

    2、无效计算太多,低效:
    太多的padding 如果句子本身长度为20 而定长为500 480个padding 参与了计算 增加训练的速度 浪费资源 低效

    能不能完美地解决输入变长这个问题,接下来要引出循环神经网络-RNN了。

    2、RNN的基本结构

    循环神经网络结构

    如图所示,输入的Xt,经过A操作后会输出ht,在A框周围的线表示一种循环,将此次进过A的中间状态st,作为下一步Xt+1的额外输入。而下次输入的Xt+1和此次的Xt使用同样的激活函数和参数。

    拆开来看:


    循环神经网络结构 带参数的循环神经网络结构

    整个计算过程为下图:


    循环神经网络计算过程

    这样,不管输入的长度有多长,每次输入的Xt都经过同一组参数的循环神经网络,中间维持的隐藏层h即为试图包含整个句子的所有信息的一个状态值。每个输入对应的输出值即为此次的预测值。

    3、参数量

    计算参数量得从两个大的步骤来看,第一步是通过隐藏层h,计算此次的中间状态ht时的参数量,有关联的是U、W,假设维护中间转态ht的W为32层的隐含层网络,则W的参数为 32 * 32,输入的xt的embedding的维度为16维,则U的参数为 16 * 32 ,偏置b 为 32;第二步输出o,中间维护的状态W大小为 32 * 32,如果输出10个类别,则V的参数为 32 * 10,偏置b 为 10。

    使用TensorFlow2.0 ,调用rnn:

    embedding_dim = 16 #词语embedding的维度
    batch_size = 512 #批次取多少条数据
    vocab_size = 10000 #词表大小
    max_length = 500 # 句子最长的长度
    
    # 单层rnn 
    single_rnn_model = keras.models.Sequential([
        keras.layers.Embedding(vocab_size, embedding_dim,
                               input_length = max_length),
        keras.layers.SimpleRNN(units = 32, return_sequences = False), 
        # return_sequences 是否每次调用隐含层都需要输出  False-最后在输出一个值  TRUE-每次都输出一个值
        keras.layers.Dense(64, activation = 'relu'),
        keras.layers.Dense(1, activation='sigmoid'),
    ])
    
    single_rnn_model.summary()
    single_rnn_model.compile(optimizer = 'adam',
                             loss = 'binary_crossentropy',
                             metrics = ['accuracy'])
    

    参数数目:

    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding_2 (Embedding)      (None, 500, 16)           160000    
    _________________________________________________________________
    simple_rnn_3 (SimpleRNN)     (None, 32)                1568      
    _________________________________________________________________
    dense_4 (Dense)              (None, 64)                2112      
    _________________________________________________________________
    dense_5 (Dense)              (None, 1)                 65        
    =================================================================
    Total params: 163,745
    Trainable params: 163,745
    Non-trainable params: 0
    _________________________________________________________________
    

    4、参考资料

    相关文章

      网友评论

          本文标题:初识循环神经网络

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