一、 导包

import time
import torch.cuda
import torchvision
from torch.utils.data import DataLoader
from torch.utils.data import random_split,Subset
from torchvision import transforms
import torch.nn as nn
from torchvision import datasets
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
import matplotlib.pyplot as plt
import seaborn as sns

二、 数据增强

1、先填充再裁剪,使用上下左右随机移动

2、水平翻转

3、亮度 对比度 饱和度变化

4、50%概率随机擦除,与经典Cutout有一定差别,感觉使用经典Cutout效果应该会更好

这里注意验证机和测试集上面不做transformer

transformer_train = transforms.Compose(
    [
        transforms.RandomCrop(32, padding=4),   # 先填充再裁剪,使用上下左右随机移动
        transforms.RandomHorizontalFlip(p=0.5),     # 0.5的概率水平反转
        transforms.ColorJitter(brightness=0.2,    # 亮度变化±20%
                              contrast=0.2,       # 对比度变化±20%
                              saturation=0.2),    # 饱和度变化±20%
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465),
                            (0.2470, 0.2435, 0.2616)),
        transforms.RandomErasing(p=0.5,           # 50%概率随机擦除
                                scale=(0.02, 0.33),
                                ratio=(0.3, 3.3))
    ]
)

transformer_test = transforms.Compose(
    [
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465),
                            (0.2470, 0.2435, 0.2616)),
    ]
)

三、 定义模型

CIFAR-10 图像为32 * 32 * 3  这里使用轻量化的CNN网络

维度变化:3 * 32 * 32 - > 64 * 4 * 4

每次卷积之后都使用了批归一化使模型更加稳定,最后就是一个正常的全连接层

