很多人可以使用框架,快速搭建神经网络,但对神经网络的实现及反向传播一直是一知半解。本文用Numpy,通过一个隐层连接一个ReLU,再使用L2 Loss,反向传播,原生实现一个两层的线性神经网络,帮大家更好的理解神经网络的结构。
公式
为了计算方便,使用不带截距的线性模型。
h = x @ w1
h_relu = max(h, 0)
y_hat = h_relu @ w2
代码示例
import numpy as np # N 为 batch size; D_in 为输入数据维度(特征数) # H 为隐层维度; D_out 为输出数据维度. N, D_in, H, D_out = 64, 100, 1000, 1 # 定义输入和输出数据 x = np.random.randn(N, D_in) y = np.random.randn(N, D_out) # 随机生成初始权重参数 w1 = np.random.randn(D_in, H) w2 = np.random.randn(H, D_out) learning_rate = 1e-6 for i in range(500): # 前向传播计算预测值 h = x @ w1 h_relu = np.maximum(h, 0) y_hat = h_relu @ w2 # 计算平方差损失 loss = np.square(y_hat - y).sum() print(i, loss) # 链式法则计算梯度 grad_y_hat = 2 * (y_hat - y) grad_w2 = h_relu.T @ grad_y_hat # 注意顺序,可以用shape逆推 grad_h_relu = grad_y_hat @ w2.T grad_h = grad_h_relu.copy() grad_h[h < 0] = 0 # 布尔索引修正梯度值 grad_w1 = x.T @ grad_h # 梯度下降 w1 -= grad_w1 * learning_rate w2 -= grad_w2 * learning_rate
本文为 陈华 原创,欢迎转载,但请注明出处:http://ichenhua.cn/read/307