源自B站 刘二大人 ,传送门PyTorch 深度学习实践 梯度下降法
一、实现流程
1.准备数据集(Prepare dataset)
2.设计模型(Design model)
3.构建损失函数和优化函数(Construct loss and optimizer)
4.训练模型(Training cycle)
二、Prepare dataset
在Pytorch中,计算图采用 mini-batch 的方式,所以输出和输出均为3x1的Tensors。
代码实现:
import torch
#数据作为矩阵参与Tensor计算
x_data = torch.Tensor([1.0],[2.0],[3.0])
y_data = torch.Tensor([2.0],[4.0],[6.0])
三、Design model
在如下的计算图中,Linear Unit 为线性单元,在线性单元中完成 y = kx +b 的线性计算,其中输入和输出的维度固定,w 和 b 会根据输入和输出的维度自动生成。
代码实现:
#固定继承于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()
线性计算模型继承与Module,其中参数初始化使用到了torch.nn.Linear()函数,该函数的原型就是进行y = kx +b 的线性计算,同时该函数可以针对维度如(2 x 2 x 3)这种多维度输入。函数会根据输入和输出的维度自动调整 w 和 b 的形状。
torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
1.in_features:输入的最后一维度大小,如(2 x 2 x 3)就是3
2.out_features:输出的最后一维度大小,设为4时,(2 x 2 x 3)会变为(2 x 2 x 4)
3.bias:是否使用偏差,即上述公式是否 +b
四、Construct loss and Optimizer
1.Loss计算
criterion = torch.nn.MSELoss(size_average=False,reduce=Ture)
MSE:Mean Squared Error(均方误差),是预测值与真实值之差的平方和的平均值,即
size_average:选择是否计算均值,计算均值对损失值影响不大,一般不进行计算,在缺少样本时可以进行计算。
reduce:选择是否将损失值降为标量。
2.Optimizer计算
优化器并不构建计算图,生成的优化器对象可以直接对整个模型进行优化。
torch.optim是一个实现了各种优化算法的库。大部分常用的方法得到支持,并且接口具备足够的通用性,使得未来能够集成更加复杂的方法。SGD是optim中的一个优化器算法:随机梯度下降算法。
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
model.parameters:能够检查模型中所有能够优化的张量,对其梯度进行计算
lr:表示学习率
四、Training cycle
1.计算预测值
2.计算损失值
3.进行反馈计算
4.参数更新
代码实现:
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)