深度学习 Day16——P5运动鞋识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊 | 接辅导、项目定制

文章目录

  • 前言
  • 1 我的环境
  • 2 代码实现与执行结果
    • 2.1 前期准备
      • 2.1.1 引入库
      • 2.1.2 设置GPU(如果设备上支持GPU就使用GPU,否则使用CPU)
      • 2.1.3 导入数据
      • 2.1.4 可视化数据
      • 2.1.4 图像数据变换
      • 2.1.4 加载数据
      • 2.1.4 查看数据
    • 2.2 构建CNN网络模型
    • 2.3 训练模型
      • 2.3.1 设置超参数
      • 2.3.2 编写训练函数
      • 2.3.3 编写测试函数
      • 2.3.4 正式训练
    • 2.4 结果可视化
    • 2.4 指定图片进行预测
    • 2.6 保存并加载模型
  • 3 知识点详解
    • 3.1 torch动态学习率
      • 3.1.1 torch.optim.lr_scheduler.StepLR
      • 3.1.2 lr_scheduler.LambdaLR
      • 3.1.3 lr_scheduler.MultiStepLR
    • 3.2 拔高尝试
  • 总结


前言

本文将采用pytorch框架创建CNN网络,实现运动鞋识别。讲述实现代码与执行结果,并浅谈涉及知识点。
关键字:torch动态学习率

1 我的环境

  • 电脑系统:Windows 11
  • 语言环境:python 3.8.6
  • 编译器:pycharm2020.2.3
  • 深度学习环境:
    torch == 1.9.1+cu111
    torchvision == 0.10.1+cu111
  • 显卡:NVIDIA GeForce RTX 4070

2 代码实现与执行结果

2.1 前期准备

2.1.1 引入库

import torch
import torch.nn as nn
from torchvision import transforms, datasets
import time
from pathlib import Path
from PIL import Image
from torchinfo import summary
import torch.nn.functional as F
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams['figure.dpi'] = 100  # 分辨率
import warnings

warnings.filterwarnings('ignore')  # 忽略一些warning内容,无需打印

2.1.2 设置GPU(如果设备上支持GPU就使用GPU,否则使用CPU)

"""前期准备-设置GPU"""
# 如果设备上支持GPU就使用GPU,否则使用CPU
 device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 print("Using {} device".format(device))

输出

Using cuda device

2.1.3 导入数据

'''前期工作-导入数据'''
data_dir = r"D:\DeepLearning\data\monkeypox_recognition"
data_dir = Path(data_dir)

data_paths = list(data_dir.glob('./train/*'))
    classeNames = [str(path).split("\\")[-1] for path in data_paths]
    print(classeNames)

输出

['adidas', 'nike']

2.1.4 可视化数据

'''前期工作-可视化数据'''
subfolder = Path(data_dir)/"train"/"nike"
image_files = list(p.resolve() for p in subfolder.glob('*') if p.suffix in [".jpg", ".png", ".jpeg"])
plt.figure(figsize=(10, 6))
for i in range(len(image_files[:12])):
    image_file = image_files[i]
    ax = plt.subplot(3, 4, i + 1)
    img = Image.open(str(image_file))
    plt.imshow(img)
    plt.axis("off")
# 显示图片
plt.tight_layout()
plt.show()

在这里插入图片描述

2.1.4 图像数据变换

