day40python打卡

article/2025/7/18 15:45:28

知识点回顾:

  1. 彩色和灰度图片测试和训练的规范写法:封装在函数中
  2. 展平操作:除第一个维度batchsize外全部展平
  3. dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout

作业:仔细学习下测试和训练代码的逻辑,这是基础,这个代码框架后续会一直沿用,后续的重点慢慢就是转向模型定义阶段了。

昨天我们介绍了图像数据的格式以及模型定义的过程,发现和之前结构化数据的略有不同,主要差异体现在2处

  1. 模型定义的时候需要展平图像
  2. 由于数据过大,需要将数据集进行分批次处理,这往往涉及到了dataset和dataloader来规范代码的组织

现在我们把注意力放在训练和测试代码的规范写法上

单通道图片的规范写法

# 先继续之前的代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加载数据的工具
from torchvision import datasets, transforms # torchvision 是一个用于计算机视觉的库,datasets 和 transforms 是其中的模块
import matplotlib.pyplot as plt
import warnings
# 忽略警告信息
warnings.filterwarnings("ignore")
# 设置随机种子,确保结果可复现
torch.manual_seed(42)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"使用设备: {device}")
使用设备: cuda
# 1. 数据预处理
transform = transforms.Compose([transforms.ToTensor(),  # 转换为张量并归一化到[0,1]transforms.Normalize((0.1307,), (0.3081,))  # MNIST数据集的均值和标准差
])# 2. 加载MNIST数据集
train_dataset = datasets.MNIST(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.MNIST(root='./data',train=False,transform=transform
)# 3. 创建数据加载器
batch_size = 64  # 每批处理64个样本
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# 4. 定义模型、损失函数和优化器
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 将28x28的图像展平为784维向量self.layer1 = nn.Linear(784, 128)  # 第一层:784个输入,128个神经元self.relu = nn.ReLU()  # 激活函数self.layer2 = nn.Linear(128, 10)  # 第二层:128个输入,10个输出(对应10个数字类别)def forward(self, x):x = self.flatten(x)  # 展平图像x = self.layer1(x)   # 第一层线性变换x = self.relu(x)     # 应用ReLU激活函数x = self.layer2(x)   # 第二层线性变换,输出logitsreturn x# 初始化模型
model = MLP()
model = model.to(device)  # 将模型移至GPU(如果可用)# from torchsummary import summary  # 导入torchsummary库
# print("\n模型结构信息:")
# summary(model, input_size=(1, 28, 28))  # 输入尺寸为MNIST图像尺寸criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数,适用于多分类问题
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam优化器
# 5. 训练模型(记录每个 iteration 的损失)
def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):model.train()  # 设置为训练模式# 新增:记录每个 iteration 的损失all_iter_losses = []  # 存储所有 batch 的损失iter_indices = []     # 存储 iteration 序号(从1开始)for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):# enumerate() 是 Python 内置函数,用于遍历可迭代对象(如列表、元组)并同时获取索引和值。# batch_idx:当前批次的索引(从 0 开始)# (data, target):当前批次的样本数据和对应的标签,是一个元组,这是因为dataloader内置的getitem方法返回的是一个元组,包含数据和标签。# 只需要记住这种固定写法即可data, target = data.to(device), target.to(device)  # 移至GPU(如果可用)optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向传播loss = criterion(output, target)  # 计算损失loss.backward()  # 反向传播optimizer.step()  # 更新参数# 记录当前 iteration 的损失(注意:这里直接使用单 batch 损失,而非累加平均)iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)  # iteration 序号从1开始# 统计准确率和损失running_loss += loss.item() #将loss转化为标量值并且累加到running_loss中,计算总损失_, predicted = output.max(1) # output:是模型的输出(logits),形状为 [batch_size, 10](MNIST 有 10 个类别)# 获取预测结果,max(1) 返回每行(即每个样本)的最大值和对应的索引,这里我们只需要索引total += target.size(0) # target.size(0) 返回当前批次的样本数量,即 batch_size,累加所有批次的样本数,最终等于训练集的总样本数correct += predicted.eq(target).sum().item() # 返回一个布尔张量,表示预测是否正确,sum() 计算正确预测的数量,item() 将结果转换为 Python 数字# 每100个批次打印一次训练信息(可选:同时打印单 batch 损失)if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 单Batch损失: {iter_loss:.4f} | 累计平均损失: {running_loss/(batch_idx+1):.4f}')# 测试、打印 epoch 结果epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / totalepoch_test_loss, epoch_test_acc = test(model, test_loader, criterion, device)print(f'Epoch {epoch+1}/{epochs} 完成 | 训练准确率: {epoch_train_acc:.2f}% | 测试准确率: {epoch_test_acc:.2f}%')# 绘制所有 iteration 的损失曲线plot_iter_losses(all_iter_losses, iter_indices)# 保留原 epoch 级曲线(可选)# plot_metrics(train_losses, test_losses, train_accuracies, test_accuracies, epochs)return epoch_test_acc  # 返回最终测试准确率

之前我们用mlp训练鸢尾花数据集的时候并没有用函数的形式来封装训练和测试过程,这样写会让代码更加具有逻辑-----隔离参数和内容。

  1. 后续直接修改参数就行,不需要去找到对应操作的代码
  2. 方便复用,未来有多模型对比时,就可以复用这个函数

这里我们先不写早停策略,因为规范的早停策略需要用到验证集,一般还需要划分测试集

  1. 划分数据集:训练集(用于训练)、验证集(用于早停和调参)、测试集(用于最终报告性能)。
  2. 在训练过程中,使用验证集触发早停。
  3. 训练结束后,仅用测试集运行一次测试函数,得到最终准确率。

测试函数和绘图函数均被封装在了train函数中,但是test和绘图函数在定义train函数之后,这是因为在 Python 中,函数定义的顺序不影响调用,只要在调用前已经完成定义即可。

# 6. 测试模型(不变)
def test(model, test_loader, criterion, device):model.eval()  # 设置为评估模式test_loss = 0correct = 0total = 0with torch.no_grad():  # 不计算梯度,节省内存和计算资源for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()avg_loss = test_loss / len(test_loader)accuracy = 100. * correct / totalreturn avg_loss, accuracy  # 返回损失和准确率

如果打印每一个bitchsize的损失和准确率,会看的更加清晰,更加直观

