using keras learn Neural networks (2)

15 篇文章 1 订阅
5 篇文章 0 订阅

        上节探究了模型输入和神经元输出的关系,其主要是为了疏理清楚一些之前的思维误区,为了更好的理解RNN。同时也是因为自己在之前的学习过程始终存在一些不明白的地方,正所谓理越辨越明,学习之路任重而道远,特此记录下来,可以帮助到同时也存在相同困惑的童鞋们(天才少年可以跳过,不浪费时间),若理解有误,欢迎拍砖纠正

         词嵌入是现在基于nn处理各种NLP任务的First step,所以有义务好好理解它。这里特殊说明,词嵌入是对词表征的一种形式。而word2vec、glove是模型,是用于实现这种词嵌入的方法。

        词嵌入其实就是输入层经过一次常规层的计算后的那层权重,而该层的权重是通过后续构造的输出层与学习目标构造的损失函数通过梯度下降进行反向传播学习到的。其本质就是简单的常规层(常规层就是隐藏层,这里为了区别其他高级层,以此命名),只是后续为了达到词表征的目的而制定了一些和语言相关的学习策略而已,像word2vec就是通过语言模型来构造输入输出,来学习训练词向量的。 

        \tiny \begin{pmatrix} w_{1,1} & w_{1,2} & ... & w_{1,n} \\ w_{2,1} & w_{2,2} & ... & w_{2, n} \\\vdots &\vdots &\vdots &\vdots \\ w_{m, 1} & w_{m, 2} & ... & w_{m,n} \end{pmatrix} * \begin{pmatrix}x{_{1}} \\x_{2} \\\vdots \\ \vdots \\ \vdots \\ x_{n-1} \\ x_{n} \end{pmatrix} = \begin{pmatrix} w_{1,1}x_{1} + w_{1,2} x_{2} + \cdots + w_{1,n}x_{n} \\ w_{2,1}x_{1} + w_{2,2} x_{2} + \cdots + w_{2,n}x_{n} \\ \vdots \\ w_{m,1}x_{1} + w_{m,2} x_{2} + \cdots + w_{m,n}x_{n} \end{pmatrix} = \begin{pmatrix} \sum_{i=1}^{n}w_{1, i}x_{i} \\ \sum_{i=1}^{n}w_{2, i}x_{i} \\ \vdots \\ \sum_{i=1}^{n}w_{m , i}x_{i} \end{pmatrix}

       上图的运算表示了输入特征和权重之间的运算。特征向量X=[x1, x2, .... , xn] 表示有n个特征,而权重矩阵的维度为 (m, n),m就表示输出m个神经元。       

import numpy as np
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from keras.layers.core import Dense
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.text import one_hot, text_to_word_sequence
x1 = np.array([1, 2, 3]).reshape((-1, 3))
model = Sequential()
model.add(Dense(10, input_shape=(3, )))
model.predict(x1)

  

    上图设置一 层Dense layer并设置untis=10,输入特征向量 X = [1, 2, 3],这里得到了10个输出结果。通过model.get_weights() 和 model.summary() 来查看模型的参数和权重。

       

        

        权重矩阵的维度为(3, 10),3代表特征数,10代表神经元结点数,这是上文公式权重矩阵的转置后的形式。其实该矩阵就是词嵌入初始化状态。模型参数之所以多出10个,是因为还有偏置(线性回归当中Y = WX + B,即这个B)。

        既然词嵌入是简单的常规层计算,干嘛还要搞个embedding layer出来。那是因为我们输入特征的特殊性。常规输入的特征每个特征都有各自对应的数字,而做在NLP时我们输入的特征是一个长长的one_hot的,除了当前特征的数字为1,其他维度上的特征均为0。

       \tiny \begin{pmatrix} w_{1,1} & w_{1,2} & ... & w_{1,n} \\ w_{2,1} & w_{2,2} & ... & w_{2, n} \\\vdots &\vdots &\vdots &\vdots \\ w_{m, 1} & w_{m, 2} & ... & w_{m,n} \end{pmatrix} * \begin{pmatrix} 1} \\0 \\0 \\ 0 \\ \vdots \\ 0 \\ 0 \end{pmatrix} = \begin{pmatrix} w_{1, 1} \\ w_{2, 1} \\ \vdots \\ w_{m , 1} \end{pmatrix}       

x2 = np.array([1, 0, 0]).reshape((-1, 3))
model = Sequential()
model.add(Dense(10, input_shape=(3, )))
model.predict(x2)

  

         通过model.get_weights() 获取权重

 

       从上图可以发现,最后的输出结果就是得到权重矩阵的第一行。有此可以得到启示,不需要再进行矩阵运算,因为当输入向量维度很高时,会进行大量的不必要计算。取而代之的是直接通过索引去权重矩阵中查找对应的输出结果。       

vec_len = 5
num_words = 10
text = ["我 是 谁"]
tokenizer = Tokenizer(num_words)
tokenizer.fit_on_texts(text)
x_data = np.array(tokenizer.texts_to_sequences(text))
print(x_data)
model_1 = Sequential()
# use Embedding
model_1.add(Embedding(num_words, vec_len, input_length=3))
model_1.predict(x_data)

  

        这里同输入一句话,得到了句子当中每个词对应向量输出,其中vec_len代表输出神经元的个数,也就是词向量的长度。num_words代表了特征数目,也就是词典中词的数目。

         同样使用model.get_weights() 来获取权重矩阵。

         

        矩阵维度为(10, 5), 10代表特征数,5代表神经元结点数,即(词典大小,词向量长度) ,仔细观察会发现,embedding层最后的输出结果即使按照索引[1, 2, 3]在上述矩阵中查找的结果。

         思维拓展: 每一个创新点的背后都是在原有技术的基础上进行改进和升级,但其本质还是原有技术的原理。所以基础确实非常重要,各种网络层,其实之不过是在玩矩阵而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值