isLandLZ's picture
Upload train.py
9e14f32
raw history blame
No virus
4.26 kB
import torch
import torchvision
from torch import optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
from Pytorch_MNIST图片识别.model import Net
import matplotlib.pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
# TODO epoch的数量定义了我们将循环整个训练数据集的次数
n_epochs = 3
# TODO 使用batch_size=64进行训练,并使用size=1000对这个数据集进行测试
batch_size_train = 64
batch_size_test = 1000
# TODO 优化器的超参数
learning_rate = 0.01
momentum = 0.5
log_interval = 10
random_seed = 1
torch.manual_seed(random_seed)
# TODO 自动将MNIST数据集下载到目录下的data文件夹
train_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('./data/', train=True, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
# TODO MNIST数据集的全局平均值和标准偏差
torchvision.transforms.Normalize(
(0.1307,), (0.3081,))
])),
batch_size=batch_size_train, shuffle=True)
test_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('./data/', train=False, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
# TODO MNIST数据集的全局平均值和标准偏差
torchvision.transforms.Normalize(
(0.1307,), (0.3081,))
])),
batch_size=batch_size_test, shuffle=False)
# TODO 初始化网络和优化器
network = Net()
optimizer = optim.SGD(network.parameters(), lr=learning_rate, momentum=momentum)
train_losses = []
train_counter = []
test_losses = []
test_counter = [i * len(train_loader.dataset) for i in range(n_epochs + 1)]
# TODO 模型存储位置(一个是完整的模型,一个是只有参数的模型)
# TODO 需要先建立一个model文件夹
model_path = './model1/model.pth'
optimizer_path = './model1/optimizer.pth'
def train(epoch):
network.train()
for batch_idx, (data, target) in enumerate(train_loader):
# TODO 需要使用optimizer.zero_grad()手动将梯度设置为零,因为PyTorch在默认情况下会累积梯度
optimizer.zero_grad()
output = network(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if batch_idx % log_interval == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item()))
train_losses.append(loss.item())
train_counter.append(
(batch_idx * 64) + ((epoch - 1) * len(train_loader.dataset)))
if epoch == (n_epochs - 1):
# TODO 存储模型
torch.save(network.state_dict(), model_path)
torch.save(optimizer.state_dict(), optimizer_path)
def test():
network.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
output = network(data)
test_loss += F.nll_loss(output, target, size_average=False).item()
pred = output.data.max(1, keepdim=True)[1]
correct += pred.eq(target.data.view_as(pred)).sum()
test_loss /= len(test_loader.dataset)
test_losses.append(test_loss)
print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
for epoch in range(1, n_epochs + 1):
train(epoch)
test()
fig = plt.figure()
plt.plot(train_counter, train_losses, color='blue')
print(len(test_counter))
print(len(test_losses))
plt.scatter(test_counter, test_losses, color='red')
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')
plt.show()