- 博主主页:@璞玉牧之
- 本文所在专栏:《PyTorch深度学习》
- 博主简介:22级大数据专业大学生,科研方向:深度学习,持续创作中
在图上进行梯度的传播,建立更具有弹性的模型结构
面对复杂网络时,把网络看成一个图,在图上传播梯度,最后根据链式法则求出梯度,这种算法叫反向传播算法。
H = 权重矩阵 * 输入的x,其中x是5行1列矩阵(x属于5维矩阵),H是6行1列矩阵,所以权重矩阵是6行5列矩阵,因此有30个不同权重。
以两层神经网络为例
设输入矩阵x的维度为n,隐层维度为m,则权重维度为m * n
经矩阵乘法H(1)=W1X,可得到中间隐层的输出。
所有绿色模块为计算模块,不同的计算模块求局部偏导的计算方法不同
矩阵计算公式可参考matrix cookbook
http://faculty.bicmr.pku.edu.cn/~wenzw/bigdata/matrix-cook-book.pdf
为了提高模型复杂度,不能像上图一样将模型化简,否则增加的权重就没有意义了,所以要对每一层最终的输出加一个非线性的变化函数,对张量里的每一个值都应用一个非线性函数。
当加了非线性函数做变换后,式子就没办法展开了,才能做成真正的神经网络。
PyTorch实现线性模型
import torch
x_data = [1.0, 2.0, 3.0, 4.0]
y_data = [2.0, 4.0, 6.0, 8.0]
w = torch.Tensor([1.0])
w.requires_grad = True # 需要计算梯度
def forward(x):
return x * w # 其中w是Tensor
def loss(x, y): # 构建计算图
y_pred = forward(x)
return (y_pred - y) ** 2
print("predict (before training)", 4, forward(4).item())
for epoch in range(100): # 训练100轮
for x, y in zip(x_data, y_data): # 将x_data,y_data zip成数据
l = loss(x, y) # 前馈,计算loss
l.backward() # 反馈,并会释放计算图。每进行一次反向传播就会释放计算图,并准备下一次的图
print('\tgrad:', x, y, w.grad.item()) # 取w的data不会建立计算图
w.data -= w.data - 0.01 * w.grad.data # 张量的计算会构建计算图
w.grad.data.zero_() # 把权重里面梯度的数据全都清零
print("progress:", epoch, l.item())
print("predict (after training)", 4, forward(4).item())
import torch
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w1 = torch.Tensor([1.0]) # 初始权值
w1.requires_grad = True # 计算梯度,默认是不计算的
w2 = torch.Tensor([1.0])
w2.requires_grad = True
b = torch.Tensor([1.0])
b.requires_grad = True
def forward(x):
return w1 * x ** 2 + w2 * x + b
def loss(x, y): # 构建计算图
y_pred = forward(x)
return (y_pred - y) ** 2
print('Predict (before training)', 4, forward(4))
for epoch in range(100):
l = loss(1, 2) # 为了在for循环之前定义l,以便之后的输出,无实际意义
for x, y in zip(x_data, y_data):
l = loss(x, y)
l.backward()
print('\tgrad:', x, y, w1.grad.item(), w2.grad.item(), b.grad.item())
w1.data = w1.data - 0.01 * w1.grad.data # 注意这里的grad是一个tensor,所以要取他的data
w2.data = w2.data - 0.01 * w2.grad.data
b.data = b.data - 0.01 * b.grad.data
w1.grad.data.zero_() # 释放之前计算的梯度
w2.grad.data.zero_()
b.grad.data.zero_()
print('Epoch:', epoch, l.item())
print('Predict (after training)', 4, forward(4).item())
我是璞玉牧之,持续输出优质文章,希望和你一起学习进步!!!原创不易,如果本文对你有帮助,可以 点赞+收藏+评论 支持一下哦!我们下期见~~