#加载必要的库
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
BATCH_SIZE:每一批处理的数据,比如数据集10000,BATCH_SIZE = 128,第一次就放1-128张图片进去训练。下一个批次就从129-256。
EPOCHS:整个数据集一共训练10次。
#定义超参数
BATCH_SIZE = 128 #每批处理的数据
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(DEVICE)
EPOCHS = 10 #训练数据集的轮次
#构建pipeline,对图像做处理
pipeline = transforms.Compose([
transforms.ToTensor(),#将图片转化为tensor
transforms.Normalize((0.1307,), (0.3081,))#正则化
])
收集数据集,并做预处理。
#下载、加载数据
from torch.utils.data import DataLoader
#下载数据集
train_set = datasets.MNIST("data", train = True, download = True, transform = pipeline)
test_set = datasets.MNIST("data", train = False, download = True, transform = pipeline)
#加载数据集
train_loader = DataLoader(train_set, batch_size = BATCH_SIZE, shuffle = True)
test_loader = DataLoader(test_set, batch_size = BATCH_SIZE, shuffle = True)
搭建网络模型
主要就是神经网络的前向传播
#构建网络模型
class Digit(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 10, 5)#灰度图片的通道
self.conv2 = nn.Conv2d(10, 20, 3) # 灰度图片的通道
self.fc1 = nn.Linear(20*100, 500)
self.fc2 = nn.Linear(500, 10)
def forward(self, x):
input_size = x.size(0)
x = self.conv1(x)
x = F.relu(x)
x = F.max_pool2d(x, 2, 2)
x = self.conv2(x)
x = F.relu(x)
x = x.view(input_size, -1)
x = self.fc1(x)
x = F.relu(x)
x = self.fc2(x)
output = F.log_softmax(x, dim = 1)#计算分类后每个数字的概率
return output
#定义优化器,损失函数,将网络部署在设备上
model = Digit().to(DEVICE)
optimizer = optim.Adam(model.parameters())
loss_fn=torch.nn.CrossEntropyLoss()
#定义训练方法
def train_model(model, device, train_loader, optimizer, epoch):
#模型训练
model.train()
for batch_index, (data, target) in enumerate(train_loader):
#部署到DEVICE上
data, target = data.to(device), target.to(device)
#梯度初始化为0
optimizer.zero_grad()
#训练后的结果
output = model(data)
#计算损失
#loss = F.cross_entropy(output, target)
loss=loss_fn(output, target)
#找到概率值最大的下标
# pred = output.max(1, keepdim = True)
#反向传播
loss.backward()
#参数优化
optimizer.step()
if batch_index % 3000 == 0:
print("Train Epoch : {}\t Loss : {:.6f}".format(epoch, loss.item()))
#定义测试方法
def test_model(model, device, test_loader):
#模型验证
model.eval()
#正确率
correct = 0.0
#测试损失
test_loss = 0.0
with torch.no_grad():
for data, target in test_loader:
#部署到device
data, target = data.to(device), target.to(device)
#测试数据
output = model(data)
#计算测试损失
#test_loss += F.loss_entropy(output, target).item()
test_loss += loss_fn(output, target).item()
#找到概率值最大的下标
pred = output.max(1, keepdim = True)[1]
#累计正确率
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print("Test - Average loss: {:.4f}, Accuracy : {:.3f}".format(
test_loss, 100.0 * correct/len(test_loader.dataset)))
直接调用函数
for epoch in range(1, EPOCHS + 1):
train_model(model, DEVICE, train_loader, optimizer, epoch)
test_model(model, DEVICE, test_loader)