05Linear Regression with PyTorch

本节使用Pytorch中的linear做回归

使用pytorch做深度学习分析,一般有如下范式
Alt

  • 1,准备数据集,数据集有很多种类型,图像数据集、表格数据集等。
  • 2,设计自己的模型,继承Pytorch的nn.module类。
  • 3,构建损失函数和优化器,调用pytorch现成的接口。
  • 4,循环训练,前向传播–>反向传播–>更新权重。

1,准备数据集

pytorch中的数据集一般是mini-batch风格,也就是(N,data.dim),对于本节的任务。有三个样本,一次batch就是3个样本,构建成矩阵。

import torch
 
#构建数据集
 
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
 
y_data = torch.Tensor([[2.0], [4.0], [6.0]])

2,构建模型

本小结使用的模型为只包含一个神经元的线性层
Alt

#模型类继承于nn.Module
class LinearModel(torch.nn.Module):
 
    def __init__(self):#构造函数,初始化对象时默认调用的函数
        #重写了__init__,要继承父类的构造
    	super(LinearModel, self).__init__()  #调用父类的构造,继承父类的资源
        
     	#nn.Linear类包含两个成员张量:weight和bias
      	#Linear类也是继承自Module,可以自动进行反向传播
    	self.linear = torch.nn.Linear(1, 1)  #类后面加括号-构造对象
 
    def forward(self, x):
 
    	y_pred = self.linear(x)#对象后面加括号-实现了一个__call__(),可调用的对象
    	return y_pred
 
#创建一个LinearModel实例    
model = LinearModel()   #注意这个model是可调用的,callable

3,构建损失函数和优化器

criterion = torch.nn.MSELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)  #SGD类的实例化

损失函数用的是平均平方损失
Alt
创建损失函数有三个参数,但前两个pytorch并不建议使用
Alt
实际上前两个参数的修改都可以通过第三个参数的修改到达目的,下面有个小实验

import torch

criterion = torch.nn.MSELoss(reduction='sum')

# 一个批次是3个样本
input = torch.arange(3,dtype=torch.float32).reshape(-1,1)
target = torch.arange(3,6,dtype=torch.float32).reshape(-1,1)
loss = criterion(input,target)
loss

实验结果

  • 把size_average=False设置成FALSE就是不对每个batch求平均,损失函数编程平方损失,而不是平均平方损失。
    Alt
    优化器采用的是随机梯度下降,实际上应该叫小批量随机梯度下降
  • pytorch实际上预设有13种优化方法,本小结的作业,需要对比采用不同的优化器,损失迭代的曲线有何不同,有些优化器使用方法略有不同。如下图所示:
    Alt

4,循环训练

for epoch in range(100):
 
    y_pred = model(x_data)#forward:预测
    loss = criterion(y_pred, y_data)#forward:loss
    print(epoch, loss)  #打印loss时会自动调用__str__()函数,不会产生计算图,这是安全的
    
    optimizer.zero_grad()#注意.backward()时梯度会被累计,注意所有的权重设为0
    loss.backward()#反向传播:autograd
    optimizer.step()#update,根据梯度和设好的学习率进行更新

完整代码

Alt

import torch
 
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__()
    	self.linear = torch.nn.Linear(1, 1)
     
    def forward(self, x):
 
    	y_pred = self.linear(x)
    	return y_pred
 
model = LinearModel()
 
criterion = torch.nn.MSELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
 
for epoch in range(1000):
 
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    print("epoch:",epoch,"loss:",loss.item())
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
print("**************test***************")
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
 
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
 
print('when x = 4, y_pred = ',y_test.data)

作业

  • 同时设置不同的优化器,我使用的是列表。先把方法存到列表中。
import numpy as np
import torch
import matplotlib.pyplot as plt


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__()
		self.linear = torch.nn.Linear(1, 1)

	def forward(self, x):
		y_pred = self.linear(x)
		return y_pred

model = LinearModel()
# 线性层实际接受的是向量,但是注意,我们输入的是mini-batch,所以输入到线性层就是矩阵。那么输出也是batch的矩阵。
criterion = torch.nn.MSELoss()
# optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 作业要求:对比不同优化器的损失曲线
optimizer_list = ['Adagrad','Adam','Adamax','ASGD',
				  'RMSprop','Rprop','SGD']

l1 = [] # 总的优化器损失列表
for opt in range(len(optimizer_list)):
	optimizer = 'torch.optim.' + optimizer_list[opt]

	optimizer = eval(optimizer)(model.parameters(), lr=0.01) # eval消除引号

	l2 = [] # 当前被选中的优化器损失列表
	for epoch in range(50):

		y_pred = model(x_data)
		loss = criterion(y_pred, y_data)
		# 记录损失
		l2.append(loss.item())

		optimizer.zero_grad() # 消除上一步梯度信息

		loss.backward() # 反向传播,更新梯度

		optimizer.step() # 更新参数

	l1.append(l2)

l1 = np.array(l1) # 转成numpy格式方便作图

# 作图
marker = ['s','p','*','+','x','d','2']
plt.rc('legend', fontsize=14)
fig = plt.figure(figsize=(10,5.5),dpi=100)
for i in range(len(optimizer_list)):
	plt.plot(l1[i],marker=marker[i],label=optimizer_list[i])
plt.xlabel('epoch',fontsize=14)
plt.ylabel('loss',fontsize=14)
plt.legend()
plt.show()

Alt
这里对比7种算法
Alt
再把学习率调成0.001,和老师的0.01不同。如下图为0.001
Alt
再把学习率调成0.01
Alt

作业实验结果与讨论

  • 学习率有时候会显著影响训练情况。
  • 不同的优化器产生的训练效果不同,但这不是说明哪个优化器更好,仅仅说明在当前任务下哪些优化器更好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值