1.torch.optim

在机器学习或者深度学习中,我们需要通过修改参数使得损失的数最小化(或最大化),优化算法就是一种调整模型参数更新策略

1.1一阶优化算法

使用参数的梯度值来更新参数,最常用的是梯度下降。梯度是导数的多变量表达式,函数的梯度形成了向量场,同时也是一个方向,这个方向导数最大,等于梯度。

梯度下降的功能是寻找最小值,控制方差,更新模型参数最终使模型收敛,网络的参数更新公式是:

pytorch内存优化 pytorch 优化函数_优化算法


pytorch内存优化 pytorch 优化函数_pytorch内存优化_02


1.2.二阶优化算法

二阶优化算法使用了二阶导数(Hessian)最小化或最大化损失函数。计算成本高

我们可以直接调用Pytorch自带的实现优化算法的包,大多数常见的算法都可以调用包来实现,比如随机梯度下降添加动量的随机梯度下降自适应学习率等。

在调用的时候将需要优化的参数传入,这些参数都必须是variable,然后传入一些基本的设定,比如学习率动量

例子:

pytorch内存优化 pytorch 优化函数_pytorch内存优化_03


2.线性模型实例

从最简单的线性模型入手,给多个数据点,找到一个函数来拟合这些数据点使其误差最小

pytorch内存优化 pytorch 优化函数_python_04


一维线性回归代码实现:

开发时间: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)
(更新参数)
(每隔几段时间就打印损失函数看看)
⑦验证看看效果