# 7. 绘制每个 iteration 的损失曲线
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')plt.xlabel('Iteration(Batch序号)')plt.ylabel('损失值')plt.title('每个 Iteration 的训练损失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()
# 8. 执行训练和测试(设置 epochs=2 验证效果)
epochs = 2  
print("开始训练模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"训练完成!最终测试准确率: {final_accuracy:.2f}%")
开始训练模型...
Epoch: 1/2 | Batch: 100/938 | 单Batch损失: 0.3580 | 累计平均损失: 0.6322
Epoch: 1/2 | Batch: 200/938 | 单Batch损失: 0.2051 | 累计平均损失: 0.4777
Epoch: 1/2 | Batch: 300/938 | 单Batch损失: 0.3124 | 累计平均损失: 0.4054
Epoch: 1/2 | Batch: 400/938 | 单Batch损失: 0.1475 | 累计平均损失: 0.3672
Epoch: 1/2 | Batch: 500/938 | 单Batch损失: 0.1780 | 累计平均损失: 0.3323
Epoch: 1/2 | Batch: 600/938 | 单Batch损失: 0.3142 | 累计平均损失: 0.3107
Epoch: 1/2 | Batch: 700/938 | 单Batch损失: 0.0472 | 累计平均损失: 0.2923
Epoch: 1/2 | Batch: 800/938 | 单Batch损失: 0.0938 | 累计平均损失: 0.2765
Epoch: 1/2 | Batch: 900/938 | 单Batch损失: 0.3006 | 累计平均损失: 0.2630
Epoch 1/2 完成 | 训练准确率: 92.43% | 测试准确率: 95.83%
Epoch: 2/2 | Batch: 100/938 | 单Batch损失: 0.1810 | 累计平均损失: 0.1363
Epoch: 2/2 | Batch: 200/938 | 单Batch损失: 0.1757 | 累计平均损失: 0.1290
Epoch: 2/2 | Batch: 300/938 | 单Batch损失: 0.1231 | 累计平均损失: 0.1282
Epoch: 2/2 | Batch: 400/938 | 单Batch损失: 0.2033 | 累计平均损失: 0.1235
Epoch: 2/2 | Batch: 500/938 | 单Batch损失: 0.0255 | 累计平均损失: 0.1206
Epoch: 2/2 | Batch: 600/938 | 单Batch损失: 0.0688 | 累计平均损失: 0.1193
Epoch: 2/2 | Batch: 700/938 | 单Batch损失: 0.0931 | 累计平均损失: 0.1172
Epoch: 2/2 | Batch: 800/938 | 单Batch损失: 0.1466 | 累计平均损失: 0.1155
Epoch: 2/2 | Batch: 900/938 | 单Batch损失: 0.0907 | 累计平均损失: 0.1141
Epoch 2/2 完成 | 训练准确率: 96.61% | 测试准确率: 96.75%

训练完成!最终测试准确率: 96.75%

在PyTorch中处理张量(Tensor)时,以下是关于展平(Flatten)、维度调整(如view/reshape)等操作的关键点,这些操作通常不会影响第一个维度(即批量维度batch_size):

图像任务中的张量形状

输入张量的形状通常为:
(batch_size, channels, height, width)
例如:(batch_size, 3, 28, 28)
其中,batch_size 代表一次输入的样本数量。

NLP任务中的张量形状

输入张量的形状可能为:
(batch_size, sequence_length)
此时,batch_size 同样是第一个维度。

1. Flatten操作

  • 功能:将张量展平为一维数组,但保留批量维度。
  • 示例
    • 输入形状(batch_size, 3, 28, 28)(图像数据)
    • Flatten后形状(batch_size, 3×28×28) = (batch_size, 2352)
    • 说明:第一个维度batch_size不变,后面的所有维度被展平为一个维度。

2. view/reshape操作

  • 功能:调整张量维度,但必须显式保留或指定批量维度。
  • 示例
    • 输入形状(batch_size, 3, 28, 28)
    • 调整为(batch_size, -1)
    • 结果:展平为两个维度,保留batch_size,第二个维度自动计算为3×28×28=2352

总结

  • 批量维度不变性:无论进行flatten、view还是reshape操作,第一个维度batch_size通常保持不变。
  • 动态维度指定:使用-1让PyTorch自动计算该维度的大小,但需确保其他维度的指定合理,避免形状不匹配错误。

下面是所有代码的整合版本

# import torch
# import torch.nn as nn
# import torch.optim as optim
# from torchvision import datasets, transforms
# from torch.utils.data import DataLoader
# import matplotlib.pyplot as plt
# import numpy as np# # 设置中文字体支持
# plt.rcParams["font.family"] = ["SimHei"]
# plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题# # 1. 数据预处理
# transform = transforms.Compose([
#     transforms.ToTensor(),  # 转换为张量并归一化到[0,1]
#     transforms.Normalize((0.1307,), (0.3081,))  # MNIST数据集的均值和标准差
# ])# # 2. 加载MNIST数据集
# train_dataset = datasets.MNIST(
#     root='./data',
#     train=True,
#     download=True,
#     transform=transform
# )# test_dataset = datasets.MNIST(
#     root='./data',
#     train=False,
#     transform=transform
# )# # 3. 创建数据加载器
# batch_size = 64  # 每批处理64个样本
# train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
# test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# # 4. 定义模型、损失函数和优化器
# class MLP(nn.Module):
#     def __init__(self):
#         super(MLP, self).__init__()
#         self.flatten = nn.Flatten()  # 将28x28的图像展平为784维向量
#         self.layer1 = nn.Linear(784, 128)  # 第一层:784个输入,128个神经元
#         self.relu = nn.ReLU()  # 激活函数
#         self.layer2 = nn.Linear(128, 10)  # 第二层:128个输入,10个输出(对应10个数字类别)#     def forward(self, x):
#         x = self.flatten(x)  # 展平图像
#         x = self.layer1(x)   # 第一层线性变换
#         x = self.relu(x)     # 应用ReLU激活函数
#         x = self.layer2(x)   # 第二层线性变换,输出logits
#         return x# # 检查GPU是否可用
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# # 初始化模型
# model = MLP()
# model = model.to(device)  # 将模型移至GPU(如果可用)# criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数,适用于多分类问题
# optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam优化器# # 5. 训练模型(记录每个 iteration 的损失)
# def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):
#     model.train()  # 设置为训练模式#     # 新增:记录每个 iteration 的损失
#     all_iter_losses = []  # 存储所有 batch 的损失
#     iter_indices = []     # 存储 iteration 序号(从1开始)#     for epoch in range(epochs):
#         running_loss = 0.0
#         correct = 0
#         total = 0#         for batch_idx, (data, target) in enumerate(train_loader):
#             data, target = data.to(device), target.to(device)  # 移至GPU(如果可用)#             optimizer.zero_grad()  # 梯度清零
#             output = model(data)  # 前向传播
#             loss = criterion(output, target)  # 计算损失
#             loss.backward()  # 反向传播
#             optimizer.step()  # 更新参数#             # 记录当前 iteration 的损失(注意:这里直接使用单 batch 损失,而非累加平均)
#             iter_loss = loss.item()
#             all_iter_losses.append(iter_loss)
#             iter_indices.append(epoch * len(train_loader) + batch_idx + 1)  # iteration 序号从1开始#             # 统计准确率和损失(原逻辑保留,用于 epoch 级统计)
#             running_loss += iter_loss
#             _, predicted = output.max(1)
#             total += target.size(0)
#             correct += predicted.eq(target).sum().item()#             # 每100个批次打印一次训练信息(可选:同时打印单 batch 损失)
#             if (batch_idx + 1) % 100 == 0:
#                 print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} '
#                       f'| 单Batch损失: {iter_loss:.4f} | 累计平均损失: {running_loss/(batch_idx+1):.4f}')#         # 原 epoch 级逻辑(测试、打印 epoch 结果)不变
#         epoch_train_loss = running_loss / len(train_loader)
#         epoch_train_acc = 100. * correct / total
#         epoch_test_loss, epoch_test_acc = test(model, test_loader, criterion, device)#         print(f'Epoch {epoch+1}/{epochs} 完成 | 训练准确率: {epoch_train_acc:.2f}% | 测试准确率: {epoch_test_acc:.2f}%')#     # 绘制所有 iteration 的损失曲线
#     plot_iter_losses(all_iter_losses, iter_indices)
#     # 保留原 epoch 级曲线(可选)
#     # plot_metrics(train_losses, test_losses, train_accuracies, test_accuracies, epochs)#     return epoch_test_acc  # 返回最终测试准确率# # 6. 测试模型
# def test(model, test_loader, criterion, device):
#     model.eval()  # 设置为评估模式
#     test_loss = 0
#     correct = 0
#     total = 0#     with torch.no_grad():  # 不计算梯度,节省内存和计算资源
#         for data, target in test_loader:
#             data, target = data.to(device), target.to(device)
#             output = model(data)
#             test_loss += criterion(output, target).item()#             _, predicted = output.max(1)
#             total += target.size(0)
#             correct += predicted.eq(target).sum().item()#     avg_loss = test_loss / len(test_loader)
#     accuracy = 100. * correct / total
#     return avg_loss, accuracy  # 返回损失和准确率# # 7.绘制每个 iteration 的损失曲线
# def plot_iter_losses(losses, indices):
#     plt.figure(figsize=(10, 4))
#     plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')
#     plt.xlabel('Iteration(Batch序号)')
#     plt.ylabel('损失值')
#     plt.title('每个 Iteration 的训练损失')
#     plt.legend()
#     plt.grid(True)
#     plt.tight_layout()
#     plt.show()# # 8. 执行训练和测试(设置 epochs=2 验证效果)
# epochs = 2  
# print("开始训练模型...")
# final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
# print(f"训练完成!最终测试准确率: {final_accuracy:.2f}%")

彩色图片的规范写法

彩色的通道也是在第一步被直接展平,其他代码一致

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np# 设置中文字体支持
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题# 1. 数据预处理
transform = transforms.Compose([transforms.ToTensor(),                # 转换为张量transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # 标准化处理
])# 2. 加载CIFAR-10数据集
train_dataset = datasets.CIFAR10(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.CIFAR10(root='./data',train=False,transform=transform
)# 3. 创建数据加载器
batch_size = 64
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# 4. 定义MLP模型(适应CIFAR-10的输入尺寸)
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 将3x32x32的图像展平为3072维向量self.layer1 = nn.Linear(3072, 512)  # 第一层:3072个输入,512个神经元self.relu1 = nn.ReLU()self.dropout1 = nn.Dropout(0.2)  # 添加Dropout防止过拟合self.layer2 = nn.Linear(512, 256)  # 第二层:512个输入,256个神经元self.relu2 = nn.ReLU()self.dropout2 = nn.Dropout(0.2)self.layer3 = nn.Linear(256, 10)  # 输出层:10个类别def forward(self, x):# 第一步:将输入图像展平为一维向量x = self.flatten(x)  # 输入尺寸: [batch_size, 3, 32, 32] → [batch_size, 3072]# 第一层全连接 + 激活 + Dropoutx = self.layer1(x)   # 线性变换: [batch_size, 3072] → [batch_size, 512]x = self.relu1(x)    # 应用ReLU激活函数x = self.dropout1(x) # 训练时随机丢弃部分神经元输出# 第二层全连接 + 激活 + Dropoutx = self.layer2(x)   # 线性变换: [batch_size, 512] → [batch_size, 256]x = self.relu2(x)    # 应用ReLU激活函数x = self.dropout2(x) # 训练时随机丢弃部分神经元输出# 第三层(输出层)全连接x = self.layer3(x)   # 线性变换: [batch_size, 256] → [batch_size, 10]return x  # 返回未经过Softmax的logits# 检查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 初始化模型
model = MLP()
model = model.to(device)  # 将模型移至GPU(如果可用)criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam优化器# 5. 训练模型(记录每个 iteration 的损失)
def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):model.train()  # 设置为训练模式# 记录每个 iteration 的损失all_iter_losses = []  # 存储所有 batch 的损失iter_indices = []     # 存储 iteration 序号for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)  # 移至GPUoptimizer.zero_grad()  # 梯度清零output = model(data)  # 前向传播loss = criterion(output, target)  # 计算损失loss.backward()  # 反向传播optimizer.step()  # 更新参数# 记录当前 iteration 的损失iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)# 统计准确率和损失running_loss += iter_loss_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()# 每100个批次打印一次训练信息if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 单Batch损失: {iter_loss:.4f} | 累计平均损失: {running_loss/(batch_idx+1):.4f}')# 计算当前epoch的平均训练损失和准确率epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / total# 测试阶段model.eval()  # 设置为评估模式test_loss = 0correct_test = 0total_test = 0with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()_, predicted = output.max(1)total_test += target.size(0)correct_test += predicted.eq(target).sum().item()epoch_test_loss = test_loss / len(test_loader)epoch_test_acc = 100. * correct_test / total_testprint(f'Epoch {epoch+1}/{epochs} 完成 | 训练准确率: {epoch_train_acc:.2f}% | 测试准确率: {epoch_test_acc:.2f}%')# 绘制所有 iteration 的损失曲线plot_iter_losses(all_iter_losses, iter_indices)return epoch_test_acc  # 返回最终测试准确率# 6. 绘制每个 iteration 的损失曲线
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')plt.xlabel('Iteration(Batch序号)')plt.ylabel('损失值')plt.title('每个 Iteration 的训练损失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 7. 执行训练和测试
epochs = 20  # 增加训练轮次以获得更好效果
print("开始训练模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"训练完成!最终测试准确率: {final_accuracy:.2f}%")# # 保存模型
# torch.save(model.state_dict(), 'cifar10_mlp_model.pth')
# # print("模型已保存为: cifar10_mlp_model.pth")
Files already downloaded and verified
开始训练模型...
Epoch: 1/20 | Batch: 100/782 | 单Batch损失: 1.8077 | 累计平均损失: 1.9125
Epoch: 1/20 | Batch: 200/782 | 单Batch损失: 1.6074 | 累计平均损失: 1.8426
Epoch: 1/20 | Batch: 300/782 | 单Batch损失: 1.7398 | 累计平均损失: 1.7997
Epoch: 1/20 | Batch: 400/782 | 单Batch损失: 1.4806 | 累计平均损失: 1.7703
Epoch: 1/20 | Batch: 500/782 | 单Batch损失: 1.4886 | 累计平均损失: 1.7446
Epoch: 1/20 | Batch: 600/782 | 单Batch损失: 1.5184 | 累计平均损失: 1.7276
Epoch: 1/20 | Batch: 700/782 | 单Batch损失: 1.8482 | 累计平均损失: 1.7151
Epoch 1/20 完成 | 训练准确率: 39.43% | 测试准确率: 45.36%
Epoch: 2/20 | Batch: 100/782 | 单Batch损失: 1.3831 | 累计平均损失: 1.4669
Epoch: 2/20 | Batch: 200/782 | 单Batch损失: 1.3637 | 累计平均损失: 1.4693
Epoch: 2/20 | Batch: 300/782 | 单Batch损失: 1.6578 | 累计平均损失: 1.4730
Epoch: 2/20 | Batch: 400/782 | 单Batch损失: 1.5088 | 累计平均损失: 1.4667
Epoch: 2/20 | Batch: 500/782 | 单Batch损失: 1.3744 | 累计平均损失: 1.4660
Epoch: 2/20 | Batch: 600/782 | 单Batch损失: 1.5227 | 累计平均损失: 1.4630
Epoch: 2/20 | Batch: 700/782 | 单Batch损失: 1.5014 | 累计平均损失: 1.4627
Epoch 2/20 完成 | 训练准确率: 48.39% | 测试准确率: 48.32%
Epoch: 3/20 | Batch: 100/782 | 单Batch损失: 1.4056 | 累计平均损失: 1.3430
Epoch: 3/20 | Batch: 200/782 | 单Batch损失: 1.2368 | 累计平均损失: 1.3300
Epoch: 3/20 | Batch: 300/782 | 单Batch损失: 1.3304 | 累计平均损失: 1.3352
Epoch: 3/20 | Batch: 400/782 | 单Batch损失: 1.1077 | 累计平均损失: 1.3407
Epoch: 3/20 | Batch: 500/782 | 单Batch损失: 1.4874 | 累计平均损失: 1.3422
Epoch: 3/20 | Batch: 600/782 | 单Batch损失: 1.2793 | 累计平均损失: 1.3427
Epoch: 3/20 | Batch: 700/782 | 单Batch损失: 1.4587 | 累计平均损失: 1.3447
Epoch 3/20 完成 | 训练准确率: 52.55% | 测试准确率: 51.32%
Epoch: 4/20 | Batch: 100/782 | 单Batch损失: 1.1435 | 累计平均损失: 1.2318
Epoch: 4/20 | Batch: 200/782 | 单Batch损失: 1.5731 | 累计平均损失: 1.2438
Epoch: 4/20 | Batch: 300/782 | 单Batch损失: 1.4256 | 累计平均损失: 1.2434
Epoch: 4/20 | Batch: 400/782 | 单Batch损失: 1.2422 | 累计平均损失: 1.2464
Epoch: 4/20 | Batch: 500/782 | 单Batch损失: 1.4303 | 累计平均损失: 1.2481
Epoch: 4/20 | Batch: 600/782 | 单Batch损失: 1.3966 | 累计平均损失: 1.2501
Epoch: 4/20 | Batch: 700/782 | 单Batch损失: 1.2377 | 累计平均损失: 1.2546
Epoch 4/20 完成 | 训练准确率: 55.44% | 测试准确率: 50.58%
Epoch: 5/20 | Batch: 100/782 | 单Batch损失: 1.2511 | 累计平均损失: 1.1545
Epoch: 5/20 | Batch: 200/782 | 单Batch损失: 1.2885 | 累计平均损失: 1.1576
Epoch: 5/20 | Batch: 300/782 | 单Batch损失: 1.2130 | 累计平均损失: 1.1667
Epoch: 5/20 | Batch: 400/782 | 单Batch损失: 1.0851 | 累计平均损失: 1.1684
Epoch: 5/20 | Batch: 500/782 | 单Batch损失: 1.3902 | 累计平均损失: 1.1675
Epoch: 5/20 | Batch: 600/782 | 单Batch损失: 1.2293 | 累计平均损失: 1.1661
Epoch: 5/20 | Batch: 700/782 | 单Batch损失: 1.0104 | 累计平均损失: 1.1667
Epoch 5/20 完成 | 训练准确率: 58.58% | 测试准确率: 52.33%
Epoch: 6/20 | Batch: 100/782 | 单Batch损失: 1.1741 | 累计平均损失: 1.0360
Epoch: 6/20 | Batch: 200/782 | 单Batch损失: 1.0454 | 累计平均损失: 1.0492
Epoch: 6/20 | Batch: 300/782 | 单Batch损失: 1.0181 | 累计平均损失: 1.0601
Epoch: 6/20 | Batch: 400/782 | 单Batch损失: 0.9719 | 累计平均损失: 1.0674
Epoch: 6/20 | Batch: 500/782 | 单Batch损失: 0.8914 | 累计平均损失: 1.0724
Epoch: 6/20 | Batch: 600/782 | 单Batch损失: 1.0058 | 累计平均损失: 1.0798
Epoch: 6/20 | Batch: 700/782 | 单Batch损失: 1.0079 | 累计平均损失: 1.0847
Epoch 6/20 完成 | 训练准确率: 61.29% | 测试准确率: 52.42%
Epoch: 7/20 | Batch: 100/782 | 单Batch损失: 0.9277 | 累计平均损失: 0.9729
Epoch: 7/20 | Batch: 200/782 | 单Batch损失: 0.9453 | 累计平均损失: 0.9867
Epoch: 7/20 | Batch: 300/782 | 单Batch损失: 1.1329 | 累计平均损失: 0.9957
Epoch: 7/20 | Batch: 400/782 | 单Batch损失: 1.1643 | 累计平均损失: 1.0029
Epoch: 7/20 | Batch: 500/782 | 单Batch损失: 1.0009 | 累计平均损失: 1.0036
Epoch: 7/20 | Batch: 600/782 | 单Batch损失: 1.0897 | 累计平均损失: 1.0105
Epoch: 7/20 | Batch: 700/782 | 单Batch损失: 0.9353 | 累计平均损失: 1.0122
Epoch 7/20 完成 | 训练准确率: 63.83% | 测试准确率: 53.23%
Epoch: 8/20 | Batch: 100/782 | 单Batch损失: 0.8126 | 累计平均损失: 0.9025
Epoch: 8/20 | Batch: 200/782 | 单Batch损失: 0.9867 | 累计平均损失: 0.8911
Epoch: 8/20 | Batch: 300/782 | 单Batch损失: 0.6664 | 累计平均损失: 0.8952
Epoch: 8/20 | Batch: 400/782 | 单Batch损失: 0.9331 | 累计平均损失: 0.9083
Epoch: 8/20 | Batch: 500/782 | 单Batch损失: 0.7988 | 累计平均损失: 0.9170
Epoch: 8/20 | Batch: 600/782 | 单Batch损失: 0.8833 | 累计平均损失: 0.9276
Epoch: 8/20 | Batch: 700/782 | 单Batch损失: 0.8107 | 累计平均损失: 0.9361
Epoch 8/20 完成 | 训练准确率: 66.29% | 测试准确率: 52.69%
Epoch: 9/20 | Batch: 100/782 | 单Batch损失: 0.9422 | 累计平均损失: 0.8223
Epoch: 9/20 | Batch: 200/782 | 单Batch损失: 1.1191 | 累计平均损失: 0.8260
Epoch: 9/20 | Batch: 300/782 | 单Batch损失: 0.8772 | 累计平均损失: 0.8303
Epoch: 9/20 | Batch: 400/782 | 单Batch损失: 1.0643 | 累计平均损失: 0.8424
Epoch: 9/20 | Batch: 500/782 | 单Batch损失: 0.9481 | 累计平均损失: 0.8482
Epoch: 9/20 | Batch: 600/782 | 单Batch损失: 1.1955 | 累计平均损失: 0.8581
Epoch: 9/20 | Batch: 700/782 | 单Batch损失: 0.8107 | 累计平均损失: 0.8622
Epoch 9/20 完成 | 训练准确率: 68.85% | 测试准确率: 52.10%
Epoch: 10/20 | Batch: 100/782 | 单Batch损失: 0.9278 | 累计平均损失: 0.7558
Epoch: 10/20 | Batch: 200/782 | 单Batch损失: 0.6106 | 累计平均损失: 0.7595
Epoch: 10/20 | Batch: 300/782 | 单Batch损失: 0.8664 | 累计平均损失: 0.7670
Epoch: 10/20 | Batch: 400/782 | 单Batch损失: 0.8446 | 累计平均损失: 0.7708
Epoch: 10/20 | Batch: 500/782 | 单Batch损失: 0.9738 | 累计平均损失: 0.7790
Epoch: 10/20 | Batch: 600/782 | 单Batch损失: 0.9130 | 累计平均损失: 0.7867
Epoch: 10/20 | Batch: 700/782 | 单Batch损失: 0.9078 | 累计平均损失: 0.7936
Epoch 10/20 完成 | 训练准确率: 71.38% | 测试准确率: 53.01%
Epoch: 11/20 | Batch: 100/782 | 单Batch损失: 0.6402 | 累计平均损失: 0.6871
Epoch: 11/20 | Batch: 200/782 | 单Batch损失: 0.7935 | 累计平均损失: 0.6893
Epoch: 11/20 | Batch: 300/782 | 单Batch损失: 0.7513 | 累计平均损失: 0.7026
Epoch: 11/20 | Batch: 400/782 | 单Batch损失: 0.9429 | 累计平均损失: 0.7153
Epoch: 11/20 | Batch: 500/782 | 单Batch损失: 0.6525 | 累计平均损失: 0.7219
Epoch: 11/20 | Batch: 600/782 | 单Batch损失: 0.9268 | 累计平均损失: 0.7307
Epoch: 11/20 | Batch: 700/782 | 单Batch损失: 0.5548 | 累计平均损失: 0.7340
Epoch 11/20 完成 | 训练准确率: 73.44% | 测试准确率: 52.51%
Epoch: 12/20 | Batch: 100/782 | 单Batch损失: 0.6176 | 累计平均损失: 0.6142
Epoch: 12/20 | Batch: 200/782 | 单Batch损失: 0.7543 | 累计平均损失: 0.6335
Epoch: 12/20 | Batch: 300/782 | 单Batch损失: 0.6295 | 累计平均损失: 0.6461
Epoch: 12/20 | Batch: 400/782 | 单Batch损失: 0.4608 | 累计平均损失: 0.6533
Epoch: 12/20 | Batch: 500/782 | 单Batch损失: 0.5611 | 累计平均损失: 0.6661
Epoch: 12/20 | Batch: 600/782 | 单Batch损失: 0.6843 | 累计平均损失: 0.6729
Epoch: 12/20 | Batch: 700/782 | 单Batch损失: 0.7903 | 累计平均损失: 0.6799
Epoch 12/20 完成 | 训练准确率: 75.67% | 测试准确率: 52.23%
Epoch: 13/20 | Batch: 100/782 | 单Batch损失: 0.5043 | 累计平均损失: 0.5892
Epoch: 13/20 | Batch: 200/782 | 单Batch损失: 0.5915 | 累计平均损失: 0.5744
Epoch: 13/20 | Batch: 300/782 | 单Batch损失: 0.3866 | 累计平均损失: 0.5840
Epoch: 13/20 | Batch: 400/782 | 单Batch损失: 0.6512 | 累计平均损失: 0.5927
Epoch: 13/20 | Batch: 500/782 | 单Batch损失: 0.5521 | 累计平均损失: 0.5985
Epoch: 13/20 | Batch: 600/782 | 单Batch损失: 0.6899 | 累计平均损失: 0.6081
Epoch: 13/20 | Batch: 700/782 | 单Batch损失: 1.0226 | 累计平均损失: 0.6168
Epoch 13/20 完成 | 训练准确率: 77.94% | 测试准确率: 53.61%
Epoch: 14/20 | Batch: 100/782 | 单Batch损失: 0.2617 | 累计平均损失: 0.5374
Epoch: 14/20 | Batch: 200/782 | 单Batch损失: 0.5938 | 累计平均损失: 0.5367
Epoch: 14/20 | Batch: 300/782 | 单Batch损失: 0.5605 | 累计平均损失: 0.5378
Epoch: 14/20 | Batch: 400/782 | 单Batch损失: 0.5295 | 累计平均损失: 0.5479
Epoch: 14/20 | Batch: 500/782 | 单Batch损失: 0.6355 | 累计平均损失: 0.5599
Epoch: 14/20 | Batch: 600/782 | 单Batch损失: 0.5767 | 累计平均损失: 0.5648
Epoch: 14/20 | Batch: 700/782 | 单Batch损失: 0.7111 | 累计平均损失: 0.5717
Epoch 14/20 完成 | 训练准确率: 79.35% | 测试准确率: 52.69%
Epoch: 15/20 | Batch: 100/782 | 单Batch损失: 0.2707 | 累计平均损失: 0.4779
Epoch: 15/20 | Batch: 200/782 | 单Batch损失: 0.2778 | 累计平均损失: 0.4865
Epoch: 15/20 | Batch: 300/782 | 单Batch损失: 0.5449 | 累计平均损失: 0.4968
Epoch: 15/20 | Batch: 400/782 | 单Batch损失: 0.6294 | 累计平均损失: 0.5017
Epoch: 15/20 | Batch: 500/782 | 单Batch损失: 0.5366 | 累计平均损失: 0.5080
Epoch: 15/20 | Batch: 600/782 | 单Batch损失: 0.4407 | 累计平均损失: 0.5174
Epoch: 15/20 | Batch: 700/782 | 单Batch损失: 0.6451 | 累计平均损失: 0.5253
Epoch 15/20 完成 | 训练准确率: 81.06% | 测试准确率: 52.64%
Epoch: 16/20 | Batch: 100/782 | 单Batch损失: 0.6881 | 累计平均损失: 0.4451
Epoch: 16/20 | Batch: 200/782 | 单Batch损失: 0.4996 | 累计平均损失: 0.4471
Epoch: 16/20 | Batch: 300/782 | 单Batch损失: 0.5469 | 累计平均损失: 0.4607
Epoch: 16/20 | Batch: 400/782 | 单Batch损失: 0.6781 | 累计平均损失: 0.4733
Epoch: 16/20 | Batch: 500/782 | 单Batch损失: 0.7900 | 累计平均损失: 0.4838
Epoch: 16/20 | Batch: 600/782 | 单Batch损失: 0.5282 | 累计平均损失: 0.4880
Epoch: 16/20 | Batch: 700/782 | 单Batch损失: 0.5217 | 累计平均损失: 0.4942
Epoch 16/20 完成 | 训练准确率: 82.15% | 测试准确率: 52.63%
Epoch: 17/20 | Batch: 100/782 | 单Batch损失: 0.5320 | 累计平均损失: 0.4118
Epoch: 17/20 | Batch: 200/782 | 单Batch损失: 0.4442 | 累计平均损失: 0.4162
Epoch: 17/20 | Batch: 300/782 | 单Batch损失: 0.4952 | 累计平均损失: 0.4249
Epoch: 17/20 | Batch: 400/782 | 单Batch损失: 0.4195 | 累计平均损失: 0.4342
Epoch: 17/20 | Batch: 500/782 | 单Batch损失: 0.4573 | 累计平均损失: 0.4453
Epoch: 17/20 | Batch: 600/782 | 单Batch损失: 0.4631 | 累计平均损失: 0.4515
Epoch: 17/20 | Batch: 700/782 | 单Batch损失: 0.4552 | 累计平均损失: 0.4575
Epoch 17/20 完成 | 训练准确率: 83.55% | 测试准确率: 52.80%
Epoch: 18/20 | Batch: 100/782 | 单Batch损失: 0.2212 | 累计平均损失: 0.3911
Epoch: 18/20 | Batch: 200/782 | 单Batch损失: 0.3049 | 累计平均损失: 0.3895
Epoch: 18/20 | Batch: 300/782 | 单Batch损失: 0.4986 | 累计平均损失: 0.4007
Epoch: 18/20 | Batch: 400/782 | 单Batch损失: 0.3962 | 累计平均损失: 0.4075
Epoch: 18/20 | Batch: 500/782 | 单Batch损失: 0.4092 | 累计平均损失: 0.4159
Epoch: 18/20 | Batch: 600/782 | 单Batch损失: 0.3700 | 累计平均损失: 0.4233
Epoch: 18/20 | Batch: 700/782 | 单Batch损失: 0.4538 | 累计平均损失: 0.4323
Epoch 18/20 完成 | 训练准确率: 84.28% | 测试准确率: 51.88%
Epoch: 19/20 | Batch: 100/782 | 单Batch损失: 0.3703 | 累计平均损失: 0.3645
Epoch: 19/20 | Batch: 200/782 | 单Batch损失: 0.4807 | 累计平均损失: 0.3642
Epoch: 19/20 | Batch: 300/782 | 单Batch损失: 0.4501 | 累计平均损失: 0.3684
Epoch: 19/20 | Batch: 400/782 | 单Batch损失: 0.3209 | 累计平均损失: 0.3812
Epoch: 19/20 | Batch: 500/782 | 单Batch损失: 0.5543 | 累计平均损失: 0.3870
Epoch: 19/20 | Batch: 600/782 | 单Batch损失: 0.4586 | 累计平均损失: 0.3935
Epoch: 19/20 | Batch: 700/782 | 单Batch损失: 0.5588 | 累计平均损失: 0.3997
Epoch 19/20 完成 | 训练准确率: 85.71% | 测试准确率: 53.66%
Epoch: 20/20 | Batch: 100/782 | 单Batch损失: 0.4661 | 累计平均损失: 0.3689
Epoch: 20/20 | Batch: 200/782 | 单Batch损失: 0.3074 | 累计平均损失: 0.3479
Epoch: 20/20 | Batch: 300/782 | 单Batch损失: 0.3794 | 累计平均损失: 0.3492
Epoch: 20/20 | Batch: 400/782 | 单Batch损失: 0.3515 | 累计平均损失: 0.3652
Epoch: 20/20 | Batch: 500/782 | 单Batch损失: 0.2618 | 累计平均损失: 0.3697
Epoch: 20/20 | Batch: 600/782 | 单Batch损失: 0.2653 | 累计平均损失: 0.3773
Epoch: 20/20 | Batch: 700/782 | 单Batch损失: 0.5042 | 累计平均损失: 0.3846
Epoch 20/20 完成 | 训练准确率: 86.15% | 测试准确率: 51.59%

训练完成!最终测试准确率: 51.59%

由于深度mlp的参数过多,为了避免过拟合在这里引入了dropout这个操作,他可以在训练阶段随机丢弃一些神经元,避免过拟合情况。dropout的取值也是超参数。

在测试阶段,由于开启了eval模式,会自动关闭dropout。

可以继续调用这个函数来复用

# 7. 执行训练和测试
epochs = 20  # 增加训练轮次以获得更好效果
print("开始训练模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"训练完成!最终测试准确率: {final_accuracy:.2f}%")
开始训练模型...
Epoch: 1/20 | Batch: 100/782 | 单Batch损失: 1.4619 | 累计平均损失: 1.3271
Epoch: 1/20 | Batch: 200/782 | 单Batch损失: 1.2312 | 累计平均损失: 1.2557
Epoch: 1/20 | Batch: 300/782 | 单Batch损失: 1.1511 | 累计平均损失: 1.2159
Epoch: 1/20 | Batch: 400/782 | 单Batch损失: 0.9654 | 累计平均损失: 1.1774
Epoch: 1/20 | Batch: 500/782 | 单Batch损失: 1.2084 | 累计平均损失: 1.1537
Epoch: 1/20 | Batch: 600/782 | 单Batch损失: 1.2039 | 累计平均损失: 1.1260
Epoch: 1/20 | Batch: 700/782 | 单Batch损失: 1.0381 | 累计平均损失: 1.1123
Epoch 1/20 完成 | 训练准确率: 63.63% | 测试准确率: 52.61%
Epoch: 2/20 | Batch: 100/782 | 单Batch损失: 0.3717 | 累计平均损失: 0.4796
Epoch: 2/20 | Batch: 200/782 | 单Batch损失: 0.3691 | 累计平均损失: 0.4380
Epoch: 2/20 | Batch: 300/782 | 单Batch损失: 0.3134 | 累计平均损失: 0.4115
Epoch: 2/20 | Batch: 400/782 | 单Batch损失: 0.3479 | 累计平均损失: 0.3937
Epoch: 2/20 | Batch: 500/782 | 单Batch损失: 0.3160 | 累计平均损失: 0.3820
Epoch: 2/20 | Batch: 600/782 | 单Batch损失: 0.4037 | 累计平均损失: 0.3761
Epoch: 2/20 | Batch: 700/782 | 单Batch损失: 0.4130 | 累计平均损失: 0.3708
Epoch 2/20 完成 | 训练准确率: 87.23% | 测试准确率: 53.91%
Epoch: 3/20 | Batch: 100/782 | 单Batch损失: 0.3526 | 累计平均损失: 0.2483
Epoch: 3/20 | Batch: 200/782 | 单Batch损失: 0.4958 | 累计平均损失: 0.2644
Epoch: 3/20 | Batch: 300/782 | 单Batch损失: 0.2418 | 累计平均损失: 0.2742
Epoch: 3/20 | Batch: 400/782 | 单Batch损失: 0.2887 | 累计平均损失: 0.2823
Epoch: 3/20 | Batch: 500/782 | 单Batch损失: 0.2651 | 累计平均损失: 0.2902
Epoch: 3/20 | Batch: 600/782 | 单Batch损失: 0.4208 | 累计平均损失: 0.2969
Epoch: 3/20 | Batch: 700/782 | 单Batch损失: 0.5297 | 累计平均损失: 0.3066
Epoch 3/20 完成 | 训练准确率: 88.99% | 测试准确率: 52.74%
Epoch: 4/20 | Batch: 100/782 | 单Batch损失: 0.2994 | 累计平均损失: 0.3053
Epoch: 4/20 | Batch: 200/782 | 单Batch损失: 0.2492 | 累计平均损失: 0.2865
Epoch: 4/20 | Batch: 300/782 | 单Batch损失: 0.2671 | 累计平均损失: 0.2934
Epoch: 4/20 | Batch: 400/782 | 单Batch损失: 0.3402 | 累计平均损失: 0.3009
Epoch: 4/20 | Batch: 500/782 | 单Batch损失: 0.3917 | 累计平均损失: 0.3101
Epoch: 4/20 | Batch: 600/782 | 单Batch损失: 0.3708 | 累计平均损失: 0.3226
Epoch: 4/20 | Batch: 700/782 | 单Batch损失: 0.4512 | 累计平均损失: 0.3286
Epoch 4/20 完成 | 训练准确率: 88.29% | 测试准确率: 52.30%
Epoch: 5/20 | Batch: 100/782 | 单Batch损失: 0.3248 | 累计平均损失: 0.2962
Epoch: 5/20 | Batch: 200/782 | 单Batch损失: 0.4970 | 累计平均损失: 0.2960
Epoch: 5/20 | Batch: 300/782 | 单Batch损失: 0.2850 | 累计平均损失: 0.3082
Epoch: 5/20 | Batch: 400/782 | 单Batch损失: 0.3529 | 累计平均损失: 0.3095
Epoch: 5/20 | Batch: 500/782 | 单Batch损失: 0.2250 | 累计平均损失: 0.3100
Epoch: 5/20 | Batch: 600/782 | 单Batch损失: 0.4958 | 累计平均损失: 0.3149
Epoch: 5/20 | Batch: 700/782 | 单Batch损失: 0.2408 | 累计平均损失: 0.3193
Epoch 5/20 完成 | 训练准确率: 88.60% | 测试准确率: 53.02%
Epoch: 6/20 | Batch: 100/782 | 单Batch损失: 0.1920 | 累计平均损失: 0.3102
Epoch: 6/20 | Batch: 200/782 | 单Batch损失: 0.1668 | 累计平均损失: 0.3053
Epoch: 6/20 | Batch: 300/782 | 单Batch损失: 0.1788 | 累计平均损失: 0.2953
Epoch: 6/20 | Batch: 400/782 | 单Batch损失: 0.4075 | 累计平均损失: 0.2948
Epoch: 6/20 | Batch: 500/782 | 单Batch损失: 0.2510 | 累计平均损失: 0.2947
Epoch: 6/20 | Batch: 600/782 | 单Batch损失: 0.2050 | 累计平均损失: 0.2986
Epoch: 6/20 | Batch: 700/782 | 单Batch损失: 0.5312 | 累计平均损失: 0.3033
Epoch 6/20 完成 | 训练准确率: 89.10% | 测试准确率: 53.53%
Epoch: 7/20 | Batch: 100/782 | 单Batch损失: 0.2166 | 累计平均损失: 0.2619
Epoch: 7/20 | Batch: 200/782 | 单Batch损失: 0.3512 | 累计平均损失: 0.2687
Epoch: 7/20 | Batch: 300/782 | 单Batch损失: 0.3647 | 累计平均损失: 0.2775
Epoch: 7/20 | Batch: 400/782 | 单Batch损失: 0.2889 | 累计平均损失: 0.2813
Epoch: 7/20 | Batch: 500/782 | 单Batch损失: 0.2479 | 累计平均损失: 0.2866
Epoch: 7/20 | Batch: 600/782 | 单Batch损失: 0.4674 | 累计平均损失: 0.2940
Epoch: 7/20 | Batch: 700/782 | 单Batch损失: 0.4617 | 累计平均损失: 0.3015
Epoch 7/20 完成 | 训练准确率: 89.66% | 测试准确率: 52.66%
Epoch: 8/20 | Batch: 100/782 | 单Batch损失: 0.2086 | 累计平均损失: 0.2536
Epoch: 8/20 | Batch: 200/782 | 单Batch损失: 0.2134 | 累计平均损失: 0.2535
Epoch: 8/20 | Batch: 300/782 | 单Batch损失: 0.2565 | 累计平均损失: 0.2543
Epoch: 8/20 | Batch: 400/782 | 单Batch损失: 0.3714 | 累计平均损失: 0.2594
Epoch: 8/20 | Batch: 500/782 | 单Batch损失: 0.2150 | 累计平均损失: 0.2643
Epoch: 8/20 | Batch: 600/782 | 单Batch损失: 0.2809 | 累计平均损失: 0.2691
Epoch: 8/20 | Batch: 700/782 | 单Batch损失: 0.4545 | 累计平均损失: 0.2740
Epoch 8/20 完成 | 训练准确率: 90.25% | 测试准确率: 51.92%
Epoch: 9/20 | Batch: 100/782 | 单Batch损失: 0.2487 | 累计平均损失: 0.2876
Epoch: 9/20 | Batch: 200/782 | 单Batch损失: 0.1357 | 累计平均损失: 0.2653
Epoch: 9/20 | Batch: 300/782 | 单Batch损失: 0.0931 | 累计平均损失: 0.2680
Epoch: 9/20 | Batch: 400/782 | 单Batch损失: 0.4563 | 累计平均损失: 0.2739
Epoch: 9/20 | Batch: 500/782 | 单Batch损失: 0.3293 | 累计平均损失: 0.2761
Epoch: 9/20 | Batch: 600/782 | 单Batch损失: 0.3813 | 累计平均损失: 0.2745
Epoch: 9/20 | Batch: 700/782 | 单Batch损失: 0.2299 | 累计平均损失: 0.2751
Epoch 9/20 完成 | 训练准确率: 90.42% | 测试准确率: 53.40%
Epoch: 10/20 | Batch: 100/782 | 单Batch损失: 0.2981 | 累计平均损失: 0.3056
Epoch: 10/20 | Batch: 200/782 | 单Batch损失: 0.2199 | 累计平均损失: 0.2931
Epoch: 10/20 | Batch: 300/782 | 单Batch损失: 0.3375 | 累计平均损失: 0.2854
Epoch: 10/20 | Batch: 400/782 | 单Batch损失: 0.4397 | 累计平均损失: 0.2812
Epoch: 10/20 | Batch: 500/782 | 单Batch损失: 0.3059 | 累计平均损失: 0.2805
Epoch: 10/20 | Batch: 600/782 | 单Batch损失: 0.3160 | 累计平均损失: 0.2858
Epoch: 10/20 | Batch: 700/782 | 单Batch损失: 0.5194 | 累计平均损失: 0.2853
Epoch 10/20 完成 | 训练准确率: 89.89% | 测试准确率: 51.50%
Epoch: 11/20 | Batch: 100/782 | 单Batch损失: 0.1122 | 累计平均损失: 0.2332
Epoch: 11/20 | Batch: 200/782 | 单Batch损失: 0.1647 | 累计平均损失: 0.2357
Epoch: 11/20 | Batch: 300/782 | 单Batch损失: 0.2570 | 累计平均损失: 0.2366
Epoch: 11/20 | Batch: 400/782 | 单Batch损失: 0.3052 | 累计平均损失: 0.2416
Epoch: 11/20 | Batch: 500/782 | 单Batch损失: 0.3760 | 累计平均损失: 0.2417
Epoch: 11/20 | Batch: 600/782 | 单Batch损失: 0.1941 | 累计平均损失: 0.2495
Epoch: 11/20 | Batch: 700/782 | 单Batch损失: 0.4851 | 累计平均损失: 0.2567
Epoch 11/20 完成 | 训练准确率: 90.94% | 测试准确率: 51.46%
Epoch: 12/20 | Batch: 100/782 | 单Batch损失: 0.3288 | 累计平均损失: 0.2309
Epoch: 12/20 | Batch: 200/782 | 单Batch损失: 0.1121 | 累计平均损失: 0.2223
Epoch: 12/20 | Batch: 300/782 | 单Batch损失: 0.1995 | 累计平均损失: 0.2247
Epoch: 12/20 | Batch: 400/782 | 单Batch损失: 0.4753 | 累计平均损失: 0.2275
Epoch: 12/20 | Batch: 500/782 | 单Batch损失: 0.1604 | 累计平均损失: 0.2325
Epoch: 12/20 | Batch: 600/782 | 单Batch损失: 0.2429 | 累计平均损失: 0.2387
Epoch: 12/20 | Batch: 700/782 | 单Batch损失: 0.1945 | 累计平均损失: 0.2423
Epoch 12/20 完成 | 训练准确率: 91.41% | 测试准确率: 51.64%
Epoch: 13/20 | Batch: 100/782 | 单Batch损失: 0.1330 | 累计平均损失: 0.2135
Epoch: 13/20 | Batch: 200/782 | 单Batch损失: 0.2700 | 累计平均损失: 0.2220
Epoch: 13/20 | Batch: 300/782 | 单Batch损失: 0.1553 | 累计平均损失: 0.2316
Epoch: 13/20 | Batch: 400/782 | 单Batch损失: 0.2453 | 累计平均损失: 0.2330
Epoch: 13/20 | Batch: 500/782 | 单Batch损失: 0.2094 | 累计平均损失: 0.2330
Epoch: 13/20 | Batch: 600/782 | 单Batch损失: 0.1698 | 累计平均损失: 0.2354
Epoch: 13/20 | Batch: 700/782 | 单Batch损失: 0.2484 | 累计平均损失: 0.2391
Epoch 13/20 完成 | 训练准确率: 91.62% | 测试准确率: 51.57%
Epoch: 14/20 | Batch: 100/782 | 单Batch损失: 0.1442 | 累计平均损失: 0.2536
Epoch: 14/20 | Batch: 200/782 | 单Batch损失: 0.1760 | 累计平均损失: 0.2478
Epoch: 14/20 | Batch: 300/782 | 单Batch损失: 0.2174 | 累计平均损失: 0.2547
Epoch: 14/20 | Batch: 400/782 | 单Batch损失: 0.3635 | 累计平均损失: 0.2534
Epoch: 14/20 | Batch: 500/782 | 单Batch损失: 0.2063 | 累计平均损失: 0.2497
Epoch: 14/20 | Batch: 600/782 | 单Batch损失: 0.2849 | 累计平均损失: 0.2500
Epoch: 14/20 | Batch: 700/782 | 单Batch损失: 0.1911 | 累计平均损失: 0.2522
Epoch 14/20 完成 | 训练准确率: 91.26% | 测试准确率: 52.80%
Epoch: 15/20 | Batch: 100/782 | 单Batch损失: 0.2775 | 累计平均损失: 0.2189
Epoch: 15/20 | Batch: 200/782 | 单Batch损失: 0.2573 | 累计平均损失: 0.2218
Epoch: 15/20 | Batch: 300/782 | 单Batch损失: 0.2027 | 累计平均损失: 0.2130
Epoch: 15/20 | Batch: 400/782 | 单Batch损失: 0.1956 | 累计平均损失: 0.2087
Epoch: 15/20 | Batch: 500/782 | 单Batch损失: 0.2585 | 累计平均损失: 0.2122
Epoch: 15/20 | Batch: 600/782 | 单Batch损失: 0.1852 | 累计平均损失: 0.2188
Epoch: 15/20 | Batch: 700/782 | 单Batch损失: 0.4187 | 累计平均损失: 0.2222
Epoch 15/20 完成 | 训练准确率: 92.24% | 测试准确率: 52.62%
Epoch: 16/20 | Batch: 100/782 | 单Batch损失: 0.1929 | 累计平均损失: 0.1914
Epoch: 16/20 | Batch: 200/782 | 单Batch损失: 0.1501 | 累计平均损失: 0.2000
Epoch: 16/20 | Batch: 300/782 | 单Batch损失: 0.2517 | 累计平均损失: 0.2124
Epoch: 16/20 | Batch: 400/782 | 单Batch损失: 0.3234 | 累计平均损失: 0.2209
Epoch: 16/20 | Batch: 500/782 | 单Batch损失: 0.4349 | 累计平均损失: 0.2273
Epoch: 16/20 | Batch: 600/782 | 单Batch损失: 0.2599 | 累计平均损失: 0.2312
Epoch: 16/20 | Batch: 700/782 | 单Batch损失: 0.3407 | 累计平均损失: 0.2351
Epoch 16/20 完成 | 训练准确率: 91.92% | 测试准确率: 52.44%
Epoch: 17/20 | Batch: 100/782 | 单Batch损失: 0.2697 | 累计平均损失: 0.1811
Epoch: 17/20 | Batch: 200/782 | 单Batch损失: 0.1481 | 累计平均损失: 0.1882
Epoch: 17/20 | Batch: 300/782 | 单Batch损失: 0.1005 | 累计平均损失: 0.1928
Epoch: 17/20 | Batch: 400/782 | 单Batch损失: 0.1714 | 累计平均损失: 0.2004
Epoch: 17/20 | Batch: 500/782 | 单Batch损失: 0.4656 | 累计平均损失: 0.2105
Epoch: 17/20 | Batch: 600/782 | 单Batch损失: 0.1378 | 累计平均损失: 0.2238
Epoch: 17/20 | Batch: 700/782 | 单Batch损失: 0.2795 | 累计平均损失: 0.2320
Epoch 17/20 完成 | 训练准确率: 92.09% | 测试准确率: 52.45%
Epoch: 18/20 | Batch: 100/782 | 单Batch损失: 0.1461 | 累计平均损失: 0.2036
Epoch: 18/20 | Batch: 200/782 | 单Batch损失: 0.3390 | 累计平均损失: 0.1922
Epoch: 18/20 | Batch: 300/782 | 单Batch损失: 0.2414 | 累计平均损失: 0.1944
Epoch: 18/20 | Batch: 400/782 | 单Batch损失: 0.2051 | 累计平均损失: 0.1900
Epoch: 18/20 | Batch: 500/782 | 单Batch损失: 0.2092 | 累计平均损失: 0.1928
Epoch: 18/20 | Batch: 600/782 | 单Batch损失: 0.1721 | 累计平均损失: 0.1985
Epoch: 18/20 | Batch: 700/782 | 单Batch损失: 0.3793 | 累计平均损失: 0.2071
Epoch 18/20 完成 | 训练准确率: 92.82% | 测试准确率: 52.33%
Epoch: 19/20 | Batch: 100/782 | 单Batch损失: 0.2564 | 累计平均损失: 0.1907
Epoch: 19/20 | Batch: 200/782 | 单Batch损失: 0.1887 | 累计平均损失: 0.1978
Epoch: 19/20 | Batch: 300/782 | 单Batch损失: 0.1175 | 累计平均损失: 0.1953
Epoch: 19/20 | Batch: 400/782 | 单Batch损失: 0.3717 | 累计平均损失: 0.1998
Epoch: 19/20 | Batch: 500/782 | 单Batch损失: 0.2294 | 累计平均损失: 0.2066
Epoch: 19/20 | Batch: 600/782 | 单Batch损失: 0.1868 | 累计平均损失: 0.2067
Epoch: 19/20 | Batch: 700/782 | 单Batch损失: 0.1615 | 累计平均损失: 0.2114
Epoch 19/20 完成 | 训练准确率: 92.69% | 测试准确率: 52.46%
Epoch: 20/20 | Batch: 100/782 | 单Batch损失: 0.2190 | 累计平均损失: 0.2338
Epoch: 20/20 | Batch: 200/782 | 单Batch损失: 0.1818 | 累计平均损失: 0.2232
Epoch: 20/20 | Batch: 300/782 | 单Batch损失: 0.1221 | 累计平均损失: 0.2194
Epoch: 20/20 | Batch: 400/782 | 单Batch损失: 0.3309 | 累计平均损失: 0.2235
Epoch: 20/20 | Batch: 500/782 | 单Batch损失: 0.3291 | 累计平均损失: 0.2262
Epoch: 20/20 | Batch: 600/782 | 单Batch损失: 0.3049 | 累计平均损失: 0.2267
Epoch: 20/20 | Batch: 700/782 | 单Batch损失: 0.2965 | 累计平均损失: 0.2274
Epoch 20/20 完成 | 训练准确率: 92.31% | 测试准确率: 52.40%

训练完成!最终测试准确率: 52.40%

此时你会发现MLP(多层感知机)在图像任务上表现较差(即使增加深度和轮次也只能达到 50-55% 准确率),主要原因与图像数据的空间特性和MLP 的结构缺陷密切相关。

  1. MLP 的每一层都是全连接层,输入图像会被展平为一维向量(如 CIFAR-10 的 32x32x3 图像展平为 3072 维向量)。图像中相邻像素通常具有强相关性(如边缘、纹理),但 MLP 将所有像素视为独立特征,无法利用局部空间结构。例如,识别 “汽车轮胎” 需要邻近像素的组合信息,而 MLP 需通过大量参数单独学习每个像素的关联,效率极低。
  2. 深层 MLP 的参数规模呈指数级增长,容易过拟合

所以我们接下来将会学习CNN架构,CNN架构的参数规模相对较小,且训练速度更快,而且CNN架构可以解决图像识别问题,而MLP不能。 浙大疏锦行


http://www.hkcw.cn/article/augipXncJO.shtml

相关文章

2022-2023-2-移动机器人设计与实践-期末B

2022-2023-2-移动机器人设计与实践-期末A-CSDN博客 本文介绍了《移动机器人设计与实践》课程期末考试试卷B卷的内容与参考答案。试卷包含分析题、设计题、实践题和编程题四部分,总分100分。分析题考察学生对空中、水面和地上三种移动机器人模型运动机制及应用场景的…

DM8部分函数的功能分别举例说明

DM8部分函数的功能分别举例说明 1 环境说明2 函数功能使用示例2.1 AVG OVER2.2 COUNT OVER2.3 MIN OVER,MAX OVER,SUM OVER2.4 DENSE_RANK2.5 ROW_NUMBER2.6 FIRST2.7 LAG2.8 WM_CONCAT 3 更多达梦数据库全方位指南:安装 优化 与实战教程 1 环境说明 Cp…

大语言模型 24 - MCP 自动操作 提高模型上下文能力 Cursor + Sequential Thinking Server Memory

点一下关注吧!!!非常感谢!!持续更新!!! Java篇: MyBatis 更新完毕目前开始更新 Spring,一起深入浅出! 大数据篇 300: Hadoop&…

【多线程初阶】线程状态 线程安全

文章目录 1.线程状态线程的状态及状态转移 2.多线程带来的风险 - 线程安全(重点)线程安全问题产生的原因如何解决线程安全问题 1.线程状态 EE的第一篇总览中有提到过 进程的状态 1.就绪 2.阻塞 这都是从操作系统的视角看待的 Java线程也是对操作系统线程的封装,针对状态这里…

Python 序列的修改、散列和切 片(Vector类第4版:散列和快速等值 测试)

Vector类第4版:散列和快速等值测试 我们要再次实现__hash__ 方法。加上现有的__eq__ 方法,这会把 Vector 实例变成可散列的对象。 示例 9-8 中的__hash__ 方法简单地计算 hash(self.x) ^ hash(self.y)。这一次,我们要使用^(异或…

ai姿势项目

链接:https://pan.baidu.com/s/1dGSt7wEk8w6O7zlgme3CUQ?pwd=x60y 提取码:x60y --来自百度网盘超级会员V2的分享 配置环境 conda create -n 环境名称 python=3.8conda activate 环境名称 如果你运行程序的话会报错 ModuleNotFoundError: No module named mediapipe 进…

LoRA:高效微调预训练模型的利器

LoRA(Low-Rank Adaptation) 的思想:冻结预训练模型权重,将可训练的低秩分解矩阵注入到Transformer架构的每一层(也可单独配置某一层)中, 从而大大减少在下游任务的可训练参数量。 核心原理 对于预训练权重矩阵 ,LoRA限制了其更新…

越界检测算法AI智能分析网关V4打造多场景化的应用解决方案

一、方案概述 随着社会发展,传统安防系统在复杂环境下暴露出误报率高、响应慢等短板。AI智能分析网关V4依托先进算法与强大算力,实现周界区域精准监测与智能分析,显著提升入侵防范效能。本方案通过部署该网关及其越界检测功能,为…

使用SkiaSharp打造专业级12导联心电图查看器:性能与美观兼具的可视化实践

前言 欢迎关注dotnet研习社,今天我们研究的Google Skia图形库的.NET绑定SkiaSharp图形库。 在医疗软件开发领域,心电图(ECG)数据的可视化是一个既有挑战性又极其重要的任务。作为开发者,我们需要创建既专业又直观的界面来展示复杂的生物医学…

24位高精度数据采集卡NET8860音频振动信号采集监测满足自动化测试应用现场的多样化需求

NET8860 高分辨率数据采集卡技术解析 阿尔泰科技的NET8860是一款高性能数据采集卡,具备8路同步模拟输入通道和24bit分辨率,适用于高精度信号采集场景。其输入量程覆盖10V、5V、2V、1V,采样速率高达256KS/s,能够满足多种工业与科研…

2025年05月30日Github流行趋势

项目名称:agenticSeek 项目地址url:https://github.com/Fosowl/agenticSeek项目语言:Python历史star数:13040今日star数:1864项目维护者:Fosowl, steveh8758, klimentij, ganeshnikhil, apps/copilot-pull-…

PCB设计实践(三十一)PCB设计中机械孔的合理设计与应用指南

一、机械孔的基本概念与分类 机械孔是PCB设计中用于实现机械固定、结构支撑、散热及电气连接的关键结构元件,其分类基于功能特性、制造工艺和应用场景的差异,主要分为以下几类: 1. 金属化机械孔 通过电镀工艺在孔内壁形成导电层,…

TC/BC/OC P2P/E2E有啥区别?-PTP协议基础概念介绍

前言 时间同步网络中的每个节点,都被称为时钟,PTP协议定义了三种基本时钟节点。本文将介绍这三种类型的时钟,以及gPTP在同步机制上与其他机制的区别 本系列文章将由浅入深的带你了解gPTP,欢迎关注 时钟类型 在PTP中我们将各节…

五.MySQL表的约束

1.not null空属性 和 default缺省值 两个值:null(默认的)和not null(不为空) 元素可以分为两类 1.not null 不能为空的,这种没有默认default 要手动设定,我们必须插入数据而且不能为NULL。但我们插入数据有两种方式 1.…

4.Haproxy搭建Web群集

一.案例分析 1.案例概述 Haproxy是目前比较流行的一种群集调度工具,同类群集调度工具有很多,包括LVS、Nginx,LVS性能最好,但是搭建相对复杂;Nginx的upstream模块支持群集功能,但是对群集节点健康检查功能…

NewsNow:免费好用的实时新闻聚合平台,让信息获取更优雅(深度解析、部署攻略)

名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、NewsNow项目概览1. 项目核心亮点2. 技术架构特点 二、核心功能深度解析1. 智能新…

论文阅读笔记——FLOW MATCHING FOR GENERATIVE MODELING

Flow Matching 论文 扩散模型:根据中心极限定理,对原始图像不断加高斯噪声,最终将原始信号破坏为近似的标准正态分布。这其中每一步都构造为条件高斯分布,形成离散的马尔科夫链。再通过逐步去噪得到原始图像。 Flow matching 采取…

【leetcode】02.07. 链表相交

链表相交 题目代码1. 计算两个链表的长度2. 双指针 题目 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交: 代码 …

文字转图片的字符画生成工具

软件介绍 今天要介绍的这款软件可以将文字转换成图片的排列形式,非常适合需要将文字图形化的场景,建议有需要的朋友收藏。 软件名称与用途 这款软件名为《字符画大师》,是一款在网吧等场所非常流行的聊天辅助工具,其主要功能就…

Bitlocker密钥提取之SYSTEM劫持

该漏洞编号CVE-2024-20666,本文实现复现过程,Windows系统版本如下 简介 从Windows10(th1)开始,微软在winload模块中,增加了systemdatadevice字段值的获取,该字段值存储在BCD引导配置文件中。当…