一、线性模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import torch
from torchvision import transforms
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader, Dataset
from torchvision import datasets

# 参数定义
Batch_size = 128
LR = 0.001
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 加载数据集
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST(
root='./dataset/mnist',
train=True,
download=True,
transform=transform,
)
test_dataset = datasets.MNIST(
root='./dataset/mnist',
train=False,
download=True,
transform=transform,
)
train_loader = DataLoader(dataset=train_dataset, batch_size=Batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=Batch_size)

# 设计模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.L1 = nn.Linear(784, 512)
self.L2 = nn.Linear(512, 256)
self.L3 = nn.Linear(256, 128)
self.L4 = nn.Linear(128, 64)
self.L5 = nn.Linear(64, 10)

def forward(self, x):
x = x.view(-1, 784)
x = F.relu(self.L1(x))
x = F.relu(self.L2(x))
x = F.relu(self.L3(x))
x = F.relu(self.L4(x))
return self.L5(x)
model = Net().to(device)

# 构造损失和优化
criterion = nn.CrossEntropyLoss()
# optimizer = optim.SGD(model.parameters(), lr=LR, momentum=0.5)
optimizer = optim.Adam(
model.parameters(),
lr=LR,
)
# 定义单轮训练函数
def train(epoch):
running_loss = 0.0
for batch_id, data in enumerate(train_loader, 0):
inputs, target = data
optimizer.zero_grad()

outputs = model(inputs.cuda())
loss = criterion(outputs, target.cuda())
loss.backward()

optimizer.step()

running_loss += loss.item()

if batch_id % 100 == 99:
print('[%d,%5d] loss:%.3f' % (epoch+1, batch_id+1,running_loss / 100))
running_loss = 0.0


# 定义测试函数
def test_model():
correct = 0
total = 0
with torch.no_grad():
for data in test_loader:
images, labels = data
outputs = model(images.cuda())
_, predicted = torch.max(outputs.data, dim=1)
total += labels.size(0)
correct += (predicted == labels.cuda()).sum().item()
print('Accuracy on test set:%.4f %%' % (100 * correct / total))

# 开始训练
for epoch in range(2):
train(epoch)

print('开始测试模型...')
# 测试模型
test_model()

二、卷积神经网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import cv2
import torch
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader

import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable

train_set = torchvision.datasets.MNIST(root='dataset/mnist', train=True, transform=transforms.ToTensor(), download=True)
test_set = torchvision.datasets.MNIST(root='dataset/mnist', train=False, transform=transforms.ToTensor(), download=True)

train_loader = DataLoader(dataset=train_set, batch_size=128, shuffle=True)
test_loader = DataLoader(dataset=test_set, batch_size=128, shuffle=False)

class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Sequential(nn.Conv2d(1, 6, 3, 1, 2), nn.ReLU(),
nn.MaxPool2d(2, 2))

self.conv2 = nn.Sequential(nn.Conv2d(6, 16, 5), nn.ReLU(),
nn.MaxPool2d(2, 2))

self.fc1 = nn.Sequential(nn.Linear(16 * 5 * 5, 120),
nn.BatchNorm1d(120), nn.ReLU())

self.fc2 = nn.Sequential(
nn.Linear(120, 84),
nn.BatchNorm1d(84),
nn.ReLU(),
nn.Linear(84, 10))


def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size()[0], -1)
x = self.fc1(x)
x = self.fc2(x)
return x
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
LR = 0.001

net = LeNet().to(device)
# 损失函数使用交叉熵
criterion = nn.CrossEntropyLoss()
# 优化函数使用 Adam 自适应优化算法
optimizer = optim.Adam(
net.parameters(),
lr=LR,
)

epoch = 2
if __name__ == '__main__':
for epoch in range(epoch):
sum_loss = 0.0
for i, data in enumerate(train_loader):
inputs, labels = data
inputs, labels = Variable(inputs).cuda(), Variable(labels).cuda()
optimizer.zero_grad() #将梯度归零
outputs = net(inputs) #将数据传入网络进行前向运算
loss = criterion(outputs, labels) #得到损失函数
loss.backward() #反向传播
optimizer.step() #通过梯度做一步参数更新

# print(loss)
sum_loss += loss.item()
if i % 100 == 99:
print('[%d,%d] loss:%.03f' %
(epoch + 1, i + 1, sum_loss / 100))
sum_loss = 0.0
net.eval() # 将模型变换为测试模式
correct = 0
total = 0
for data_test in test_loader:
images, labels = data_test
images, labels = Variable(images).cuda(), Variable(labels).cuda()
output_test = net(images)
_, predicted = torch.max(output_test, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print("Accuracy on test set: {0}%".format(100 * correct / total))