class myCNN(nn.Module):
    def __init__(self,class_num):
        super().__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3,16,3,1,1),
            nn.BatchNorm2d(16),
            nn.ReLU(),

            nn.Conv2d(16, 16, 3, 1, 1),
            nn.BatchNorm2d(16),
            nn.ReLU(),

            nn.MaxPool2d(2)     # 16 * 16 * 16
        )

        self.layer2 = nn.Sequential(
            nn.Conv2d(16, 32, 3, 1, 1),
            nn.BatchNorm2d(32),
            nn.ReLU(),

            nn.Conv2d(32, 32, 3, 1, 1),
            nn.BatchNorm2d(32),
            nn.ReLU(),

            nn.MaxPool2d(2)  # 32 * 8 * 8
        )

        self.layer3 = nn.Sequential(
            nn.Conv2d(32, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            nn.Conv2d(64, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            nn.MaxPool2d(2)  # 64 * 4 * 4
        )

        self.layer4 = nn.Sequential(
            nn.Flatten(),   # 在这里展开就不需要再在forward函数中重新展开
            nn.Linear(64*4*4,512),
            nn.ReLU(),
            nn.Linear(512,256),
            nn.ReLU(),
            nn.Linear(256,class_num)
        )

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        return x

四、 训练函数

训练函数中每个epoch记录一次loss,所以画出的loss图像大多都很平

(模型参数保存好像写得有问题,没改,最优参数都没保存)

def train_val(model, train_loader, val_loader, optimizer, loss, epoches, device, save_path, dir_path):
    model = model.to(device)
    plt_train_loss = []
    plt_val_loss = []
    plt_train_acc = []
    plt_val_acc = []    # 该列表用来记录每一个epoch的 loss 和 acc
    max_acc = []

    for epoch in range(epoches):
        start_time = time.time()
        train_loss = 0.0
        val_loss = 0.0   # 用来记录每一个epoch的 loss 和 acc
        train_acc = 0.0
        val_acc = 0.0

        model.train()   # 模型调为训练模式
        for batch_x, batch_y in train_loader:
            x, target = batch_x.to(device), batch_y.to(device)
            pred = model(x)
            train_batch_loss = loss(pred, target)
            optimizer.zero_grad()           # 梯度清理
            train_batch_loss.backward()     # 反向传播
            optimizer.step()                # 更新梯度
            train_loss += train_batch_loss.detach().cpu().item()
            train_acc += np.sum(np.argmax(pred.detach().cpu().numpy(),
                                           axis=1) == target.cpu().numpy())

        plt_train_loss.append(train_loss/train_loader.__len__())
        plt_train_acc.append(train_acc/train_loader.dataset.__len__())

        model.eval()
        with torch.no_grad():
            for batch_x,batch_y in val_loader:
                x, target = batch_x.to(device), batch_y.to(device)
                pred = model(x)
                val_batch_loss = loss(pred,target)
                val_loss += val_batch_loss.detach().cpu().item()
                val_acc += np.sum(np.argmax(pred.detach().cpu().numpy(),
                                               axis=1) == target.cpu().numpy())

        plt_val_loss.append(val_loss/val_loader.__len__())
        plt_val_acc.append(val_acc/val_loader.dataset.__len__())

        if val_acc > max_acc:
            torch.save(model,save_path)
            max_acc = val_acc

        print("[%02d/%02d] %2.2f sec(s) Trainloss:%.6f |train_acc:%.2f | val_loss:%.6f | val_acc:%.2f"%
            (epoch, epoches, time.time() - start_time,plt_train_loss[-1], plt_train_acc[-1], plt_val_loss[-1], plt_val_acc[-1]))

    plt.figure()
    plt.plot(plt_train_loss,label='traiin')
    plt.plot(plt_val_loss,label='val')
    plt.title('loss')
    plt.legend()  # 显示图例
    plt.savefig("img/" + dir_path + 'loss_curve.png')  # 保存
    plt.close()  # 关图,防止内存泄漏

    # ---------- acc 曲线 ----------
    plt.figure()
    plt.plot(plt_train_acc, label='train')
    plt.plot(plt_val_acc, label='val')
    plt.title('acc')
    plt.legend()
    plt.savefig("img/" + dir_path + 'acc_curve.png')
    plt.close()

五、 测试模型函数

def test_model(model, test_loader, device, dir_path, class_names=None):
    """
    CIFAR-10 完整测试评估
    """
    if class_names is None:
        class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
                       'dog', 'frog', 'horse', 'ship', 'truck']

    model = model.to(device)
    model.eval()

    all_preds = []
    all_targets = []
    total_loss = 0.0
    loss_fn = torch.nn.CrossEntropyLoss()

    with torch.no_grad():
        for batch_x, batch_y in test_loader:
            x, target = batch_x.to(device), batch_y.to(device)

            # 前向传播
            pred = model(x)

            # 计算loss
            loss = loss_fn(pred, target)
            total_loss += loss.item() * target.size(0)

            # 收集预测和标签
            pred_labels = pred.argmax(1).cpu().numpy()
            all_preds.extend(pred_labels)
            all_targets.extend(target.cpu().numpy())

    # 转为numpy数组
    all_preds = np.array(all_preds)
    all_targets = np.array(all_targets)

    # ========== 基础指标 ==========
    # Top-1 Accuracy
    top1_acc = accuracy_score(all_targets, all_preds)

    # 平均Loss
    avg_loss = total_loss / len(all_targets)

    # ========== 详细分类报告 ==========
    report = classification_report(
        all_targets,
        all_preds,
        target_names=class_names,
        digits=4
    )

    # ========== 混淆矩阵 ==========
    cm = confusion_matrix(all_targets, all_preds)

    # ========== 每类准确率 ==========
    per_class_acc = cm.diagonal() / cm.sum(axis=1)

    # ========== 打印结果 ==========
    print("\n" + "=" * 50)
    print("           CIFAR-10 Test Results")
    print("=" * 50)
    print(f"Test Loss       : {avg_loss:.4f}")
    print(f"Top-1 Accuracy  : {top1_acc:.4f} ({top1_acc * 100:.2f}%)")
    print(f"Total Samples   : {len(all_targets)}")
    print("-" * 50)

    print("\nPer-class Accuracy:")
    for i, (name, acc) in enumerate(zip(class_names, per_class_acc)):
        print(f"  {i:2d}. {name:12s}: {acc:.4f} ({acc * 100:5.2f}%)")

    print("\n" + "-" * 50)
    print("Classification Report:")
    print(report)

    # ========== 可视化混淆矩阵 ==========
    plt.figure(figsize=(10, 8))
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
                xticklabels=class_names,
                yticklabels=class_names)
    plt.xlabel('Predicted Label')
    plt.ylabel('True Label')
    plt.title('CIFAR-10 Confusion Matrix')
    plt.tight_layout()
    plt.savefig('img/' + dir_path + 'confusion_matrix.png', dpi=150)
    print("\nConfusion matrix saved to 'confusion_matrix.png'")
    plt.show()

    # ========== 找出最难分类的类别 ==========
    worst_classes = np.argsort(per_class_acc)[:3]
    print(f"\nTop 3 Most Difficult Classes:")
    for idx in worst_classes:
        print(f"  {class_names[idx]}: {per_class_acc[idx]:.4f}")

    print("=" * 50)

    return {
        'top1_acc': top1_acc,
        'avg_loss': avg_loss,
        'per_class_acc': per_class_acc,
        'confusion_matrix': cm,
        'predictions': all_preds,
        'targets': all_targets
    }

