文章目录
- 前提的python的知识补充
- 基本流程
- 准备数据
- 构造计算图
- loss以及oprimizer
- 循环训练
- 课程代码
课程来源: 链接
课程内容参考: 链接
以及(强烈推荐)Birandaの
前提的python的知识补充
pytorch 之 call, init,forward
pytorch系列nn.Modlue中call的进一步解释
即可以了解调用mode实际上就是在调用其中的forward函数。
基本流程
- 准备数据集
- 设计用于计算最终结果的模型
- 构造损失函数及优化器
- 设计循环周期——前馈、反馈、更新
准备数据
在原先的题设中,
x
,
y
^
∈
R
x,\widehat y \in R
x,y
∈R
在pytorch中,若使用mini-batch的算法,一次性求出一个批量的
y
^
\widehat y
y
,则需要
x
x
x以及
y
^
\widehat y
y
作为矩阵参与计算,此时利用其广播机制,可以将原标量参数
ω
\omega
ω扩写为同维度的矩阵
[
w
]
[w]
[w],参与运算而不改变其Tensor的性质。
对于矩阵,行表示样本,列表示特征
代码部分:
import torch
#数据作为矩阵参与Tensor计算
x_data = torch.Tensor([1.0],[2.0],[3.0])
y_data = torch.Tensor([2.0],[4.0],[6.0])
构造计算图
在如下线性模型的计算图中,红框区域为线性单元,其中的
ω
\omega
ω以及
b
b
b是需要反复训练确定的,在设计时,需要率先设计出此二者的维度。
而由于公式
y
^
=
ω
x
+
b
\widehat y = \omega x +b
y
=ωx+b
因此,只要确定了$\widehat y
以及
以及
以及x$的维度,就可以确定上述两个量的维度大小。
代码部分:
# 固定继承于Module
class LinearModel(torch.nn.Module):
# 构造函数初始化
def __init__(self):
# 调用父类的init
super(LinearModel, self).__init__()
# Linear对象包括weight(w)以及bias(b)两个成员张量
self.linear = torch.nn.Linear(1,1)
#前馈函数forward,对父类函数中的overwrite
def forward(self, x):
#调用linear中的call(),以利用父类forward()计算wx+b
y_pred = self.linear(x)
return y_pred
#反馈函数backward由module自动根据计算图生成
model = LinearModel()
loss以及oprimizer
按照上述理论,由于前边的计算过程都是针对矩阵的,因此最后的
l
o
s
s
loss
loss也是矩阵,但由于要进行反向传播调整参数,因此
l
o
s
s
loss
loss应当是个标量,因此要对矩阵
[
l
o
s
s
]
[loss]
[loss]内的每个量求和求均值(MSE)。
l
o
s
s
=
1
N
Σ
[
l
o
s
s
1
⋮
l
o
s
s
n
]
loss = \frac{1}{N}\Sigma \begin{bmatrix} {loss_1}\\ {\vdots}\\ {loss_n}\\ \end{bmatrix}
loss=N1Σ
loss1⋮lossn
优化器并不构建计算图,生成的优化器对象可以直接对整个模型进行优化
代码:
criterion = torch.nn.MSELoss(size_average=False)
#model.parameters()用于检查模型中所能进行优化的张量
#learningrate(lr)表学习率,可以统一也可以不统一
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
关于model.parameters(),即将model当中所有权重参数传入到优化器当中,相当于进行更新。
循环训练
- 前馈计算预测值与损失函数
- forward前馈计算预测值即损失loss
- 梯度或前文清零并进行backward
- 更新参数
for epoch in range(100):
#前馈计算y_pred
y_pred = model(x_data)
#前馈计算损失loss
loss = criterion(y_pred,y_data)
#打印调用loss时,会自动调用内部__str__()函数,避免产生计算图
print(epoch,loss)
#梯度清零
optimizer.zero_grad()
#梯度反向传播,计算图清除
loss.backward()
#根据传播的梯度以及学习率更新参数
optimizer.step()
课程代码
import torch
#数据作为矩阵参与Tensor计算
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[2.0],[4.0],[6.0]])
#固定继承于Module
class LinearModel(torch.nn.Module):
#构造函数初始化
def __init__(self):
#调用父类的init
super(LinearModel, self).__init__()
#Linear对象包括weight(w)以及bias(b)两个成员张量
self.linear = torch.nn.Linear(1,1)
#前馈函数forward,对父类函数中的overwrite
def forward(self, x):
#调用linear中的call(),以利用父类forward()计算wx+b
y_pred = self.linear(x)
return y_pred
#反馈函数backward由module自动根据计算图生成
model = LinearModel()
#构造的criterion对象所接受的参数为(y',y)
criterion = torch.nn.MSELoss(size_average=False)
#model.parameters()用于检查模型中所能进行优化的张量
#learningrate(lr)表学习率,可以统一也可以不统一
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range(1000):
#前馈计算y_pred
y_pred = model(x_data)
#前馈计算损失loss
loss = criterion(y_pred,y_data)
#打印调用loss时,会自动调用内部__str__()函数,避免产生计算图
print(epoch,loss)
#梯度清零
optimizer.zero_grad()
#梯度反向传播,计算图清除
loss.backward()
#根据传播的梯度以及学习率更新参数
optimizer.step()
#Output
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
#TestModel
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ',y_test.data)