摆烂…先写这么多,有空来更新(指的是矩阵求导部分懒得写现在)
写在最前面
本打算围绕《Learning representations by back-propagating errors》一文进行解读的
奈何没有中文版的文档(笔者懒得翻译English)
所以文章内容只能根据笔者自身对BP反向传播算法的理解来编写咯~😅
在论文的标题里写了back-propagating errors,即反向传播误差
- 先通过前向传播计算得最终的输出结果
- 进而计算与正确值之间的误差
- 将误差反向传播,更新权重,得以实现“学习”的目的
- 至于…误差如何反向传播,权重如何更新,也是本文在探讨的
import random
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
定义激活函数、损失函数
这里只采用 ReLU、Sigmoid 作为神经网络的激活函数,MSE 作为损失函数
下面列了这仨的计算公式与导数的计算公式。除了定义计算方式,也定义了其求导公式,因为链式法则,懂吧?😁 就是为了方便后面的求导(也就是误差反向传播)
ReLU
R e L U = m a x ( 0 , x ) ReLU=max(0,x) ReLU=max(0,x)
d y d x = { 1 , x > 0 0 , x ≤ 0 \frac{\mathrm{d} y}{\mathrm{d} x} = \left\{\begin{matrix} 1 \quad ,x > 0\\ 0 \quad ,x \le 0 \end{matrix}\right. dxdy={ 1,x>00,x≤0
Sigmoid
S i g m o i d = 1 1 + e − x Sigmoid=\frac{1}{1+e^{-x}} Sigmoid=1+e−x1
d y d x = x ⋅ ( 1 − x ) \frac{\mathrm{d} y}{\mathrm{d} x} = x\cdot (1-x) dxdy=x⋅(1−x)
MSE
M S E = 1 n ∑ ( p r e d − t r u e ) 2 MSE=\frac{1}{n}\sum (pred-true)^{2} MSE=n1∑(pred−true)2
d y d x = p r e d − t r u e \frac{\mathrm{d} y}{\mathrm{d} x} = pred-true dxdy=pred−true
# ReLU 激活函数
class ReLU:
def __call__(self, x):
return np.maximum(0, x)
# 对 ReLU 求导
def diff(self, x):
x_temp = x.copy()
x_temp[x_temp > 0] = 1
return x_temp
# Sigmoid 激活函数
class Sigmoid:
def __call__(self, x):
return 1/(1+np.exp(-x))
# 对 Sigmoid 求导
def diff(self, x):
return x*(1-x)
# MSE 损失函数
class MSE:
def __call__(self, true, pred):
return np.mean(np.power(pred-true, 2), keepdims=True)
# 对 MSE 求导
def diff(self, true, pred):
return pred-true
relu = ReLU()
sigmoid = Sigmoid()
mse = MSE()
简单的 BP 反向传播
这里从最简单的开始,隐藏层只设置一个神经元,用sigmoid
作为激活函数
一切随缘🔀,对于x
、w
、b
、true
全都随机生成。而这一个神经元的任务就是不断的卷(学习),让输出结果无限接进true
整个神经网络的模型图如下,将就着看吧,笔者懒得弄图😅😅😅
|————————————输入层
| |————————隐藏层
| | |————输出层
〇——〇——〇
前向计算过程:x -> w·x+b -> sigmoid(w·x+b) -> mse(true, sigmoid(w·x+b))
反向计算过程:
{ d m s e ( t r u e , s i g m o i d ( w ⋅ x + b ) ) d w = d m s e ( t r u e , s i g m o i d ( w ⋅ x + b