知识点
步骤:
1.构建数据集
2.设计模型 nn.Moudle 计算y_hat
3.计算损失函数 和优化器 (pytorch的函数)
4.训练周期 (前馈-反馈-更新)
转成矩阵形式:
不用人工求导数,重点是构造计算图,pytorch会自动计算梯度。
需要知道 x、y_hat的维度,可以求w、b的维度 本例为一元模型,
模型
损失函数 MSE
优化器 SGD
可调用对象
class Foobar:
def __init__(self):
pass
def __call__(self,*args,**kwargs):
pass
def func(*args,**kwargs):
print(args)
print(kwargs)
#调用一下
func(1,2,3,4,x=3,y=5)
结果:
(1,2,3,4)
{‘x’:3,‘y’:5}
代码
import torch
# Tip1:数据集 x,y是矩阵,3行1列 也就是说总共有3个数据,每个数据只有1个特征
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
# Tip2:构造模型 (模板)
class LinearModel(torch.nn.Module):
def __init__(self): # 构造函数
super(LinearModel, self).__init__() # super是父类 initial
self.linear = torch.nn.Linear(1, 1, bias=True) # nn.Linear构造对象,包含权重w和偏置b
def forward(self, x): # 进行实现,前馈过程中进行的计算
y_pred = self.linear(x) # 可调用的对象
return y_pred
model = LinearModel()
# Tip3:损失函数、优化器
# criterion = torch.nn.MSELoss(size_average=False)
criterion = torch.nn.MSELoss(reduction='sum') # 损失函数 MSE,size_average求均值
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 优化器,model.parameters()指的是权重, lr为学习率
# Tip4:训练过程
for epoch in range(100):
y_pred = model(x_data) # 前馈
loss = criterion(y_pred, y_data) # 损失
print(epoch, loss)
optimizer.zero_grad() # 梯度归零
loss.backward() # 反向传播
optimizer.step() # 梯度更新
print('w = ', model.linear.weight.item()) # 输出权重、偏置
print('b = ', model.linear.bias.item())
# Tip5:测试
x_test = torch.tensor([[4.0]]) # 1*1的矩阵
y_test = model(x_test)
print('y_pred = ', y_test.data)
作业(使用不同优化器进行比较)
结果图:
import torch
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
class LinearModel(torch.nn.Module):
def __init__(self): # 构造函数
super(LinearModel, self).__init__() # super是父类 initial
self.linear = torch.nn.Linear(1, 1, bias=True) # nn.Linear构造对象,包含权重w和偏置b
def forward(self, x): # 进行实现,前馈过程中进行的计算
y_pred = self.linear(x) # 可调用的对象
return y_pred
model_SGD = LinearModel()
model_Rprop = LinearModel()
model_Adagrad = LinearModel()
model_RMSprop = LinearModel()
model_Adam = LinearModel()
criterion = torch.nn.MSELoss(reduction='sum') # 损失函数 MSE,size_average求均值
optimizer_SGD = torch.optim.SGD(model_SGD.parameters(), lr=0.01) # 优化器,model.parameters()指的是权重, lr为学习率
optimizer_Rprop = torch.optim.Rprop(model_Rprop.parameters(), lr=0.01)
optimizer_Adagrad = torch.optim.Adagrad(model_Adagrad.parameters(), lr=0.01)
optimizer_RMSprop = torch.optim.RMSprop(model_RMSprop.parameters(), lr=0.01)
optimizer_Adam = torch.optim.Adam(model_Adam.parameters(), lr=0.01)
epoch_list = []
# SGD
loss_SGD_list = []
for epoch in range(100):
y_pred = model_SGD(x_data) # 前馈
loss_SGD = criterion(y_pred, y_data) # 损失
optimizer_SGD.zero_grad() # 梯度归零
loss_SGD.backward() # 反向传播
optimizer_SGD.step() # 梯度更新
epoch_list.append(epoch)
loss_SGD_list.append(loss_SGD.data)
# Rprop
loss_Rprop_list = []
for epoch in range(100):
y_pred = model_Rprop(x_data) # 前馈
loss = criterion(y_pred, y_data) # 损失
optimizer_Rprop.zero_grad() # 梯度归零
loss.backward() # 反向传播
optimizer_Rprop.step() # 梯度更新
loss_Rprop_list.append(loss.data)
# Adagrad
loss_Adagrad_list = []
for epoch in range(100):
y_pred = model_Adagrad(x_data) # 前馈
loss_Adagrad = criterion(y_pred, y_data) # 损失
optimizer_Adagrad.zero_grad() # 梯度归零
loss_Adagrad.backward() # 反向传播
optimizer_Adagrad.step() # 梯度更新
loss_Adagrad_list.append(loss_Adagrad.data)
# RMSprop
loss_RMSprop_list = []
for epoch in range(100):
y_pred = model_RMSprop(x_data) # 前馈
loss_RMSprop = criterion(y_pred, y_data) # 损失
optimizer_RMSprop.zero_grad() # 梯度归零
loss_RMSprop.backward() # 反向传播
optimizer_RMSprop.step() # 梯度更新
loss_RMSprop_list.append(loss_RMSprop.data)
# Adam
loss_Adam_list = []
for epoch in range(100):
y_pred = model_Adam(x_data) # 前馈
loss_Adam = criterion(y_pred, y_data) # 损失
optimizer_Adam.zero_grad() # 梯度归零
loss_Adam.backward() # 反向传播
optimizer_Adam.step() # 梯度更新
loss_Adam_list.append(loss_Adam.data)
plt.plot(epoch_list, loss_SGD_list)
plt.plot(epoch_list, loss_Rprop_list)
plt.plot(epoch_list, loss_Adagrad_list)
plt.plot(epoch_list, loss_RMSprop_list)
plt.plot(epoch_list, loss_Adam_list)
plt.ylabel('Loss') # 纵坐标
plt.xlabel('Epoch') # 横坐标
plt.title('不同优化器的Loss比较')
plt.legend(['SGD', 'Rprop', 'Adagrad', 'RMSprop', 'Adam'], loc='upper right') # 图例
plt.show()