> 文档中心 > Python深度学习基础(三)——全连接层以及反向传递的理解与手动实现

Python深度学习基础(三)——全连接层以及反向传递的理解与手动实现

全连接层以及反向传递的理解与手动实现

  • 全连接层简介
  • 实现原理
    • 正向传递
    • 反向传递
  • 代码实现

全连接层简介

全连接层又被称为密连接层,通常可以用Affine或Dense表示

实现原理

正向传递

全连接层在正向传递时和感知机完全一致,都是直接将输入值乘以权值在加上偏置即可,这里尤为注意的是我们使用的是矩阵。公式非常简单
y = x ⋅ w + b y=x \cdot w + b y=xw+b

反向传递

对于正向传递的表达式,我们可以将整个正向传递过程看成两步
y 1 = x ⋅ w ; y = y 1 + b y1=x \cdot w; \\ y=y1+b y1=xw;y=y1+b
这样我们就将问题转换成了乘法层和加法层的堆叠

∂ y∂ y 1 = 1 \frac{ \partial y}{\partial y1}=1 y1y=1
∂ y∂ b = 1 \frac{ \partial y}{\partial b}=1 by=1
∂ y∂ y 1 ∂ y 1∂ x = w \frac{ \partial y}{\partial y1}\frac{ \partial y1}{\partial x}=w y1yxy1=w
∂ y∂ y 1 ∂ y 1∂ w = x \frac{ \partial y}{\partial y1}\frac{ \partial y1}{\partial w}=x y1ywy1=x
∂ y∂ b = 1 \frac{ \partial y}{\partial b}=1 by=1
根据链式法则每个偏导都应该乘以下一层传来的偏导数值,本文代码用dout表示,故
∂ L∂ y ∂ y∂ y 1 ∂ y 1∂ x = ∂ L∂ y ⋅ w \frac{ \partial L}{\partial y}\frac{ \partial y}{\partial y1}\frac{ \partial y1}{\partial x}=\frac{ \partial L}{\partial y} \cdot w yLy1yxy1=yLw
∂ L∂ y ∂ y∂ y 1 ∂ y 1∂ w = ∂ L∂ y ⋅ x \frac{ \partial L}{\partial y}\frac{ \partial y}{\partial y1}\frac{ \partial y1}{\partial w}=\frac{ \partial L}{\partial y} \cdot x yLy1ywy1=yLx
∂ L∂ y ∂ y∂ b = ∂ L∂ y ⋅ 1 \frac{ \partial L}{\partial y}\frac{ \partial y}{\partial b}=\frac{ \partial L}{\partial y} \cdot 1 yLby=yL1

代码实现

class Affine:    def __init__(self, W, b): self.W =W self.b = b  self.x = None self.original_x_shape = None # 权重和偏置参数的导数 self.dW = None self.db = None    def forward(self, x): # 对应张量 self.original_x_shape = x.shape x = x.reshape(x.shape[0], -1) self.x = x out = np.dot(self.x, self.W) + self.b return out    def backward(self, dout): dx = np.dot(dout, self.W.T) self.dW = np.dot(self.x.T, dout) self.db = np.sum(dout, axis=0)  dx = dx.reshape(self.original_x_shape)  # 还原输入数据的形状(对应张量) return dx