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

你可能感兴趣的:(深度学习方法,深度学习)