搭建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()