一、定义网络

1.1 代码

# 导入若干工具包
import torch
import torch.nn as nn
import torch.nn.functional as F


# 定义一个简单的网络类
class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 定义第一层卷积神经网络, 输入通道维度=1, 输出通道维度=6, 卷积核大小3*3
        self.conv1 = nn.Conv2d(1, 6, 3)
        # 定义第二层卷积神经网络, 输入通道维度=6, 输出通道维度=16, 卷积核大小3*3
        self.conv2 = nn.Conv2d(6, 16, 3)
        # 定义三层全连接网络
        self.fc1 = nn.Linear(16 * 6 * 6, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 在(2, 2)的池化窗口下执行最大池化操作
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        # 计算size, 除了第0个维度上的batch_size
        size = x.size()[1:]
        num_features = 1
        for s in size:
            num_features *= s
        return num_features


net = Net()
print(net)

 1.2 一些属性和参数

#看一下里面的对象分别属于那些类
print(type(net))
print(type(net.conv1))
print(type(net.fc1))

 可以用net.parameters()或者net.sublayer(?).parameters()方法获得一个迭代器,里面是所有的参数。

net.parameters()

print(net.parameters())#一个迭代器
param=list(net.parameters())#可以用list(迭代器)将迭代器中的内容全部放入列表中
print(len(param))#数数这个模型中一共有多少个参数
print(type(param[1]))#这是迭代器中的某一个元素【第1个【第2个】参数】的类型:torch.nn.parameter.Parameter
print(param[1])#本质上也是一个tensor

 二、训练过程

inp=torch.rand(1,1,32,32)

import torch.optim as optim

# 用一个优化器,把所有的参数都放进去
optimizer = optim.SGD(net.parameters(), lr=0.01)

# 将参数梯度清零->将优化器梯度清零
optimizer.zero_grad()

#前向传播
output = net(inp)

#计算损失 用到criteriron(实例化一种计算损失的方法)output和target是两个形状相同(1*10)的tensor
loss = criterion(output, target)

# 对损失值执行反向传播的操作
loss.backward()

# 现在已经计算好了每个参数的grad,可以用optimizer定义的优化方法(SGD)来优化
optimizer.step()