'''前期工作-图像数据变换'''
    # 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
    train_transforms = transforms.Compose([
        transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
        # transforms.RandomHorizontalFlip(), # 随机水平翻转
        transforms.ToTensor(),  # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
        transforms.Normalize(  # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
            mean=[0.485, 0.456, 0.406],
            std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
    ])

    test_transform = transforms.Compose([
        transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
        transforms.ToTensor(),  # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
        transforms.Normalize(  # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
            mean=[0.485, 0.456, 0.406],
            std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
    ])

    train_dataset = datasets.ImageFolder(Path(data_dir)/"train", transform=train_transforms)
    test_dataset = datasets.ImageFolder(Path(data_dir)/"test", transform=train_transforms)
    print(train_dataset.class_to_idx)

输出

{'adidas': 0, 'nike': 1}

2.1.4 加载数据

'''前期工作-加载数据'''
batch_size = 32

train_dl = torch.utils.data.DataLoader(train_dataset,
                                       batch_size=batch_size,
                                       shuffle=True,
                                       num_workers=1)
test_dl = torch.utils.data.DataLoader(test_dataset,
                                      batch_size=batch_size,
                                      shuffle=True,
                                      num_workers=1)

2.1.4 查看数据

'''前期工作-查看数据'''
for X, y in test_dl:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break

输出

Shape of X [N, C, H, W]:  torch.Size([32, 3, 224, 224])
Shape of y:  torch.Size([32]) torch.int64

2.2 构建CNN网络模型

在这里插入图片描述

"""构建CNN网络"""
class Network_bn(nn.Module):
    def __init__(self):
        super(Network_bn, self).__init__()
        """
        nn.Conv2d()函数:
        第一个参数(in_channels)是输入的channel数量
        第二个参数(out_channels)是输出的channel数量
        第三个参数(kernel_size)是卷积核大小
        第四个参数(stride)是步长,默认为1
        第五个参数(padding)是填充大小,默认为0
        """
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(12)
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn2 = nn.BatchNorm2d(12)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn4 = nn.BatchNorm2d(24)
        self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn5 = nn.BatchNorm2d(24)
        self.fc1 = nn.Linear(24 * 50 * 50, len(classeNames))

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = self.pool(x)
        x = F.relu(self.bn4(self.conv4(x)))
        x = F.relu(self.bn5(self.conv5(x)))
        x = self.pool(x)
        x = x.view(-1, 24 * 50 * 50)
        x = self.fc1(x)

        return x

        
model = Network_bn().to(device)
print(model)   

输出

Network_bn(
  (conv1): Conv2d(3, 12, kernel_size=(5, 5), stride=(1, 1))
  (bn1): BatchNorm2d(12, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv2): Conv2d(12, 12, kernel_size=(5, 5), stride=(1, 1))
  (bn2): BatchNorm2d(12, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv4): Conv2d(12, 24, kernel_size=(5, 5), stride=(1, 1))
  (bn4): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv5): Conv2d(24, 24, kernel_size=(5, 5), stride=(1, 1))
  (bn5): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (fc1): Linear(in_features=60000, out_features=2, bias=True)
)

2.3 训练模型

2.3.1 设置超参数

"""训练模型--设置超参数"""
loss_fn = nn.CrossEntropyLoss()  # 创建损失函数,计算实际输出和真实相差多少,交叉熵损失函数,事实上,它就是做图片分类任务时常用的损失函数
learn_rate = 1e-4  # 学习率
optimizer1 = torch.optim.SGD(model.parameters(), lr=learn_rate)# 作用是定义优化器,用来训练时候优化模型参数;其中,SGD表示随机梯度下降,用于控制实际输出y与真实y之间的相差有多大
optimizer2 = torch.optim.Adam(model.parameters(), lr=learn_rate)
#测试集acc 84.2%
lr_opt = optimizer1
model_opt = optimizer1

2.3.2 编写训练函数

"""训练模型--编写训练函数"""
# 训练循环
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片
    num_batches = len(dataloader)  # 批次数目,1875(60000/32)

    train_loss, train_acc = 0, 0  # 初始化训练损失和正确率

    for X, y in dataloader:  # 加载数据加载器,得到里面的 X(图片数据)和 y(真实标签)
        X, y = X.to(device), y.to(device) # 用于将数据存到显卡

        # 计算预测误差
        pred = model(X)  # 网络输出
        loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失

        # 反向传播
        optimizer.zero_grad()  # 清空过往梯度
        loss.backward()  # 反向传播,计算当前梯度
        optimizer.step()  # 根据梯度更新网络参数

        # 记录acc与loss
        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()

    train_acc /= size
    train_loss /= num_batches

    return train_acc, train_loss

2.3.3 编写测试函数

"""训练模型--编写测试函数"""
# 测试函数和训练函数大致相同,但是由于不进行梯度下降对网络权重进行更新,所以不需要传入优化器
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)  # 测试集的大小,一共10000张图片
    num_batches = len(dataloader)  # 批次数目,313(10000/32=312.5,向上取整)
    test_loss, test_acc = 0, 0

    # 当不进行训练时,停止梯度更新,节省计算内存消耗
    with torch.no_grad(): # 测试时模型参数不用更新,所以 no_grad,整个模型参数正向推就ok,不反向更新参数
        for imgs, target in dataloader:
            imgs, target = imgs.to(device), target.to(device)

            # 计算loss
            target_pred = model(imgs)
            loss = loss_fn(target_pred, target)

            test_loss += loss.item()
            test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()#统计预测正确的个数

    test_acc /= size
    test_loss /= num_batches

    return test_acc, test_loss

