数据加载器

  • 将数据集中的尺寸转换为统一大小($28\times 28$),并将其转换为张量(Tensor)格式
  • 以8:2划分为训练集和验证集
  • 为训练集和验证集分别创建DataLoader实例,并配置数据加载参数
    • 设定batch
    • 是否打乱
    • 子进程数量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def train_val_dataprocess():
train_data = FashionMNIST(root='./data',
train=True,
# 将图片尺寸调整为28×28,之后转换为Tensor格式
transform=transform.Compose([transform.Resize(size=28), transform.ToTensor()]),
download=True)
# 将数据集按8:2的格式分为训练集和验证集
train_data, val_data = Data.random_split(train_data, [round(0.8*len(train_data)), round(0.2*len(train_data))])

# 以train_data为数据对象,批量大小为32,打乱数据集,设置子进程为2
train_dataloader = Data.Dataloader(dataset=train_data,
batch_size=32,
shuffle=True,
num_workers=2)

val_dataloader = Data.Dataloader(dataset=val_data,
batch_size=32,
shuffle=True,
num_workers=2)

return train_dataloader, val_dataloader

训练过程

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
def train_model_process(model, train_dataloader, val_dataloader, num_epochs):
# 设置运行设备为GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 设置优化器为Adam,学习率为0.01
optimizer = torch.optim.Adam(model.parameters(), 0.01)
# 设置损失函数为交叉熵损失函数
criterion = nn.CrossEntropyLoss()
# 将模型放入设备
model = model.to(device)

best_model_wts = copy.deepcopy(model.state_dict())
# 初始化参数
best_acc = 0.0
train_loss_all = []
val_loss_all = []
train_acc_all = []
val_acc_all = []
since = time.time()

for epoch in range(num_epochs):
print("Epoch {}/{}".format(epoch, num_epochs-1))
print("-"*10)

train_loss = 0.0
train_corrects = 0

val_loss = 0.0
val_corrects = 0

train_num = 0
val_num = 0

for step, (b_x, b_y) in enurmate(train_dataloader):
b_x = b_x.to(device)
b_y = b_y.to(device)

# 开启训练模型
model.train()
# 前向传播
# output为tensor形式的n行(batch_size大小)m列(类别大小)
output = model(b_x)
# pre_lab为tensor形式的一维数组,数组长度为batch_size大小,每个值为对应图片的最大可能预测值
pre_lab = torch.argmax(output, dim=1)
# 计算损失值
loss = criterion(output, b_y)

# 清空梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新model.parameters()
optimizer.step()

train_loss += loss.item() * b_x.size()
train_corrects += torch.sum(pre_lab == b_y.data)
train_sum += b_x.size(0)