阅读 320

神经网络中的运算(神经网络实现逻辑运算)

先前我们画了一个类似如下的神经网络图。对于每一层而言,只画了一个框用来表示一整层,而没有用一个个神经元去表示,尽管实际上它确实有相当多神经元,如果使用线来表示关系也确实很复杂。 但是很幸运的是,实际上我们不需要对每一个神经元进行精密的控制,我们有统一的处理方法,也就是矩阵。

考虑这样的情况,假设输入的是一个样本,它有 n 个特征,它会通过一层。而这 m 个神经元,这些神经元的输出将会做为接下来一层的输入。

出于统一性的考虑,一个很自然的想法是,一层输入的形状特征,和下一层输入的形状特征应该是一样的(这里用词可能不太准确,意会一下)。

比如说输入的形状是 1×n1 \times n1×n 而一层的输出是 m 个神经元,它们的神经元的权值会和输入保持一致。所以现在需要考虑它是 n×mn\times mn×m 还是 m×nm\times nm×n

对于输入的数据,每个神经元都需要和它做一个计算,最后得到一个值(暂且先不考虑偏置 b )。

而这个计算相当于是向量的点积。注意前述的形状以及这里的点积,很容易让人联想到矩阵乘法。

X(1,n)×W(n,m)=XW(1,m)X(1,n) \times W(n,m) = XW(1,m)X(1,nW(n,m)=XW(1,m)

可以再考虑验证一下,对于计算得到的结果,考虑第一个位置的值

XW1,1=∑k=1nx1kwk1=X⃗1⋅W⃗1XW_{1,1} =\sum _{k=1}^{n}x_{1k}w_{k1} = \vec X_1 \cdot {\vec W_1}XW1,1=k=1nx1kwk1=X1W1

其中代指 A 的第 1 行,和 B 的第 1 列。而对 B 而言,此时它的列就是一个神经元的所有权值。也就是说验证结果是正确的。

明白了这一点,实际上还可以从更简单的角度去考虑。矩阵乘法就是一个变换,在空间和空间之间进行变换。这里相当于将数据从 n 维的空间变换到 m 维的空间。中间自然是使用矩阵乘法。

偏置的理解反而更容易了,因为它实际就是一个加法,再上面的变换完成之后,相加即可。

现在让它再变化一下,假设输入的是 r 个样本,再来考虑如何这其中的过程。重点还是一致性,观察它的乘法过程 X(r,n)×W(n,m)=XW(r,m)X (r ,n ) \times W (n,m) = XW(r,m)X(r,nW(n,m)=XW(r,m) ,可以发现其实矩阵乘法根本不在乎你的数量,你给几个它输出几个。这是好消息,它意味着这里和前面的过程是一致的,也意味着不用线性层的处理过程是一致的。

稍微麻烦点的是 b 的运算,它需要理解一下,尽管对于这一个层而言,计算得到了一个形状为r×mr\times mr×m的矩阵,但是正常来讲,b 的形状则是 1×m1\times m1×m,这里会牵扯到一个广播运算(好消息是所有的数值运算都默认支持这个操作),具体的操作是对于每一行都和 b 做加法。相当于是 b 在运算过程中是一个 r×mr\times mr×m的矩阵。

每行为样本特征的运算过程我们已经理清了。然而有时候会有一些不按套路出牌的家伙,它们会使用列向量的方式组织数据,这意味着先前的输入会是这样 X(n,r)X(n,r)X(n,r)

做法仍然是考虑一致性,该层交给下一层的输入应该是 M(m,r)M(m,r)M(m,r) 。所以中间应该是 W(m,n)W (m,n)W(m,n)。运算仍然是矩阵乘法,不过需要交换下顺序 变成 W(m,n)×X(n,r)=WX(m,r)W(m,n) \times X (n,r) = WX(m,r)W(m,nX(n,r)=WX(m,r) ,特征被映射了。

还有一点需要考虑的是偏置 b,如果想权值矩阵一样,考虑以每行储存一个神经元的偏置,则可以直接使用矩阵乘法。而如果使用行储存 m 个偏置,则计算时需要先转置再契合广播运算。

我们使用 numpy 来实现一下:

def linear(features: Tensor, weight: Tensor, b: Tensor, style='row'):     if style == 'row':         return features @ weight + b     elif style.startswith('col'):         return weight @ features + b     else:         raise ValueError("没有这种样式") 复制代码

上面考虑的是正向的运算,而另外要考虑的是反向的运算,也就是反向传播中,具体的矩阵运算。

同样是出于一致性考虑,对于一个线性层,它的输入特征 n 个,输出 m 个。现在给他 r 个具有 n 个特征的输入 r×nr\times nr×n ,那么他会将数据映射到 r×mr \times mr×m。假设反向传播时交给这一层的也是一个 r×mr \times mr×m的形状,那么考虑这一层需要传播的梯度的形状也应该是 r×nr \times nr×n

而这一层的权值矩阵的形状是 n×mn\times mn×m 。这里的乘法方式显而易见了。

向下层传播梯度的矩阵运算

P(r,m)×WT(m,n)=PWT(r,n)P(r,m) \times W^T (m,n) = PW^T(r,n)P(r,mWT(m,n)=PWT(r,n)

而对于权值的更新,它会依赖输入 X(r,n)X(r,n)X(r,n) ,无论是考虑应该与 r 无关还是考虑以应该和 W 形状一致,都会得到相同的想法。

W(n,m)=W(n,m)−XT(r,n)×P(r,m)W(n,m) = W(n,m) - X^T(r,n) \times P(r,m)W(n,m)=W(n,m)−XT(r,nP(r,m)

还有一部分需要考虑的则是 b ,对它而言,在刚才的假设中他应该是1×m1 \times m1×m 的,而交给它的是 r×mr \times mr×m的,这意味着必须降维(可以这样理解:正向是通过广播实现的,反向也需要一种方式让它可以运算)。具体做法可以是通过求和之类的聚合操作实现降维。

这里就不再使用代码是实现了。

总而言之,神经网络中对于每一个层都可以单独考虑,重点在于保持一致性,而这往往会更容易让人理解。


作者:纯人工模式混淆
链接:https://juejin.cn/post/7036018285422313508

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