2.3.4 正式训练

 """训练模型--正式训练"""
    epochs = 40
    train_loss = []
    train_acc = []
    test_loss = []
    test_acc = []
    best_test_acc=0
    PATH = './model.pth'  # 保存的参数文件名
    for epoch in range(epochs):
        milliseconds_t1 = int(time.time() * 1000)

        # 更新学习率(使用自定义学习率时使用)
        adjust_learning_rate(lr_opt, epoch, learn_rate)
        model.train()
        epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, model_opt)
        # scheduler.step() # 更新学习率(调用官方动态学习率接口时使用)

        model.eval()
        epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

        train_acc.append(epoch_train_acc)
        train_loss.append(epoch_train_loss)
        test_acc.append(epoch_test_acc)
        test_loss.append(epoch_test_loss)

        # 获取当前的学习率
        lr = lr_opt.state_dict()['param_groups'][0]['lr']

        milliseconds_t2 = int(time.time() * 1000)
        template = ('Epoch:{:2d}, duration:{}ms, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}, Lr:{:.2E}')
        if best_test_acc < epoch_test_acc:
            best_test_acc = epoch_test_acc
            # 模型保存
            torch.save(model.state_dict(), PATH)
            template = (
                'Epoch:{:2d}, duration:{}ms, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}, Lr:{:.2E},save model.pth')
        print(
            template.format(epoch + 1, milliseconds_t2-milliseconds_t1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss, lr))
    print('Done')

输出

