入门神经网络训练模型搭建

前言

今天试着搭建一个小的神经网络训练模型,通过训练会使预测值和真实值逐渐逼近。

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import torch

#一次输入数据的数量 即100组数据
batch_n = 100
#每组数据的数据特征数
input_data = 1000
#数据经过隐藏层后保留的数据特征的个数(只考虑一层隐藏层)
hidden_layer = 100
#每组输出数据的数据特征数
output_data = 10

#输入层和输出层
x = torch.randn(batch_n, input_data)
y = torch.randn(batch_n, output_data)

#输入层到隐藏层的权重参数和隐藏层到输出层的权重参数
w1 = torch.randn(input_data, hidden_layer)
w2 = torch.randn(hidden_layer, output_data)

#训练次数
epoch_n = 20
#学习速率
learning_rate = 1e-6

for epoch in range(epoch_n):
h1 = x.mm(w1)
h1 = h1.clamp(min=0)
y_pred = h1.mm(w2)

loss = (y_pred - y).pow(2).sum()
print("Epoch:{}, Loss:{:.4f}".format(epoch, loss))

grad_y_pred = 2 * (y_pred - y)
grad_w2 = h1.t().mm(grad_y_pred)

grad_h = grad_y_pred.clone()
grad_h = grad_h.mm(w2.t())
grad_h.clamp_(min=0)
grad_w1 = x.t().mm(grad_h)

w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2

测试结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Epoch:0, Loss:58291408.0000
Epoch:1, Loss:159056992.0000
Epoch:2, Loss:521834688.0000
Epoch:3, Loss:522471264.0000
Epoch:4, Loss:4316087.5000
Epoch:5, Loss:3243381.0000
Epoch:6, Loss:2620373.0000
Epoch:7, Loss:2226943.0000
Epoch:8, Loss:1957315.6250
Epoch:9, Loss:1758743.6250
Epoch:10, Loss:1603234.8750
Epoch:11, Loss:1475709.2500
Epoch:12, Loss:1367604.5000
Epoch:13, Loss:1273678.0000
Epoch:14, Loss:1190754.3750
Epoch:15, Loss:1116698.3750
Epoch:16, Loss:1049910.6250
Epoch:17, Loss:989398.0625
Epoch:18, Loss:934201.0625
Epoch:19, Loss:883768.8750

一、前向传播

26-28行其实就是用输入层进入隐藏层再进入输出层的整个过程了,通过mm函数(注意不是mul函数)实现了数据特征从1000到100到10的变化,在计算过程中还对矩阵的乘积使用clamp函数进行裁剪,将小于0的数赋值为0(clamp函数本来有3个参数,分别是需要进行裁剪的Tensor变量,裁剪的上边界和下边界,在这里需要裁剪的变量是其本身,只定义下边界不定义上边界是为了实现ReLU激活函数的功能,但并不完全等于ReLU激活函数)
30-31行计算损失函数并打印,这里使用的是均方误差的计算方法,给个图:

求出来是真实值和预测值的差值的平方和。

二、后向传播

后向传播主要是为了对权重值w进行优化。
33-39行grad_w1和grad_w2是更新的权重梯度值。(梯度就是多元函数的偏导数以向量形式表示)
41-42行在得到参数的梯度值之后,按照设置好的学习速率对权重值进行更新。