(一)神经网络可以通过 torch.nn 包来构建,一个 nn.Module 包括层和一个方法 forward(input) 它会返回输出(output)。
1、定义一个包含可训练参数的神经网络
2、迭代整个输入
3、通过神经网络处理输入
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
def forward(self, x):
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)
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
定义一个前馈函数,然后反向传播函数被自动通过 autograd 定义。使用任何张量操作在前馈函数上。
一个模型可训练的参数可以通过调用 net.parameters() 返回:
params = list(net.parameters())
让我们尝试随机生成一个 32×32 的输入。注意:期望的输入维度是 32×32 。为了使用这个网络在 MNIST 数据及上,你需要把数据集中的图片维度修改为 32×32。
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)
一个模型可训练的参数可以通过调用 net.parameters() 返回 params = list(net.parameters())
把所有参数梯度缓存器置零,用随机的梯度来反向传播
net.zero_grad()
out.backward(torch.randn(1, 10))
4、计算损失函数loss损失函数:一个损失函数需要一对输入:模型输出和目标,然后计算一个值来评估输出距离目标有多远。
有一些不同的损失函数在 nn 包中。
(1)一个简单的损失函数 nn.MSELoss ,用于计算均方误差。
output = net(input)
target = torch.randn(10) # a dummy target, for example
target = target.view(1, -1) # make it the same shape as output
criterion = nn.MSELoss()
loss = criterion(output, target) print(loss)
注:torch.randn(10)返回一个张量,从标准正态分布(均值为0,方差为1)中抽取的一组随机数。张量的形状由参数sizes定义。
(2)使用分类交叉熵Cross-Entropy 作损失函数,动量SGD做优化器。
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
训练神经网络:在数据迭代器上循环传给网络和优化器 输入就可以。
for epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# get the inputs
inputs, labels = data
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
5、反向传播梯度到神经网络的参数
为了实现反向传播损失,使用 loss.backward(),调用之前需要清空现存的梯度
net.zero_grad()
loss.backward()
6、更新网络的参数:
weight = weight - learning_rate * gradient
(二)利用pytorch训练分类器
怎样处理数据?通常来说,当处理图像,文本,语音或者视频数据时,可以使用标准 python 包将数据加载成 numpy 数组格式,然后将这个数组转换成 torch.*Tensor
- 对于图像,可以用 Pillow,OpenCV
- 对于语音,可以用 scipy,librosa
- 对于文本,可以直接用 Python 或 Cython 基础数据加载模块,或者用 NLTK 和 SpaCy
训练图像分类器的步骤:
- 使用torchvision加载并且归一化CIFAR10的训练和测试数据
- 定义一个卷积神经网络
- 定义一个损失函数
- 在训练样本数据上训练网络
- 在测试样本数据上测试网络
展示图片:
import matplotlib.pyplot as plt
import numpy as np
网络在整个数据集上的表现
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
在GPU上训练:
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Assume that we are on a CUDA machine, then this should print a CUDA device:
print(device)