Epoch: 1, duration:5323ms, Train_acc:52.2%, Train_loss:0.745, Test_acc:50.0%,Test_loss:0.700, Lr:1.00E-04,save model.pth
Epoch: 2, duration:3125ms, Train_acc:62.9%, Train_loss:0.651, Test_acc:57.9%,Test_loss:0.667, Lr:1.00E-04,save model.pth
Epoch: 3, duration:3130ms, Train_acc:66.9%, Train_loss:0.614, Test_acc:67.1%,Test_loss:0.584, Lr:9.20E-05,save model.pth
Epoch: 4, duration:3136ms, Train_acc:70.5%, Train_loss:0.567, Test_acc:72.4%,Test_loss:0.568, Lr:9.20E-05,save model.pth
Epoch: 5, duration:3346ms, Train_acc:76.1%, Train_loss:0.531, Test_acc:72.4%,Test_loss:0.537, Lr:8.46E-05
Epoch: 6, duration:3087ms, Train_acc:77.5%, Train_loss:0.510, Test_acc:72.4%,Test_loss:0.531, Lr:8.46E-05
Epoch: 7, duration:3215ms, Train_acc:77.7%, Train_loss:0.492, Test_acc:78.9%,Test_loss:0.511, Lr:7.79E-05,save model.pth
Epoch: 8, duration:3520ms, Train_acc:82.3%, Train_loss:0.467, Test_acc:77.6%,Test_loss:0.504, Lr:7.79E-05
Epoch: 9, duration:3662ms, Train_acc:83.1%, Train_loss:0.442, Test_acc:81.6%,Test_loss:0.494, Lr:7.16E-05,save model.pth
Epoch:10, duration:3410ms, Train_acc:85.7%, Train_loss:0.427, Test_acc:80.3%,Test_loss:0.464, Lr:7.16E-05
Epoch:11, duration:3486ms, Train_acc:86.3%, Train_loss:0.413, Test_acc:81.6%,Test_loss:0.469, Lr:6.59E-05
Epoch:12, duration:3356ms, Train_acc:87.6%, Train_loss:0.394, Test_acc:78.9%,Test_loss:0.452, Lr:6.59E-05
Epoch:13, duration:3453ms, Train_acc:87.6%, Train_loss:0.391, Test_acc:81.6%,Test_loss:0.494, Lr:6.06E-05
Epoch:14, duration:3226ms, Train_acc:87.8%, Train_loss:0.385, Test_acc:80.3%,Test_loss:0.450, Lr:6.06E-05
Epoch:15, duration:3290ms, Train_acc:89.0%, Train_loss:0.368, Test_acc:82.9%,Test_loss:0.486, Lr:5.58E-05,save model.pth
Epoch:16, duration:3247ms, Train_acc:90.4%, Train_loss:0.359, Test_acc:81.6%,Test_loss:0.443, Lr:5.58E-05
Epoch:17, duration:3195ms, Train_acc:90.6%, Train_loss:0.358, Test_acc:81.6%,Test_loss:0.452, Lr:5.13E-05
Epoch:18, duration:3294ms, Train_acc:90.6%, Train_loss:0.342, Test_acc:82.9%,Test_loss:0.436, Lr:5.13E-05
Epoch:19, duration:3305ms, Train_acc:91.2%, Train_loss:0.338, Test_acc:81.6%,Test_loss:0.452, Lr:4.72E-05
Epoch:20, duration:3241ms, Train_acc:91.8%, Train_loss:0.332, Test_acc:81.6%,Test_loss:0.418, Lr:4.72E-05
Epoch:21, duration:3371ms, Train_acc:93.0%, Train_loss:0.320, Test_acc:81.6%,Test_loss:0.459, Lr:4.34E-05
Epoch:22, duration:3279ms, Train_acc:92.8%, Train_loss:0.317, Test_acc:81.6%,Test_loss:0.475, Lr:4.34E-05
Epoch:23, duration:3279ms, Train_acc:93.4%, Train_loss:0.310, Test_acc:82.9%,Test_loss:0.438, Lr:4.00E-05
Epoch:24, duration:3225ms, Train_acc:93.0%, Train_loss:0.313, Test_acc:81.6%,Test_loss:0.437, Lr:4.00E-05
Epoch:25, duration:3293ms, Train_acc:94.0%, Train_loss:0.304, Test_acc:81.6%,Test_loss:0.439, Lr:3.68E-05
Epoch:26, duration:3273ms, Train_acc:94.0%, Train_loss:0.297, Test_acc:81.6%,Test_loss:0.414, Lr:3.68E-05
Epoch:27, duration:3249ms, Train_acc:94.2%, Train_loss:0.296, Test_acc:80.3%,Test_loss:0.413, Lr:3.38E-05
Epoch:28, duration:3266ms, Train_acc:94.8%, Train_loss:0.288, Test_acc:84.2%,Test_loss:0.425, Lr:3.38E-05,save model.pth
Epoch:29, duration:3248ms, Train_acc:94.4%, Train_loss:0.288, Test_acc:81.6%,Test_loss:0.400, Lr:3.11E-05
Epoch:30, duration:3243ms, Train_acc:94.6%, Train_loss:0.291, Test_acc:81.6%,Test_loss:0.445, Lr:3.11E-05
Epoch:31, duration:3250ms, Train_acc:96.4%, Train_loss:0.278, Test_acc:81.6%,Test_loss:0.465, Lr:2.86E-05
Epoch:32, duration:3193ms, Train_acc:95.2%, Train_loss:0.275, Test_acc:81.6%,Test_loss:0.438, Lr:2.86E-05
Epoch:33, duration:3283ms, Train_acc:95.2%, Train_loss:0.270, Test_acc:81.6%,Test_loss:0.402, Lr:2.63E-05
Epoch:34, duration:3542ms, Train_acc:94.8%, Train_loss:0.280, Test_acc:81.6%,Test_loss:0.407, Lr:2.63E-05
Epoch:35, duration:3592ms, Train_acc:95.8%, Train_loss:0.269, Test_acc:81.6%,Test_loss:0.442, Lr:2.42E-05
Epoch:36, duration:3592ms, Train_acc:95.4%, Train_loss:0.267, Test_acc:80.3%,Test_loss:0.413, Lr:2.42E-05
Epoch:37, duration:3588ms, Train_acc:95.0%, Train_loss:0.265, Test_acc:81.6%,Test_loss:0.432, Lr:2.23E-05
Epoch:38, duration:3736ms, Train_acc:95.0%, Train_loss:0.267, Test_acc:81.6%,Test_loss:0.438, Lr:2.23E-05
Epoch:39, duration:3431ms, Train_acc:95.2%, Train_loss:0.265, Test_acc:82.9%,Test_loss:0.400, Lr:2.05E-05
Epoch:40, duration:3417ms, Train_acc:95.8%, Train_loss:0.270, Test_acc:81.6%,Test_loss:0.379, Lr:2.05E-05
Done

2.4 结果可视化

"""训练模型--结果可视化"""
epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

在这里插入图片描述

2.4 指定图片进行预测

def predict_one_image(image_path, model, transform, classes):
    test_img = Image.open(image_path).convert('RGB')
    plt.imshow(test_img)  # 展示预测的图片
    plt.show()

    test_img = transform(test_img)
    img = test_img.to(device).unsqueeze(0)

    model.eval()
    output = model(img)

    _, pred = torch.max(output, 1)
    pred_class = classes[pred]
    print(f'预测结果是:{pred_class}')
    