六、 训练模型

if __name__ == "__main__":
    ######定义超参数#######

    train_size = 40000
    val_size = 10000
    batch_size = 64
    lr = 0.001
    momentum = 0.1
    epoches = 32
    loss = nn.CrossEntropyLoss()
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    dataPath = "data_CIFAR"
    save_path = "model_save/best.model.pth"

    full_data = torchvision.datasets.CIFAR10(dataPath, train=True, download=False)

    train_indices, val_indices = random_split(
        range(len(full_data)),
        [train_size, val_size],
        generator=torch.Generator().manual_seed(25)
    )

    train_data = Subset(datasets.CIFAR10(dataPath, train=True, transform=transformer_train, download=False),
                        train_indices.indices)
    val_data = Subset(datasets.CIFAR10(dataPath, train=True, transform=transformer_test, download=False),  # 或 None
                      val_indices.indices)
    test_data = datasets.CIFAR10(dataPath, train=False, transform=transformer_test, download=False)



    model = myCNN(10)

    lr_lst = [0.001, 0.005, 0.0001]
    batch_size_lst = [64, 128, 256]

    for lr in lr_lst:
        for batch_size in batch_size_lst:
            train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
            val_loader = DataLoader(val_data, batch_size=batch_size, shuffle=False)
            test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=False)
            dir_path = f'lr_{lr}_epoches_{epoches}_bs_{batch_size}'
            print(f"{'='*20}" , dir_path, f"{'='*20}")
            optimizer = torch.optim.Adam(model.parameters(), lr=lr)
            save_path = "model_save/" + dir_path + "best.model.pth"
            train_val(model, train_loader, val_loader, optimizer, loss, epoches, device, save_path, dir_path)
            results = test_model(model, test_loader, device='cuda', dir_path=dir_path)
            print(f"\nFinal Test Accuracy: {results['top1_acc'] * 100:.2f}%")

七、 结果

1、batch_size = 64,lr = 0.001

最后发现,模型在batch_size=64,lr=0.001 需要多个epoch才能收敛

此时train_acc=0.81  val_acc = 0.83


详细结果如下:

==================================================
           CIFAR-10 Test Results
==================================================
Test Loss       : 0.5250
Top-1 Accuracy  : 0.8292 (82.92%)
Total Samples   : 10000
--------------------------------------------------

Per-class Accuracy:
   0. airplane    : 0.8520 (85.20%)
   1. automobile  : 0.9090 (90.90%)
   2. bird        : 0.6650 (66.50%)
   3. cat         : 0.5390 (53.90%)
   4. deer        : 0.8650 (86.50%)
   5. dog         : 0.8270 (82.70%)
   6. frog        : 0.9150 (91.50%)
   7. horse       : 0.8970 (89.70%)
   8. ship        : 0.9040 (90.40%)
   9. truck       : 0.9190 (91.90%)

