Softmax层 输出&梯度推导及Python实现

Softmax层 输出&梯度推导及Python实现

详细代码在这里,存在于Layer.py中的Softmax类里面

推导

太长不看 下面有结论及代码
在这里插入图片描述

结论

约定:Input = I 输入,Output = O 输出

  • Softmax层的前向传播非常简单,就是输入向量的每个分量取指数,再除以所有分量的指数和即可

  • 反向传播需要计算输出向量对输入向量的导数,输出向量i分量(Oi)对输入向量的分量j(Ij)的导数分为两种情况:

    1. i=j 时,其值等于 Oi * (1 - Oi)
    2. i≠j 时,其值等于 -1 * Oi * Ij
  • 整个输出向量O,欲求O对于 Ii 的导数,必须依次计算 O1,O2, O3 …On 对 Ii的导数,再将他们加和,作为 O 对 Ii 的导数

代码

# Forward propagation
# param x : last layer's output
# 前向传播
# x 是当前层的输入
def FP(self, x):
    self.input = x.copy()
    self.expi = np.exp(self.input)
    self.sum = np.sum(self.expi)
    self.output = self.expi / self.sum
    self.next_layer.FP(x=self.output)

# Back propagation
# param gradient : last layer's gradient
# param lr       : learning rate
# 反向传播,gradient是当前层输出对损失函数的梯度, lr是学习率
def BP(self, gradient, lr):
    self.gradient = gradient.copy()
    self.tp = self.expi/self.sum
    self.last_layer_gradient = np.zeros(shape=self.input_shape, dtype=np.float64)

    for i in range(self.input_shape[0]):
        # gradient for Input[i]
        # 输入向量 Input 的第 i 个位置的梯度
        self.gradient_for_Ii = np.zeros(shape=self.input_shape, dtype=np.float64)

        for j in range(self.input_shape[0]):
            if i == j:
                self.gradient_for_Ii[j] = self.output[i]*(1 - self.output[i])
            else:
                self.gradient_for_Ii[j] = -1 * self.output[i] * self.output[j]

        self.last_layer_gradient[i] = np.sum(self.gradient_for_Ii * self.gradient)

    self.last_layer.BP(gradient=self.last_layer_gradient, lr=lr)
发布了49 篇原创文章 · 获赞 1 · 访问量 710

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104076598
今日推荐