本文所用代码请见 我的Github,版权归属于 Udacity 和 Andrew Trask。
在神经网络构建的过程中,为了快速实现模型迭代,可能在初期的时候对于问题作了基本的分析之后就开始打造网络的雏形了,一个工作正常但精度或效率不高的模型要远好于理论上精度奇高但从未完整运行成功过一次的模型。
在 Udacity 的这个影评情感分析练习中,在初期了解了电影评论的积极与消极倾向可以由评论中出现的词汇来进行预测后就可以动手打造网络了。最初的版本是将训练集中所有可能出现的词汇构成一个很长的 review_vocab 数组,这种处理方式相当于将各个词汇作为 类别数据 进行处理,在此基础上对于任意一个训练样本中的影评输入,统计其中出现的单词及其数量,以此更新其在 review_vocab 上相应位置的值,将这个向量作为网络的输入进行一个样本的训练。
后续在训练中发现网络的训练效率很低,此时,可以不急于使用那些高级的数据处理技术,可以先回过头来对于初期的实现方式进行评价,例如评论中实际上很多中性的冠词出现的频率甚至远高于带有感情色彩的形容词,此时在统计输入中如果只考虑单词是否出现,而不统计单词出现的数量,对于网络的预测能力可能就是有提升的。此时只需要将输入向量中所有出现的单词的位置设置成 1 ,在实际运算中可以发现这个小小的改动对于提高预测准确性有很大的影响。
进一步地,可以发现网络在每一个样本的计算过程中要计算大量的输入中的 0 与权重的乘法,而如果有办法将这些输入中的非零位置索引出来,将隐藏层的输出直接定义为输入与隐藏层权重参数的乘法而不是两个向量相乘就可以减少大量的计算。更进一步地,由于输入中所有非零位置的元素都为 1,那么可以直接将隐藏层的输出定义为对应输入向量非零位置的权重参数的加法。这里需要注意的是在构建每一个评论的索引列表时,索引位置还是基于相应单词在之前的 review_vobab 数组中的位置,这样可以不改变输入层到隐藏层矩阵的形状 (input_nodes, hidden_nodes) ,其中 input_nodes = len(review_vocab) 使得模型的代码修改量最小。
最后,还可以根据部分带有感情色彩的语气词在积极评价中出现的频率高于消极评价这一点,进一步改进输入参数设置,将频率过高及过低的助词直接在训练之前过滤掉,减少模型中所需要的特征输入的量,讲师 Andrew Trask 提到这一方式在自然语言处理中比较常用。总结起来就是对于问题的分析和前期的数据处理非常重要,将很大程度上决定算法的效率,在高效的算法的基础上建立的模型,才能体现出算力的重要性,否则只会浪费硬件。