--------------------------------------------------
Classification Report:
              precision    recall  f1-score   support

    airplane     0.8402    0.8520    0.8461      1000
  automobile     0.9489    0.9090    0.9285      1000
        bird     0.8636    0.6650    0.7514      1000
         cat     0.8292    0.5390    0.6533      1000
        deer     0.7621    0.8650    0.8103      1000
         dog     0.6852    0.8270    0.7494      1000
        frog     0.7888    0.9150    0.8472      1000
       horse     0.8478    0.8970    0.8717      1000
        ship     0.8915    0.9040    0.8977      1000
       truck     0.8888    0.9190    0.9036      1000

    accuracy                         0.8292     10000
   macro avg     0.8346    0.8292    0.8259     10000
weighted avg     0.8346    0.8292    0.8259     10000


Confusion matrix saved to 'confusion_matrix.png'

Top 3 Most Difficult Classes:
  cat: 0.5390
  bird: 0.6650
  dog: 0.8270
 

2、batch_size = 256,lr = 0.0001

模型一上来就能达到较高的精度(也很奇怪,寻找答案中...所以导致loss和acc的图看起来也很奇怪),后来再用这一组参数,也没有这88的精度了(不知道为什么,以后再回来看看)

3、batch_size = 256,lr = 0.001

(后来重新单独训练的一组参数,也不是一上来就收敛到80多的精度,哈哈真奇怪)

loss 和acc 曲线看起来感觉还是挺正常的

八、 完整源码

import time
import matplotlib.pyplot as plt
import numpy as np
import torch.cuda
import torchvision
from torch.utils.data import DataLoader,Dataset
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import random_split,Subset
from torchvision import transforms
import torch.nn as nn
from torchvision import datasets
import sys
import os
from datetime import datetime
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
import matplotlib.pyplot as plt
import seaborn as sns

transformer_train = transforms.Compose(
    [
        transforms.RandomCrop(32, padding=4),   # 先填充再裁剪,使用上下左右随机移动
        transforms.RandomHorizontalFlip(p=0.5),     # 0.5的概率水平反转
        transforms.ColorJitter(brightness=0.2,    # 亮度变化±20%
                              contrast=0.2,       # 对比度变化±20%
                              saturation=0.2),    # 饱和度变化±20%
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465),
                            (0.2470, 0.2435, 0.2616)),
        transforms.RandomErasing(p=0.5,           # 50%概率随机擦除
                                scale=(0.02, 0.33),
                                ratio=(0.3, 3.3))
    ]
)

transformer_test = transforms.Compose(
    [
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465),
                            (0.2470, 0.2435, 0.2616)),
    ]
)

