2019-08-12 PyTorch 入门笔记 2 简易神经网络搭建与训练

简易神经网络搭建与训练

实例代码及注释如下

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim


# 构建神经网络卷积核,映射函数,前向传播
class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 设置2D卷积核 1 input -> 6 output 3*3 kernel
        #           6 input -> 16 output 3*3 kernel
        self.conv1 = nn.Conv2d(1, 6, 3)
        self.conv2 = nn.Conv2d(6, 16, 3)
        # an affine operation: y = Wx + b
        # 设置从16*6*6到10的映射函数
        self.fc1 = nn.Linear(16 * 6 * 6, 120)  # 6*6 from image dimension
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 基于卷积结果的relu结果,最大值池化至 2*2 窗口
        # 尺寸变化:n*n -> (n-1)*(n-1) -> (n-1)*(n-1) -> 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 = x.size()[1:]  # 除了batch的所有维度
        num_features = 1
        for s in size:
            num_features *= s
        return num_features


net = Net()
print(net)

# 可学习参数
params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight

# 尝试一个随机的32x32输入
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)

# 使用随机梯度将所有参数和反向的梯度缓冲区归零:
net.zero_grad()
out.backward(torch.randn(1, 10))

# 计算均方误差
output = net(input)
target = torch.randn(10) 
target = target.view(1, -1)  # 使尺寸相同

criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)

# 后退
print(loss.grad_fn)  # MSELoss
print(loss.grad_fn.next_functions[0][0])  # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])  # ReLU

# 清除现有梯度
# 看一下conv1在向后之前和之后的偏差梯度
net.zero_grad()     # zeroes the gradient buffers of all parameters

print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)

loss.backward()

print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)

# 随机梯度下降 learning rate = 0.01
optimizer = optim.SGD(net.parameters(), lr=0.01)

# 训练100次
for num in range(1,100):
    optimizer.zero_grad()   # 清楚现有梯度
    output = net(input)
    loss = criterion(output, target)
    print(loss)
    loss.backward()
    optimizer.step()    # Does the update



你可能感兴趣的:(2019-08-12 PyTorch 入门笔记 2 简易神经网络搭建与训练)