LeNet
本文编写了一个简单易懂的LeNet网络,并在F-MNIST数据集上进行测试,允许使用GPU计算
python
在这里插入代码片
import torch
from torch import nn, optim
import d2lzh_pytorch as d2l
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# f-mnist 数据集是28*28的
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(1, 6, 5), # 输出通道,输出通道,核大小
nn.Sigmoid(),
nn.MaxPool2d(2, 2), # 高宽减半
nn.Conv2d(6, 16, 5),
nn.Sigmoid(),
nn.MaxPool2d(2, 2)
)
self.fc = nn.Sequential(
d2l.FlattenLayer(),
nn.Linear(16*4*4, 120),
nn.Sigmoid(),
nn.Linear(120, 84),
nn.Sigmoid(),
nn.Linear(84, 10)
)
def forward(self, img):
feature = self.conv(img)
output = self.fc(feature)
return output
net = LeNet()
# 数据集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
# 评估测试集,支持GPU
def evaluate_acc(data_iter, net, device = None):
if device is None and isinstance(net, nn.Module):
device = list(net.parameters())[0].device # 看参数的gpu还是cpu
acc_sum, n = 0.0, 0
with torch.no_grad():
for X,y in data_iter:
if isinstance(net, nn.Module): # 这个可加可不加
net.eval() # 评估模式
acc_sum += (net(X.to(device)).argmax(dim=1) == y.to(device)).float().sum().cpu().item()
net.train() # 转回训练模式
n += y.shape[0]
return acc_sum / n
def train(net, train_iter, test_iter, optimizer, device, epochs):
net = net.to(device)
loss = nn.CrossEntropyLoss()
for epoch in range(epochs):
train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
for X,y in train_iter:
X = X.to(device)
y = y.to(device)
y_hat = net(X)
l = loss(y_hat, y)
optimizer.zero_grad()
l.backward()
optimizer.step()
train_l_sum += l.cpu().item()
train_acc_sum += (y_hat.argmax(dim=1) == y).sum().cpu().item()
n += y.shape[0]
test_acc = evaluate_acc(test_iter, net)
print('epoch %d, loss %.4f, train_acc %.4f, test_acc %.4f'%(epoch + 1, train_l_sum, train_acc_sum/n, test_acc))
lr, epochs = 0.001, 5
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
train(net, train_iter, test_iter, optimizer, device, epochs)