class myCNN(nn.Module):
    def __init__(self,class_num):
        super().__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3,16,3,1,1),
            nn.BatchNorm2d(16),
            nn.ReLU(),

            nn.Conv2d(16, 16, 3, 1, 1),
            nn.BatchNorm2d(16),
            nn.ReLU(),

            nn.MaxPool2d(2)     # 16 * 16 * 16
        )

        self.layer2 = nn.Sequential(
            nn.Conv2d(16, 32, 3, 1, 1),
            nn.BatchNorm2d(32),
            nn.ReLU(),

            nn.Conv2d(32, 32, 3, 1, 1),
            nn.BatchNorm2d(32),
            nn.ReLU(),

            nn.MaxPool2d(2)  # 32 * 8 * 8
        )

        self.layer3 = nn.Sequential(
            nn.Conv2d(32, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            nn.Conv2d(64, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            nn.MaxPool2d(2)  # 64 * 4 * 4
        )

        self.layer4 = nn.Sequential(
            nn.Flatten(),
            nn.Linear(64*4*4,512),
            nn.ReLU(),
            nn.Linear(512,256),
            nn.ReLU(),
            nn.Linear(256,class_num)
        )

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        return x

def train_val(model, train_loader, val_loader, optimizer, loss, epoches, device, save_path, dir_path):
    model = model.to(device)
    plt_train_loss = []
    plt_val_loss = []
    plt_train_acc = []
    plt_val_acc = []    # 该列表用来记录每一个epoch的 loss 和 acc
    max_acc = []

    for epoch in range(epoches):
        start_time = time.time()
        train_loss = 0.0
        val_loss = 0.0   # 用来记录每一个epoch的 loss 和 acc
        train_acc = 0.0
        val_acc = 0.0

        model.train()   # 模型调为训练模式
        for batch_x, batch_y in train_loader:
            x, target = batch_x.to(device), batch_y.to(device)
            pred = model(x)
            train_batch_loss = loss(pred, target)
            optimizer.zero_grad()           # 梯度清理
            train_batch_loss.backward()     # 反向传播
            optimizer.step()                # 更新梯度
            train_loss += train_batch_loss.detach().cpu().item()
            train_acc += np.sum(np.argmax(pred.detach().cpu().numpy(),
                                           axis=1) == target.cpu().numpy())

        plt_train_loss.append(train_loss/train_loader.__len__())
        plt_train_acc.append(train_acc/train_loader.dataset.__len__())

        model.eval()
        with torch.no_grad():
            for batch_x,batch_y in val_loader:
                x, target = batch_x.to(device), batch_y.to(device)
                pred = model(x)
                val_batch_loss = loss(pred,target)
                val_loss += val_batch_loss.detach().cpu().item()
                val_acc += np.sum(np.argmax(pred.detach().cpu().numpy(),
                                               axis=1) == target.cpu().numpy())

        plt_val_loss.append(val_loss/val_loader.__len__())
        plt_val_acc.append(val_acc/val_loader.dataset.__len__())

        if val_acc > max_acc:
            torch.save(model,save_path)
            max_acc = val_acc

        print("[%02d/%02d] %2.2f sec(s) Trainloss:%.6f |train_acc:%.2f | val_loss:%.6f | val_acc:%.2f"%
            (epoch, epoches, time.time() - start_time,plt_train_loss[-1], plt_train_acc[-1], plt_val_loss[-1], plt_val_acc[-1]))

    plt.figure()
    plt.plot(plt_train_loss,label='traiin')
    plt.plot(plt_val_loss,label='val')
    plt.title('loss')
    plt.legend()  # 显示图例
    plt.savefig("img1/" + dir_path + 'loss_curve.png')  # 保存
    plt.close()  # 关图,防止内存泄漏

    # ---------- acc 曲线 ----------
    plt.figure()
    plt.plot(plt_train_acc, label='train')
    plt.plot(plt_val_acc, label='val')
    plt.title('acc')
    plt.legend()
    plt.savefig("img1/" + dir_path + 'acc_curve.png')
    plt.close()


def test_model(model, test_loader, device, dir_path, class_names=None):
    """
    CIFAR-10 完整测试评估
    """
    if class_names is None:
        class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
                       'dog', 'frog', 'horse', 'ship', 'truck']

    model = model.to(device)
    model.eval()

    all_preds = []
    all_targets = []
    total_loss = 0.0
    loss_fn = torch.nn.CrossEntropyLoss()

    with torch.no_grad():
        for batch_x, batch_y in test_loader:
            x, target = batch_x.to(device), batch_y.to(device)

            # 前向传播
            pred = model(x)

            # 计算loss
            loss = loss_fn(pred, target)
            total_loss += loss.item() * target.size(0)

            # 收集预测和标签
            pred_labels = pred.argmax(1).cpu().numpy()
            all_preds.extend(pred_labels)
            all_targets.extend(target.cpu().numpy())

    # 转为numpy数组
    all_preds = np.array(all_preds)
    all_targets = np.array(all_targets)

    # ========== 基础指标 ==========
    # Top-1 Accuracy
    top1_acc = accuracy_score(all_targets, all_preds)

    # 平均Loss
    avg_loss = total_loss / len(all_targets)

    # ========== 详细分类报告 ==========
    report = classification_report(
        all_targets,
        all_preds,
        target_names=class_names,
        digits=4
    )

    # ========== 混淆矩阵 ==========
    cm = confusion_matrix(all_targets, all_preds)

    # ========== 每类准确率 ==========
    per_class_acc = cm.diagonal() / cm.sum(axis=1)

    # ========== 打印结果 ==========
    print("\n" + "=" * 50)
    print("           CIFAR-10 Test Results")
    print("=" * 50)
    print(f"Test Loss       : {avg_loss:.4f}")
    print(f"Top-1 Accuracy  : {top1_acc:.4f} ({top1_acc * 100:.2f}%)")
    print(f"Total Samples   : {len(all_targets)}")
    print("-" * 50)

    print("\nPer-class Accuracy:")
    for i, (name, acc) in enumerate(zip(class_names, per_class_acc)):
        print(f"  {i:2d}. {name:12s}: {acc:.4f} ({acc * 100:5.2f}%)")

    print("\n" + "-" * 50)
    print("Classification Report:")
    print(report)

    # ========== 可视化混淆矩阵 ==========
    plt.figure(figsize=(10, 8))
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
                xticklabels=class_names,
                yticklabels=class_names)
    plt.xlabel('Predicted Label')
    plt.ylabel('True Label')
    plt.title('CIFAR-10 Confusion Matrix')
    plt.tight_layout()
    plt.savefig('img1/' + dir_path + 'confusion_matrix.png', dpi=150)
    print("\nConfusion matrix saved to 'confusion_matrix.png'")
    plt.show()

    # ========== 找出最难分类的类别 ==========
    worst_classes = np.argsort(per_class_acc)[:3]
    print(f"\nTop 3 Most Difficult Classes:")
    for idx in worst_classes:
        print(f"  {class_names[idx]}: {per_class_acc[idx]:.4f}")

    print("=" * 50)

    return {
        'top1_acc': top1_acc,
        'avg_loss': avg_loss,
        'per_class_acc': per_class_acc,
        'confusion_matrix': cm,
        'predictions': all_preds,
        'targets': all_targets
    }




