一、torch.optim
torch.optim.Optimizer(params, defaults)優化器官網說明
由官網給的使用說明打開看出來優化器實驗步驟:
①構造選擇優化器
例如采用隨機梯度下降優化器SGD
torch.optim.SGD(beyond.parameters(),lr=0.01)
,放入beyond模型的參數parameters;學習率learning rate;
每個優化器都有其特定獨有的參數
②把網絡中所有的可用梯度全部設置為0
optim.zero_grad()
梯度為tensor中的一個屬性,這就是為啥神經網絡傳入的數據必須是tensor數據類型的原因,grad這個屬性其實就是求導,常用在反向傳播中,也就是通過先通過正向傳播依次求出結果,再通過反向傳播求導來依次倒退,其目的主要是對參數進行調整優化,詳細的學習了解可自行百度。
③通過反向傳播獲取損失函數的梯度
result_loss.backward()
這里使用的損失函數為loss,其對象為result_loss,當然也可以使用其他的損失函數
從而得到每個可以調節參數的梯度
④調用step方法,對每個梯度參數進行調優更新
optim.step()
使用優化器的step方法,會利用之前得到的梯度grad,來對模型中的參數進行更新
二、優化器的使用
使用CIFAR-10數據集的測試集,使用之前實現的網絡模型,二、復現網絡模型訓練CIFAR-10數據集
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterdataset_testset = torchvision.datasets.CIFAR10("CIFAR_10",train=False,transform=torchvision.transforms.ToTensor(),download=True)dataloader = DataLoader(dataset_testset,batch_size=2)class Beyond(nn.Module):def __init__(self):super(Beyond,self).__init__()self.model = torch.nn.Sequential(torch.nn.Conv2d(3,32,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Conv2d(32,32,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Conv2d(32,64,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Flatten(),torch.nn.Linear(1024,64),torch.nn.Linear(64,10))def forward(self,x):x = self.model(x)return x
loss = nn.CrossEntropyLoss()#構建選擇損失函數為交叉熵
beyond = Beyond()
#print(beyond)
optim = torch.optim.SGD(beyond.parameters(),lr=0.01)for epoch in range(30):#進行30輪訓練sum_loss = 0.0for data in dataloader:imgs, targets = dataoutput = beyond(imgs)# print(output)# print(targets)result_loss = loss(output, targets)# print(result_loss)optim.zero_grad()#把網絡模型中所有的梯度都設置為0result_loss.backward()#反向傳播獲得每個參數的梯度從而可以通過優化器進行調優optim.step()#print(result_loss)sum_loss = sum_loss + result_lossprint(sum_loss)"""
tensor(9431.9678, grad_fn=<AddBackward0>)
tensor(7715.2842, grad_fn=<AddBackward0>)
tensor(6860.3115, grad_fn=<AddBackward0>)
......"""
在optim.zero_grad()及其下面三行處,左擊打個斷點,進入Debug模式(Shift+F9)下,
網絡模型名稱---Protected Attributes---__modules---0-8隨便選一個,例如'0'---weight---grad就是參數的梯度
三、自動調整學習速率設置
torch.optim.lr_scheduler.ExponentialLR(optimizer=optim,gamma=0.1)
optimizer為優化器的名稱,gamma表示每次都會將原來的lr乘以gamma
使用optim優化器,每次就會在原來的學習速率的基礎上乘以0.1
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.optim.lr_scheduler import StepLR, ExponentialLR
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterdataset_testset = torchvision.datasets.CIFAR10("CIFAR_10",train=False,transform=torchvision.transforms.ToTensor(),download=True)dataloader = DataLoader(dataset_testset,batch_size=2)class Beyond(nn.Module):def __init__(self):super(Beyond,self).__init__()self.model = torch.nn.Sequential(torch.nn.Conv2d(3,32,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Conv2d(32,32,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Conv2d(32,64,5,padding=2),torch.nn.MaxPool2d(2),torch.nn.Flatten(),torch.nn.Linear(1024,64),torch.nn.Linear(64,10))def forward(self,x):x = self.model(x)return x
loss = nn.CrossEntropyLoss()#構建選擇損失函數為交叉熵
beyond = Beyond()
#print(beyond)
optim = torch.optim.SGD(beyond.parameters(),lr=0.01)
scheduler = ExponentialLR(optimizer=optim,gamma=0.1)#在原來的lr上乘以gammafor epoch in range(30):#進行30輪訓練sum_loss = 0.0for data in dataloader:imgs, targets = dataoutput = beyond(imgs)# print(output)# print(targets)result_loss = loss(output, targets)# print(result_loss)optim.zero_grad()#把網絡模型中所有的梯度都設置為0result_loss.backward()#反向傳播獲得每個參數的梯度從而可以通過優化器進行調優optim.step()#print(result_loss)sum_loss = sum_loss + result_lossscheduler.step()#這里就需要不能用優化器,而是使用自動學習速率的優化器print(sum_loss)"""
tensor(9469.4385, grad_fn=<AddBackward0>)
tensor(7144.1514, grad_fn=<AddBackward0>)
tensor(6734.8311, grad_fn=<AddBackward0>)
......"""