"""指定图片进行预测"""
 classes = list(total_data.class_to_idx)
# 预测训练集中的某张照片
predict_one_image(image_path=str(Path(data_dir)/"test/adidas/1.jpg"),
                  model=model,
                  transform=train_transforms,
                  classes=classes)

如果使用效果最好的模型,就先加载保存好的模型,再调用预测代码

   # 将参数加载到model当中
    model.load_state_dict(torch.load(PATH, map_location=device))

输出

预测结果是:adidas

在这里插入图片描述

2.6 保存并加载模型

"""保存并加载模型"""
# 模型保存
PATH = './model.pth'  # 保存的参数文件名
torch.save(model.state_dict(), PATH)

# 将参数加载到model当中
model.load_state_dict(torch.load(PATH, map_location=device))

3 知识点详解

3.1 torch动态学习率

3.1.1 torch.optim.lr_scheduler.StepLR

函数原型:

torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)

关键参数详解:

  • optimizer(Optimizer):是之前定义好的需要优化的优化器的实例名
  • step_size(int):是学习率衰减的周期,每经过每个epoch,做一次学习率decay
  • gamma(float):学习率衰减的乘法因子。Default:0.1

用法示例:

optimizer = torch.optim.SGD(net.parameters(), lr=0.001 )
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

3.1.2 lr_scheduler.LambdaLR

根据自己定义的函数更新学习率。
函数原型:

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)

关键参数详解:

  • optimizer(Optimizer):是之前定义好的需要优化的优化器的实例名
  • lr_lambda(function):更新学习率的函数
    用法示例:
lambda1 = lambda epoch: (0.92 ** (epoch // 2) # 第二组参数的调整方法
optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) #选定调整方法

3.1.3 lr_scheduler.MultiStepLR

在特定的 epoch 中调整学习率
函数原型:

torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1, verbose=False)

关键参数详解:

  • optimizer(Optimizer):是之前定义好的需要优化的优化器的实例名
  • milestones(list):是一个关于epoch数值的list,表示在达到哪个epoch范围内开始变化,必须是升序排列
  • gamma(float):学习率衰减的乘法因子。Default:0.1
    用法示例:
optimizer = torch.optim.SGD(net.parameters(), lr=0.001 )
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, 
                                                 milestones=[2,6,15], #调整学习率的epoch数
                                                 gamma=0.1)

更多的官方动态学习率设置方式可参考:https://pytorch.org/docs/stable/optim.html
👉调用官方接口示例:

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler.step()

3.2 拔高尝试

尝试变更dropout失活比例为0.5,测试集acc提升至86.8%,实际上也不能确定是因为变更比例导致的效果提升,因为每次运行效果都有不同,有好有坏。

