-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.txt
More file actions
166 lines (135 loc) · 5.3 KB
/
code.txt
File metadata and controls
166 lines (135 loc) · 5.3 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import torch
import torchvision
import torch.nn.functional as F
from torch.utils.data import DataLoader
class BasicBlock(torch.nn.Module):
"""残差块"""
def __init__(self, inplanes, planes, stride=1):
"""初始化"""
super(BasicBlock, self).__init__()
self.conv1 = torch.nn.Conv2d(in_channels=inplanes, out_channels=planes, kernel_size=(3, 3),
stride=(stride, stride), padding=1) # 卷积层1
self.bn1 = torch.nn.BatchNorm2d(planes) # 标准化层1
self.conv2 = torch.nn.Conv2d(in_channels=planes, out_channels=planes, kernel_size=(3, 3), padding=1) # 卷积层2
self.bn2 = torch.nn.BatchNorm2d(planes) # 标准化层2
# 如果步长不为1, 用1*1的卷积实现下采样
if stride != 1:
self.downsample = torch.nn.Sequential(
# 下采样
torch.nn.Conv2d(in_channels=inplanes, out_channels=planes, kernel_size=(1, 1), stride=(stride, stride)))
else:
self.downsample = lambda x: x # 返回x
def forward(self, input):
"""前向传播"""
out = self.conv1(input)
out = self.bn1(out)
out = F.relu(out)
out = self.conv2(out)
out = self.bn2(out)
identity = self.downsample(input)
output = torch.add(out, identity)
output = F.relu(output)
return output
ResNet_18 = torch.nn.Sequential(
# 初始层
torch.nn.Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1)), # 卷积
torch.nn.BatchNorm2d(64),
torch.nn.ReLU(),
torch.nn.MaxPool2d((2, 2)), # 池化
# 8个block(每个为两层)
BasicBlock(64, 64, stride=1),
BasicBlock(64, 64, stride=1),
BasicBlock(64, 128, stride=2),
BasicBlock(128, 128, stride=1),
BasicBlock(128, 256, stride=2),
BasicBlock(256, 256, stride=1),
BasicBlock(256, 512, stride=2),
BasicBlock(512, 512, stride=1),
torch.nn.AvgPool2d(2), # 池化
torch.nn.Flatten(), # 平铺层
# 全连接层
torch.nn.Linear(512, 100) # 100类
)
def get_data():
"""获取数据"""
# 获取测试集
train = torchvision.datasets.CIFAR100(root="./data", train=True, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(), # 转换成张量
torchvision.transforms.Normalize((0.1307,), (0.3081,)) # 标准化
]))
train_loader = DataLoader(train, batch_size=batch_size) # 分割测试集
# 获取测试集
test = torchvision.datasets.CIFAR100(root="./data", train=False, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(), # 转换成张量
torchvision.transforms.Normalize((0.1307,), (0.3081,)) # 标准化
]))
test_loader = DataLoader(test, batch_size=batch_size) # 分割训练
# 返回分割好的训练集和测试集
return train_loader, test_loader
def train(model, epoch, train_loader):
"""训练"""
# 训练模式
model.train()
# 迭代
for step, (x, y) in enumerate(train_loader):
# 加速
if use_cuda:
model = model.cuda()
x, y = x.cuda(), y.cuda()
# 梯度清零
optimizer.zero_grad()
output = model(x)
# 计算损失
loss = F.cross_entropy(output, y)
# 反向传播
loss.backward()
# 更新梯度
optimizer.step()
# 打印损失
if step % 10 == 0:
print('Epoch: {}, Step {}, Loss: {}'.format(epoch, step, loss))
def test(model, test_loader):
"""测试"""
# 测试模式
model.eval()
# 存放正确个数
correct = 0
with torch.no_grad():
for x, y in test_loader:
# 加速
if use_cuda:
model = model.cuda()
x, y = x.cuda(), y.cuda()
# 获取结果
output = model(x)
# 预测结果
pred = output.argmax(dim=1, keepdim=True)
# 计算准确个数
correct += pred.eq(y.view_as(pred)).sum().item()
# 计算准确率
accuracy = correct / len(test_loader.dataset) * 100
# 输出准确
print("Test Accuracy: {}%".format(accuracy))
# 定义超参数
batch_size = 2048 # 一次训练的样本数目
learning_rate = 0.001 # 学习率
iteration_num = 500 # 迭代次数
network = ResNet_18
optimizer = torch.optim.Adam(network.parameters(), lr=learning_rate) # 优化器
# GPU 加速
use_cuda = torch.cuda.is_available()
if use_cuda:
network.cuda()
print("是否使用 GPU 加速:", use_cuda)
def main():
# 获取数据
train_loader, test_loader = get_data()
# 迭代
for epoch in range(iteration_num):
print("\n================ epoch: {} ================".format(epoch))
train(network, epoch, train_loader)
test(network, test_loader)
if __name__ == "__main__":
main()