1.torch.optim
在机器学习或者深度学习中,我们需要通过修改参数使得损失的数最小化(或最大化),优化算法就是一种调整模型参数更新的策略。
1.1一阶优化算法
使用参数的梯度值来更新参数,最常用的是梯度下降。梯度是导数的多变量表达式,函数的梯度形成了向量场,同时也是一个方向,这个方向导数最大,等于梯度。
梯度下降的功能是寻找最小值,控制方差,更新模型参数最终使模型收敛,网络的参数更新公式是:
1.2.二阶优化算法
二阶优化算法使用了二阶导数(Hessian)最小化或最大化损失函数。计算成本高
我们可以直接调用Pytorch自带的实现优化算法的包,大多数常见的算法都可以调用包来实现,比如随机梯度下降,添加动量的随机梯度下降,自适应学习率等。
在调用的时候将需要优化的参数传入,这些参数都必须是variable,然后传入一些基本的设定,比如学习率和动量。
例子:
2.线性模型实例
从最简单的线性模型入手,给多个数据点,找到一个函数来拟合这些数据点使其误差最小
一维线性回归代码实现:
开发时间:2020/9/22 15:28
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.autograd import Variable
#建立模型
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression,self).__init__()
self.linear = nn.Linear(1,1) #输入输出维数(in_channels,out_channels,kernel_size)
def forward(self,x):
out = self.linear(x)
return out
#测试数据
x_train = np.array([[3.4],[5.4],[6.71],[6.89],[6.93],[4.16],[9.779],[6.182],[7.59]
,[2.167],[7.042],[10.791],[5.31],[7.997],[3.1]],dtype = np.float32)
y_train = np.array([[1.7],[2.76],[2.09],[3.19],[1.694],[1.573],[3.366],[2.596],[2.53],
[1.221],[2.87],[3.45],[1.6],[2.9],[1.3]],dtype = np.float32)
#我们想要做的是找一条直线去逼近这些点,希望这条直线离这些点的距离之和最小
x_train = torch.from_numpy(x_train)
y_train = torch.from_numpy(y_train)
plt.plot(x_train,y_train,'ro')
plt.show()
#这里有个问题,就是模型和数据,要都分别放入GPU吗
if torch.cuda.is_available():
model = LinearRegression().cuda()#把这个模型换个名字
inputs = Variable(x_train).cuda()#定义输入
target = Variable(y_train).cuda()#定义目标
else:
model = LinearRegression()
inputs = Variable(x_train)
target = Variable(y_train)
criterion = nn.MSELoss() #损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
num_epochs = 100000
for epoch in range(num_epochs):
#forward
out = model(inputs) #得到前向传播的结果
loss = criterion(out,target) #求得输出和真实目标之间的损失函数
#backward
optimizer.zero_grad() #归零梯度,每次反向传播前都要归零梯度,不然梯度会累积,造成结果不收敛
loss.backward() #反向传播
optimizer.step() #更新参数
if (epoch + 1) % 200 == 0:
print('Epoch[{}/{}],loss:{:.6f}'.format(epoch + 1, num_epochs, loss.item()))
#这里的loss.item(),没有按照书上写的
#这句话目的:在训练过程中过一段时间就将损失函数的值打印出来看看,保证模型误差越来越小
#训练完毕后预测下结果
model.eval() #将模型变成测试模式,是因为有层操作,在训练和测试的时候是不一样的
predict = model(Variable(x_train.cuda()))
predict = predict.data.cpu().numpy()
#如果要把CUDA tensor的数据改成numpy,需要将其转换成 cpu float-tensor 然后再转numpy格式
#numpy不能读取CUDAtensor
plt.plot(x_train.numpy(),y_train.numpy(),'ro',label = 'Original data')
plt.plot(x_train.numpy(),predict,label = 'Fitting Line')
plt.show()
概述下整体流程:
①建立模型
②建立数据集
③由于矩阵是numpy,要转化成tensor
④如果有GPU,可以放入GPU跑,分别放入模型,输入,目标。
⑤定义损失函数和优化器
⑥训练模型:
1)前向传播
(给模型输入参数)
(求损失函数)
2)反向传播
(梯度归零)
(loss.backward)
(更新参数)
(每隔几段时间就打印损失函数看看)
⑦验证看看效果