Epoch: 1, duration:4820ms, Train_acc:53.6%, Train_loss:1.133, Test_acc:52.6%,Test_loss:0.712, Lr:1.00E-04,save model.pth
Epoch: 2, duration:3271ms, Train_acc:73.5%, Train_loss:0.547, Test_acc:59.2%,Test_loss:0.697, Lr:1.00E-04,save model.pth
Epoch: 3, duration:3566ms, Train_acc:81.5%, Train_loss:0.396, Test_acc:77.6%,Test_loss:0.485, Lr:9.20E-05,save model.pth
Epoch: 4, duration:3309ms, Train_acc:89.4%, Train_loss:0.287, Test_acc:77.6%,Test_loss:0.470, Lr:9.20E-05
Epoch: 5, duration:3411ms, Train_acc:94.2%, Train_loss:0.219, Test_acc:82.9%,Test_loss:0.418, Lr:8.46E-05,save model.pth
Epoch: 6, duration:3239ms, Train_acc:98.2%, Train_loss:0.172, Test_acc:81.6%,Test_loss:0.385, Lr:8.46E-05
Epoch: 7, duration:3282ms, Train_acc:98.8%, Train_loss:0.127, Test_acc:85.5%,Test_loss:0.374, Lr:7.79E-05,save model.pth
Epoch: 8, duration:3277ms, Train_acc:99.2%, Train_loss:0.115, Test_acc:82.9%,Test_loss:0.332, Lr:7.79E-05
Epoch: 9, duration:3440ms, Train_acc:99.6%, Train_loss:0.091, Test_acc:86.8%,Test_loss:0.356, Lr:7.16E-05,save model.pth
Epoch:10, duration:3570ms, Train_acc:100.0%, Train_loss:0.078, Test_acc:81.6%,Test_loss:0.411, Lr:7.16E-05
Epoch:11, duration:3418ms, Train_acc:99.6%, Train_loss:0.072, Test_acc:84.2%,Test_loss:0.370, Lr:6.59E-05
Epoch:12, duration:3291ms, Train_acc:100.0%, Train_loss:0.064, Test_acc:85.5%,Test_loss:0.339, Lr:6.59E-05
Epoch:13, duration:3273ms, Train_acc:100.0%, Train_loss:0.054, Test_acc:85.5%,Test_loss:0.321, Lr:6.06E-05
Epoch:14, duration:3365ms, Train_acc:100.0%, Train_loss:0.049, Test_acc:85.5%,Test_loss:0.336, Lr:6.06E-05
Epoch:15, duration:3321ms, Train_acc:100.0%, Train_loss:0.046, Test_acc:84.2%,Test_loss:0.311, Lr:5.58E-05
Epoch:16, duration:3273ms, Train_acc:100.0%, Train_loss:0.041, Test_acc:84.2%,Test_loss:0.336, Lr:5.58E-05
Epoch:17, duration:3315ms, Train_acc:100.0%, Train_loss:0.038, Test_acc:85.5%,Test_loss:0.350, Lr:5.13E-05
Epoch:18, duration:3380ms, Train_acc:100.0%, Train_loss:0.034, Test_acc:82.9%,Test_loss:0.314, Lr:5.13E-05
Epoch:19, duration:3275ms, Train_acc:100.0%, Train_loss:0.034, Test_acc:84.2%,Test_loss:0.378, Lr:4.72E-05
Epoch:20, duration:3264ms, Train_acc:100.0%, Train_loss:0.031, Test_acc:82.9%,Test_loss:0.342, Lr:4.72E-05
Epoch:21, duration:3267ms, Train_acc:100.0%, Train_loss:0.029, Test_acc:84.2%,Test_loss:0.299, Lr:4.34E-05
Epoch:22, duration:3243ms, Train_acc:100.0%, Train_loss:0.028, Test_acc:84.2%,Test_loss:0.320, Lr:4.34E-05
Epoch:23, duration:3319ms, Train_acc:100.0%, Train_loss:0.025, Test_acc:82.9%,Test_loss:0.335, Lr:4.00E-05
Epoch:24, duration:3230ms, Train_acc:100.0%, Train_loss:0.025, Test_acc:84.2%,Test_loss:0.351, Lr:4.00E-05
Epoch:25, duration:3251ms, Train_acc:100.0%, Train_loss:0.025, Test_acc:84.2%,Test_loss:0.329, Lr:3.68E-05
Epoch:26, duration:3275ms, Train_acc:100.0%, Train_loss:0.023, Test_acc:84.2%,Test_loss:0.304, Lr:3.68E-05
Epoch:27, duration:3244ms, Train_acc:100.0%, Train_loss:0.022, Test_acc:82.9%,Test_loss:0.324, Lr:3.38E-05
Epoch:28, duration:3319ms, Train_acc:100.0%, Train_loss:0.022, Test_acc:85.5%,Test_loss:0.308, Lr:3.38E-05
Epoch:29, duration:3287ms, Train_acc:100.0%, Train_loss:0.020, Test_acc:85.5%,Test_loss:0.353, Lr:3.11E-05
Epoch:30, duration:3230ms, Train_acc:100.0%, Train_loss:0.019, Test_acc:85.5%,Test_loss:0.346, Lr:3.11E-05
Epoch:31, duration:3285ms, Train_acc:100.0%, Train_loss:0.019, Test_acc:85.5%,Test_loss:0.335, Lr:2.86E-05
Epoch:32, duration:3255ms, Train_acc:100.0%, Train_loss:0.019, Test_acc:85.5%,Test_loss:0.337, Lr:2.86E-05
Epoch:33, duration:3307ms, Train_acc:100.0%, Train_loss:0.018, Test_acc:85.5%,Test_loss:0.334, Lr:2.63E-05
Epoch:34, duration:3281ms, Train_acc:100.0%, Train_loss:0.017, Test_acc:85.5%,Test_loss:0.323, Lr:2.63E-05
Epoch:35, duration:3249ms, Train_acc:100.0%, Train_loss:0.016, Test_acc:85.5%,Test_loss:0.314, Lr:2.42E-05
Epoch:36, duration:3287ms, Train_acc:100.0%, Train_loss:0.017, Test_acc:84.2%,Test_loss:0.368, Lr:2.42E-05
Epoch:37, duration:3337ms, Train_acc:100.0%, Train_loss:0.016, Test_acc:85.5%,Test_loss:0.328, Lr:2.23E-05
Epoch:38, duration:3367ms, Train_acc:100.0%, Train_loss:0.016, Test_acc:84.2%,Test_loss:0.375, Lr:2.23E-05
Epoch:39, duration:3244ms, Train_acc:100.0%, Train_loss:0.015, Test_acc:84.2%,Test_loss:0.329, Lr:2.05E-05
Epoch:40, duration:3277ms, Train_acc:100.0%, Train_loss:0.015, Test_acc:85.5%,Test_loss:0.295, Lr:2.05E-05

