搭建letnet5 以及輸出網絡結構 。網絡參數
import torch.nn as nn
import torch.nn.functional as F
import torch
class letnet5(nn.Module):
def __init__(self):#具有可學習參數的最好放在構造函數中
super(letnet5,self).__init__()
#卷積
self.conv1=nn.Conv2d(1,6,5)#輸入1通道,輸出6通道,卷積核5*5
self.conv2=nn.Conv2d(6,16,5)
#全連接層
self.fc1=nn.Linear(16*5*5,120)
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
def forward(self,x):
#只要在nn.Module的子類中定義了forward函數,backward函數就會自動被實現(利用autograd)。
#在forward 函數中可使用任何tensor支持的函數,還可以使用if、for循環、print、log等Python語法,寫法和標準的Python寫法一致。
x=F.max_pool2d(F.relu(self.conv1(x)),(2,2)) #正方形的pool 參數 (2,2) 等價於 2
x=F.max_pool2d(F.relu(self.conv2(x)),2)
#view相當於reshape,-1自適應
print(x.size())
x=x.view(x.size()[0],-1)#(batch_size,-1)
x=F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)
return x
net=letnet5()
input=torch.randn(1,1,32,32)
out=net(input)#直接輸入就可以調用forward
print(out)
#網絡的可學習參數通過net.parameters()返回
param=list(net.parameters())
print(param[0].size())#[6,1,5,5]6個卷積核,1維,5*5
#net.named_parameters可同時返回可學習的參數及名稱。
print('網絡整體參數:')
for name,parameters in net.named_parameters():
print(name,':',parameters.size())
#反向傳播
out.backward(torch.zeros((1,10)))
損失函數 和 計算梯度
net=letnet5()
input=torch.randn(1,1,32,32)
out=net(input)#直接輸入就可以調用forward
print(out)
target=torch.arange(0,10).view((1,10)).float()
loss_fun=torch.nn.MSELoss()#均方差(x-y)**2
loss=loss_fun(out,target)
print(loss)
net.zero_grad()#每次反向傳播前 梯度清零
loss.backward()
print(net.conv1.weight.grad)#輸出參數的梯度
print(net.conv1.bias.grad)
優化器
net=letnet5()
input=torch.randn(1,1,32,32)
out=net(input)#直接輸入就可以調用forward
print(out)
target=torch.arange(0,10).view((1,10)).float()
loss_fun=torch.nn.MSELoss()#均方差(x-y)**2
loss=loss_fun(out,target)
import torch.optim as optim
#新建SGD優化器
optimizer=optim.SGD(net.parameters(),lr=0.001)
#優化器梯度先清零
optimizer.zero_grad()
loss.backward()
optimizer.step()