API
调用API:和手动实现的思路是一样的。#1,#2这两个步骤是通用的步骤,相当于建立一个模型,之后你具体的数据直接丢进去就行了。只需要按着这样的样式打代码就行,死的东西,不需要你自己创造。
import torch
import torch.nn as nn
from torch.optim import SGD
#0 准备数据
x = torch.rand([500,1])
y_true = 3*x + 0.8
#1.定义模型
class MyLinear(nn.Module):
def __init__(self):
#继承父类的init
super(MyLinear,self).__init__()
self.linear = nn.Linear(1,1)
def forward(self,x):
out = self.linear(x)
return out
#2.实例化模型,优化器类实例化,loss实例化
my_linear = MyLinear()
optimizer = SGD(my_linear.parameters(),0.001)
loss_fn = nn.MSELoss()
#3.循环,进行梯度下降,参数的更新
for i in range(20000):
#得到预测值
y_predict = my_linear(x)
loss = loss_fn(y_predict,y_true)
#梯度置为0
optimizer.zero_grad()
#反向传播
loss.backward()
#参数更新
optimizer.step()
if i%50==0:
print(loss.item(),list(my_linear.parameters()))
可以看出已经很接近目标的数了
GPU版本
区别的地方:
1.
2.
3.
代码:
import torch
import torch.nn as nn
from torch.optim import SGD
#定义一个device对象
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#0 准备数据
x = torch.rand([500,1]).to(device)
y_true = 3*x + 0.8
#1.定义模型
class MyLinear(nn.Module):
def __init__(self):
#继承父类的init
super(MyLinear,self).__init__()
self.linear = nn.Linear(1,1)
def forward(self,x):
out = self.linear(x)
return out
#2.实例化模型,优化器类实例化,loss实例化
my_linear = MyLinear().to(device)
optimizer = SGD(my_linear.parameters(),0.001)
loss_fn = nn.MSELoss()
#3.循环,进行梯度下降,参数的更新
for i in range(20000):
#得到预测值
y_predict = my_linear(x)
loss = loss_fn(y_predict,y_true)
#梯度置为0
optimizer.zero_grad()
#反向传播
loss.backward()
#参数更新
optimizer.step()
if i%50==0:
print(loss.item(),list(my_linear.parameters()))
优化
3介于1和2之间
4.动量法:(实时更新梯度,用之前的梯度和现在的梯度进行一个加权求和变为新的梯度)
mini-batch SGD算法虽然这种算法能够带来很好的训练速度,但是在到达最优点的时候并不能够总是真正到达最优点,而是在最优点附近徘徊。
另一个缺点就是mini-batch SGD需要我们挑选一个合适的学习率,当我们采用小的学习率的时候,会导致网络在训练的时候收敛太慢;当我们采用大的学习率的时候,会导致在训练过程中优化的幅度跳过函数的范围,也就是可能跳过最优点。我们所希望的仅仅是网络在优化的时候网络的损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。
5和6都是实时改变学习率,用之前的学习率和现在的学习率进行加权求和,借此来更新学习率
7就是把学习率和梯度都进行更新