if __name__ == "__main__":
    ######定义超参数#######

    train_size = 40000
    val_size = 10000
    batch_size = 64
    lr = 0.001
    momentum = 0.1
    epoches = 32
    loss = nn.CrossEntropyLoss()
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    dataPath = "data_CIFAR"
    save_path = "model_save/best.model.pth"

    full_data = torchvision.datasets.CIFAR10(dataPath, train=True, download=False)

    train_indices, val_indices = random_split(
        range(len(full_data)),
        [train_size, val_size],
        generator=torch.Generator().manual_seed(25)
    )

    train_data = Subset(datasets.CIFAR10(dataPath, train=True, transform=transformer_train, download=False),
                        train_indices.indices)
    val_data = Subset(datasets.CIFAR10(dataPath, train=True, transform=transformer_test, download=False),  # 或 None
                      val_indices.indices)
    test_data = datasets.CIFAR10(dataPath, train=False, transform=transformer_test, download=False)



    model = myCNN(10)

    lr_lst = [0.0001]     # 这里根据需要自己调整
    batch_size_lst = [128, 256]

    for lr in lr_lst:
        for batch_size in batch_size_lst:
            train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
            val_loader = DataLoader(val_data, batch_size=batch_size, shuffle=False)
            test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=False)
            dir_path = f'lr_{lr}_epoches_{epoches}_bs_{batch_size}'
            print(f"{'='*20}" , dir_path, f"{'='*20}")
            optimizer = torch.optim.Adam(model.parameters(), lr=lr)
            save_path = "model_save/" + dir_path + "best.model.pth"
            train_val(model, train_loader, val_loader, optimizer, loss, epoches, device, save_path, dir_path)
            results = test_model(model, test_loader, device='cuda', dir_path=dir_path)
            print(f"\nFinal Test Accuracy: {results['top1_acc'] * 100:.2f}%")




        找到原因了,模型定义到循环外面去了,导致模型没有初始化,模型上一次训练的参数没有清除,相当于每次训练都在上一次的基础上跑模型,太搞笑了,一个小时的模型白跑


更多推荐