在这里插入图片描述

尝试变更学习率优化器及模型优化器为(SGD和Adam的四种组合),测试集acc几乎无变化
尝试变更初始学习率,尝试变更学习率不动态更新,测试集acc无提升

总结

通过本文学习到几种动态学习率的设置与调用,要想得到一个比较好的模型效果,对模型相关参数进行不同的尝试,获取一个相对适配该案例的参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/249508.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【k8s】使用Finalizers控制k8s资源删除

文章目录 词汇表基本删除操作Finalizers是什么&#xff1f;Owner References又是什么&#xff1f;强制删除命名空间参考 你有没有在使用k8s过程中遇到过这种情况: 通过kubectl delete指令删除一些资源时&#xff0c;一直处于Terminating状态。 这是为什么呢&#xff1f; 本文将…

『OPEN3D』1.5.2 动手实现点云栅格/体素最近邻

本专栏地址: https://blog.csdn.net/qq_41366026/category_12186023.html?spm=1001.2014.3001.5482 NEARBY6实现的voxel可视化 一种NEARBY14实现的可视化voxel

lwIP 细节之五:accept 回调函数是何时调用的

使用 lwIP 协议栈进行 TCP 裸机编程&#xff0c;其本质就是编写协议栈指定的各种回调函数。将你的应用逻辑封装成函数&#xff0c;注册到协议栈&#xff0c;在适当的时候&#xff0c;由协议栈自动调用&#xff0c;所以称为回调。 注&#xff1a;除非特别说明&#xff0c;以下内…

多维时序 | Matlab实现GA-LSTM-Attention遗传算法优化长短期记忆神经网络融合注意力机制多变量时间序列预测

多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实…

C#上位机与欧姆龙PLC的通信01----项目背景

最近&#xff0c;【西门庆】作为项目经理负责一个70万的北京项目&#xff0c;需要在工控系统集成软件开发中和欧 姆龙PLC对接&#xff0c;考虑项目现场情况优先想到了采用FinsTCP通讯协议&#xff0c;接下来就是记录如何一步步实现这些通讯过程的&#xff0c;希望给电气工程师&…

鸿蒙app获取文本控件按钮控件_修改控件名称_按钮触发事件_提示信息显示

鸿蒙app获取文本控件按钮控件_修改控件名称_按钮触发事件_ 点击启动&#xff1a;提示信息显示 package com.example.myapplication.slice;import com.example.myapplication.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; impor…

vivado约束方法8

无交互的逻辑互斥时钟组 逻辑排他性时钟是指在不同源点上定义但共享部分的时钟由于多路复用器或其他组合逻辑&#xff0c;它们的时钟树。时间限制向导识别此类时钟&#xff0c;并建议在它们这样做时直接对其进行时钟组约束除了连接到其共享时钟的逻辑之外&#xff0c;彼此之间…

ADUM1200ARZ数字隔离器:重新定义技术标准

ADUM1200ARZ数字隔离器成为技术进步领域的关键组件。其创新设计和多方面功能重新定义了数字隔离技术的格局&#xff0c;提供了满足不同工业需求的众多功能。让我们通过本文直观的了解ADUM1200ARZ的功能与技术标准。 窄体且符合ROHS&#xff1a;设定新基准 该数字隔离器采用窄体…

【ITRA】赛事方收费标准-2024

一、查看ITRA收费情况 1、赛事方 必须注册赛事方的账户进入ITRA 看到的这个100欧&#xff0c;只是一个起步价格&#xff0c;并不是所有价格 不过这个对于一个赛事方可以cover一年的费用 2、更多费用 想当更大的怨种可以 往下拉满

MySQL数据存储、索引记录

