不同方法准确度
方法 | 轮数 | 准确度(无 BatchNorm2d) | 准确度(有 BatchNorm2d) |
cnn-2conv | 5 | 90.60% | 89.76% |
cnn-2conv | 10 | 90.94% | 91.38% |
cnn-2conv | 15 | 91.31% | 91.95% |
cnn-2conv | 20 | 91.14% | 91.79% |
cnn-3conv | 5 | 91.11% | 90.65% |
cnn-3conv | 10 | 91.73% | 91.64% |
cnn-3conv | 15 | 92.07% | 91.92% |
cnn-3conv | 20 | 91.79% | 92.05% |
cnn-3conv | 25 | 91.96% | 92.45% |
cnn-3conv | 30 | 92.25% | 92.34% |
cnn-3conv | 35 | 91.91% | 92.29% |
cnn-2conv.py
import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data
from torchvision import datasets, transforms
num_epochs = 15
batch_size = 100
learning_rate = 0.001
transform = transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]
)
train_dataset = datasets.FashionMNIST(
root="./data", train=True, transform=transform, download=True
)
test_dataset = datasets.FashionMNIST(
root="./data", train=False, transform=transform, download=True
)
train_loader = data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
class CNNModel(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.layer2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.dropout = nn.Dropout()
self.fc1 = nn.Linear(7 * 7 * 64, 1000)
self.fc2 = nn.Linear(1000, 10)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.reshape(out.size(0), -1)
out = self.dropout(out)
out = self.fc1(out)
out = self.fc2(out)
return out
model = CNNModel().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
output = model(images)
loss = criterion(output, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print(
"Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}".format(
epoch + 1, num_epochs, i + 1, len(train_loader), loss.item()
)
)
model.eval()
with torch.no_grad():
total = 0
correct = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
output = model(images)
_, predict = torch.max(output, 1)
total += labels.size(0)
correct += (predict == labels).sum().item()
print("Accuracy of 10000 test images: {} %".format(correct / total * 100))
cnn-3conv.py
import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data
from torchvision import datasets, transforms
num_epochs = 35
batch_size = 100
learning_rate = 0.001
transform = transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]
)
train_dataset = datasets.FashionMNIST(
root="./data", train=True, transform=transform, download=True
)
test_dataset = datasets.FashionMNIST(
root="./data", train=False, transform=transform, download=True
)
train_loader = data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
class CNNModel(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.layer2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.layer3 = nn.Sequential(
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.dropout = nn.Dropout()
self.fc1 = nn.Linear(3 * 3 * 128, 512)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = self.layer3(out)
out = out.reshape(out.size(0), -1)
out = self.dropout(out)
out = self.fc1(out)
out = self.fc2(out)
return out
model = CNNModel().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
output = model(images)
loss = criterion(output, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print(
"Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}".format(
epoch + 1, num_epochs, i + 1, len(train_loader), loss.item()
)
)
model.eval()
with torch.no_grad():
total = 0
correct = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
output = model(images)
_, predict = torch.max(output, 1)
total += labels.size(0)
correct += (predict == labels).sum().item()
print("Accuracy of 10000 test images: {} %".format(correct / total * 100))
预测模型类别
'''
快速开始
'''
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor
import os
# 1.下载数据集
train_data = datasets.FashionMNIST(
root="./data",
train=True,
download=True,
transform=ToTensor()
)
test_data = datasets.FashionMNIST(
root="./data",
train=False,
download=True,
transform=ToTensor()
)
batch_size = 64
train_dataloader = DataLoader(train_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)
device = (
'cuda' if torch.cuda.is_available()
else 'mps'
if torch.backends.mps.is_available()
else 'cpu'
)
print(f'Using {device} device')
# 2.定义模型
class NeuralNetwork(nn.Module):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.linear_relu_stack = nn.Sequential(
nn.Linear(28*28, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 10)
)
def forward(self, x):
x = self.flatten(x)
logits = self.linear_relu_stack(x)
return logits
model_state_path = './model/model.pth'
model = NeuralNetwork().to(device)
if os.path.exists(model_state_path):
model.load_state_dict(torch.load(model_state_path))
print(model)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
# 3.训练模型
def train(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
model.train()
for batch, (X, y) in enumerate(dataloader):
X, y = X.to(device), y.to(device)
pred = model(X)
loss = loss_fn(pred, y)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if batch % 100 == 0:
loss, current = loss.item(), (batch + 1) * len(X)
print(f'loss: {loss:>7f} [{current:>5d}/{size:>5d}]')
# 4.测试模型
def test(dataloader, model, loss_fn):
size = len(dataloader.dataset)
num_batches = len(dataloader)
model.eval()
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in dataloader:
X, y = X.to(device), y.to(device)
pred = model(X)
test_loss += loss_fn(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batches
correct /= size
print(
f'Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f}')
epochs = 5
for t in range(epochs):
print(f'Epoch {t+1}\n----------------------------')
train(train_dataloader, model, loss_fn, optimizer)
test(test_dataloader, model, loss_fn)
print('Done!')
torch.save(model.state_dict(), model_state_path)
print('Saved PyTorch Model State to model.pth')
# 5.模型预测
classes = [
"T-shirt/top",
"Trouser",
"Pullover",
"Dress",
"Coat",
"Sandal",
"Shirt",
"Sneaker",
"Bag",
"Ankle boot",
]
model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
x = x.to(device)
pred = model(x)
predicted, actual = classes[pred[0].argmax(0)], classes[y]
print(f'Predicted: "{predicted}", Actual: "{actual}"')