行格式(每行记录) 行格式(每行记录)&#xff1a; 以记录为单位来向表中插入数据的&#xff0c;这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式。 InnoDB 存储引擎4种不同类型的 行格式 &#xff0c;分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行格式。组…

Github与Gitlab

学习目标 能够使用GitHub创建远程仓库并使用能够安装部署GitLab服务器能够使用GitLab创建仓库并使用掌握CI/CD的概念掌握蓝绿部署, 滚动更新,灰度发布的概念 GitHub是目前最火的开源项目代码托管平台。它是基于web的Git仓库&#xff0c;提供公有仓库和私有仓库&#xff0c;但私…

时序分解 | Matlab实现SSA-ICEEMDAN麻雀算法优化ICEEMDAN时间序列信号分解

时序分解 | Matlab实现SSA-ICEEMDAN麻雀算法优化ICEEMDAN时间序列信号分解 目录 时序分解 | Matlab实现SSA-ICEEMDAN麻雀算法优化ICEEMDAN时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现SSA-ICEEMDAN麻雀算法优化ICEEMDAN时间序列信号分解 可…

【基于Python的新闻文本分类系统设计与实现】

基于Python的新闻文本分类系统设计与实现 摘要&#xff1a;1. 引言2. 数据获取与预处理3. 数据分析与可视化4. 文本分类模型设计与实现5. 结果与讨论6. 总结与展望结尾 摘要&#xff1a; 本文介绍了一种基于Python语言、Flask技术以及贝叶斯算法的新闻文本分类系统的设计与实现…

为了吃鸡苦练狙击,避免坑队友自己造一个狙击游戏!

引言 一文教会你造一个简易的狙击游戏。 说到狙击&#xff0c;相信大家都不陌生&#xff0c;无论是影视作品还是网络游戏&#xff0c;都经常能看到狙击枪的身影&#xff0c;最深刻的是它能够从百里之外&#xff0c;一枪爆头。 本文将介绍如何在Cocos Creator中造一个简易的狙…

基于C/C++的libcurl多协议文件传输库dll二次封装开发使用

libcurl 可能是最便携、最强大和最常用的 这个星球上的网络传输库。官方提供的示例&#xff0c;需要在项目中引用到libcurl-imp.lib才能使用。 这里我改造了下工程&#xff0c;将常用的接口导出到了libcurl.dll中方便直接在后续的工程代码中应用&#xff0c;下面可以看到dll常用…

RNN和LSTM学习笔记-初学者

提示&#xff1a; 目录 前言一、RNN介绍二、LSTM介绍总结 前言 提示&#xff1a; 提示&#xff1a; 一、RNN介绍 RNN是一种短时记忆&#xff0c;而LSTM是长短时记忆网络 二、LSTM介绍 总结

用python+opencv+PySimpleGUI实现了一款视频播放器

目录 前言准备工作主要思路主界面视频读取进度条拖拽 源码 前言 本篇将用python实现一个mp4播放器&#xff0c;可以通过windows资源管理器选择需要播放的mp4视频文件或者图片&#xff0c;然后提供播放条的快进回放&#xff0c;播放和暂停功能&#xff1a; 准备工作 python所…

5G工业网关视频传输应用

随着科技的不断进步&#xff0c;5G网络技术已经成为了当前最热门的话题之一。而其中一个引人注目的领域就是5G视频传输和5G工业网关应用。在传统网络通信中&#xff0c;由于带宽和延迟的限制&#xff0c;视频传输常常受到限制&#xff0c;而工业网关应用也存在着链路不稳定、数…

http正向代理测试,nginx反向代理中转正向代理服务器

有3台服务器如下&#xff1a; 192.168.111.201&#xff08;反向代理到正向代理服务器&#xff09; 192.168.111.202&#xff08;正向代理服务器&#xff09; 192.168.111.203&#xff08;目标WEB系统&#xff09; 防火墙网络策略如图所示: 1、192.168.111.200 只能访问 192.168…

主宰无双H5:WIN学习手工服务端通用视频教程及GM授权物品后台,支持三网H5玩法介绍

标题&#xff1a;主宰无双H5&#xff08;游戏源码&#xff09;&#xff1a;WIN学习手工服务端通用视频教程及GM授权物品后台&#xff0c;支持三网H5玩法的百科 一、引言 随着互联网的快速发展&#xff0c;H5游戏逐渐成为人们休闲娱乐的重要方式。主宰无双H5游戏源码作为一款深…