深度学习基础--ResNet50V2网络的讲解,ResNet50V2的复现(pytorch)以及用复现的ResNet50做鸟类图像分类

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

前言

  • 如果说最经典的神经网络,ResNet肯定是一个,从ResNet发布后,作者又进行修改,命名为ResNe50v2,这篇文章是本人学习ResNe50v2的学习笔记,并且用pytorch复现了ResNet50V2,后面用它做了一个鸟类图像分类demo,与上一篇ResNet50相比,效果明显好了不少。
  • ResNet讲解: https://blog.csdn.net/weixin_74085818/article/details/145786990?spm=1001.2014.3001.5501
  • 欢迎收藏 + 关注,本人将会持续更新

文章目录

  • 1、简介
    • 与ResNet对比
    • 不同残差结构
    • 激活函数的尝试
    • 小结
  • 2、ResNet50V2搭建
    • 1、导入数据
      • 1、导入库
      • 2、查看数据信息和导入数据
      • 3、展示数据
      • 4、数据导入
      • 5、数据划分
      • 6、动态加载数据
    • 2、构建ResNet-50V2网络
    • 3、模型训练
      • 1、构建训练集
      • 2、构建测试集
      • 3、设置超参数
    • 4、模型训练
    • 5、结果可视化

1、简介

与ResNet对比

在这里插入图片描述

👀 改进点:

  • 原始resnet结果:先进行卷积,在进行BN和激活函数,最后执行addtion与RelU
  • 修改版本:先进行BN和激活函数,把addtion后的ReLU放到了残差内部,改进后残差内有两个ReLU

不同残差结构

何凯明大神产实力不同的残差结构,如下:

在这里插入图片描述

最后结果

在这里插入图片描述

发现还是原始的残差结构效果最好

激活函数的尝试

这个部分主要是激活函数、BN层的位置。

在这里插入图片描述

结果

在这里插入图片描述

发现最好的是**(e)**结果

小结

通过学习,发现可以从两个角度修改模型:

  • 激活函数、BN层的位置,如:数据处理中的位置,不同位置效果也不同。
  • 残差结构:原始版本是恒等映射,但是也有可能不同的残差也会有不同的效果。

2、ResNet50V2搭建

1、导入数据

1、导入库

import torch  
import torch.nn as nn
import torchvision 
import numpy as np 
import os, PIL, pathlib # 设置设备
device = "cuda" if torch.cuda.is_available() else "cpu"device 
'cuda'

2、查看数据信息和导入数据

数据目录有两个文件:一个数据文件,一个权重。

data_dir = "./data/"data_dir = pathlib.Path(data_dir)# 类别数量
classnames = [str(path).split("\\")[0] for path in os.listdir(data_dir)]classnames
['bird_photos', 'resnet50_weights_tf_dim_ordering_tf_kernels.h5']

3、展示数据

import matplotlib.pylab as plt  
from PIL import Image # 获取文件名称
data_path_name = "./data/bird_photos/Bananaquit/"
data_path_list = [f for f in os.listdir(data_path_name) if f.endswith(('jpg', 'png'))]# 创建画板
fig, axes = plt.subplots(2, 8, figsize=(16, 6))for ax, img_file in zip(axes.flat, data_path_list):path_name = os.path.join(data_path_name, img_file)img = Image.open(path_name) # 打开# 显示ax.imshow(img)ax.axis('off')plt.show()


在这里插入图片描述

4、数据导入

from torchvision import transforms, datasets # 数据统一格式
img_height = 224
img_width = 224 data_tranforms = transforms.Compose([transforms.Resize([img_height, img_width]),transforms.ToTensor(),transforms.Normalize(   # 归一化mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225] )
])# 加载所有数据
total_data = datasets.ImageFolder(root="./data/", transform=data_tranforms)

5、数据划分

# 大小 8 : 2
train_size = int(len(total_data) * 0.8)
test_size = len(total_data) - train_size train_data, test_data = torch.utils.data.random_split(total_data, [train_size, test_size])

6、动态加载数据

batch_size = 32 train_dl = torch.utils.data.DataLoader(train_data,batch_size=batch_size,shuffle=True
)test_dl = torch.utils.data.DataLoader(test_data,batch_size=batch_size,shuffle=False
)
# 查看数据维度
for data, labels in train_dl:print("data shape[N, C, H, W]: ", data.shape)print("labels: ", labels)break
data shape[N, C, H, W]:  torch.Size([32, 3, 224, 224])
labels:  tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0])

2、构建ResNet-50V2网络

在这里插入图片描述

上一篇文章中,本人搭建的网络有点啰嗦,很多都是一步一步的,但是这一篇,这一种搭建,比较优雅,因为这个利用了三个网络模块很多相同点,依据这个搭建而成。

ResNet50V2搭建方式和ResNet50一样,只是残差堆积不同

注意:参数,这个神经网络有很多参数,注意别错了。

import torch.nn.functional as F'''  
conv_shortcut: 采用什么样的残差连接,对应上面图的1、3模块
filters: 输出通道数
卷积核:默认为3
'''
class Block2(nn.Module):def __init__(self, in_channel, filters, kernel_size=3, stride=1, conv_shortcut=False):super().__init__()# 第一个,preact,对应上图的前两层,bn、reluself.preact = nn.Sequential(nn.BatchNorm2d(in_channel),nn.ReLU(True))# 判断是否需要使用残差连接,上图展示的网络中,有3个模块,有两个有残差连接,有一个没有,没有的那一块卷积核为 1self.shortcut = conv_shortcutif self.shortcut:   # 对应上图的第一块网络结构残差连接self.short = nn.Conv2d(in_channel, 4 * filters, kernel_size=1, stride=stride, padding=0, bias=False)  # padding默认为0, 4 * filtersz看源码得出,  输出通道else:self.short = nn.MaxPool2d(kernel_size=1, stride=stride, padding=0) if stride > 1 else nn.Identity()  # nn.Identity() 对输入的数据X,不做任何操作# 后面结果,三个模块都一样,我把他分层三个模块# 模块一,看源码self.conv1 = nn.Sequential(nn.Conv2d(in_channel, filters, kernel_size=1, stride=1, bias=False),nn.BatchNorm2d(filters),nn.ReLU(True))# 模块二self.conv2 = nn.Sequential(nn.Conv2d(filters, filters, kernel_size=kernel_size, stride=stride, padding=1, bias=False),nn.BatchNorm2d(filters),nn.ReLU(True))# 模块三self.conv3 = nn.Conv2d(filters, 4 * filters, kernel_size=1, stride=1)def forward(self, x):# 数据x1 = self.preact(x)if self.shortcut:  # 这个时候,对应对一个模块x2 = self.short(x1)  # 这个时候输入的是 x1else:x2 = self.short(x)  # 这个对应上面网络图第三个, 用的输入 x x1 = self.conv1(x1)x1 = self.conv2(x1)x1 = self.conv3(x1)x = x1 + x2  # 合并return x# 堆积
class Stack2(nn.Module):def __init__(self, in_channel, filters, blocks, stride=2):  # blocks代表上图中最左网络图,残差堆积 中 层数super().__init__()self.conv = nn.Sequential()# 上面网络图中,最左部分,残差堆积是很相似的self.conv.add_module(str(0), Block2(in_channel, filters, conv_shortcut=True))   # 参数,名字 + 模块# 中间层for i in range(1, blocks - 1):  # 上面一层去除,中间剩下 blocks - 2self.add_module(str(i), Block2(4 * filters, filters))  # 上一层输出:4 * filters,这一层回归filtersself.conv.add_module(str(blocks-1), Block2(4 * filters, filters, stride=stride))  # 这里的stride不一样def forward(self, x):x = self.conv(x)return xclass ResNet50V2(nn.Module):def __init__(self,include_top=True, # 是否需要包含最定层preact=True,  # 是否需要预激活use_bias=True,  # 卷积层是否用偏置input_shape=[224, 224, 3],classes=1000,  # 类别数量pooling=None):super().__init__()# 上图神经网络,最左边,最顶层, ZeroPad是感受野参数self.conv1 = nn.Sequential() self.conv1.add_module('conv', nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=use_bias))  # 这里的标准化,激活函数是可选的if not preact:self.conv1.add_module('bn', nn.BatchNorm2d(64))self.conv1.add_module('relu', nn.ReLU())self.conv1.add_module('max_pool', nn.MaxPool2d(kernel_size=3, stride=2, padding=1))# 上图神经网络,最左边,中间层self.conv2 = Stack2(64, 64, 3)self.conv3 = Stack2(256, 128, 4)self.conv4 = Stack2(512, 256, 6)self.conv5 = Stack2(1024, 512, 3, stride=1)  # 这些层数量变换挺有意思的self.last = nn.Sequential()if preact:self.last.add_module('bn', nn.BatchNorm2d(2048))self.last.add_module('relu', nn.ReLU(True))if include_top:self.last.add_module('avg_pool', nn.AdaptiveAvgPool2d((1, 1)))self.last.add_module('flatten', nn.Flatten())self.last.add_module('fc', nn.Linear(2048, classes))else:if pooling=='avg':self.last.add_module('avg_pool', nn.AdaptiveAvgPool2d((1, 1)))elif pooling=='max':self.last.add_module('max_pool', nn.AdaptiveAMaxPool2d((1, 1)))def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)x = self.conv4(x)x = self.conv5(x)x = self.last(x)return xmodel = ResNet50V2(classes=len(classnames)).to(device)model
ResNet50V2((conv1): Sequential((conv): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3))(max_pool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False))(conv2): Stack2((conv): Sequential((0): Block2((preact): Sequential((0): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(conv1): Sequential((0): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1)))(2): Block2((preact): Sequential((0): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): MaxPool2d(kernel_size=1, stride=2, padding=0, dilation=1, ceil_mode=False)(conv1): Sequential((0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1))))(1): Block2((preact): Sequential((0): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1))))(conv3): Stack2((conv): Sequential((0): Block2((preact): Sequential((0): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(conv1): Sequential((0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1)))(3): Block2((preact): Sequential((0): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): MaxPool2d(kernel_size=1, stride=2, padding=0, dilation=1, ceil_mode=False)(conv1): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1))))(1): Block2((preact): Sequential((0): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1)))(2): Block2((preact): Sequential((0): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1))))(conv4): Stack2((conv): Sequential((0): Block2((preact): Sequential((0): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(conv1): Sequential((0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1)))(5): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): MaxPool2d(kernel_size=1, stride=2, padding=0, dilation=1, ceil_mode=False)(conv1): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1))))(1): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1)))(2): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1)))(3): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1)))(4): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1))))(conv5): Stack2((conv): Sequential((0): Block2((preact): Sequential((0): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(conv1): Sequential((0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1)))(2): Block2((preact): Sequential((0): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1))))(1): Block2((preact): Sequential((0): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(1): ReLU(inplace=True))(short): Identity()(conv1): Sequential((0): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv2): Sequential((0): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True))(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1))))(last): Sequential((bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(avg_pool): AdaptiveAvgPool2d(output_size=(1, 1))(flatten): Flatten(start_dim=1, end_dim=-1)(fc): Linear(in_features=2048, out_features=2, bias=True))
)

3、模型训练

1、构建训练集

def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)batch_size = len(dataloader)train_acc, train_loss = 0, 0 for X, y in dataloader:X, y = X.to(device), y.to(device)# 训练pred = model(X)loss = loss_fn(pred, y)# 梯度下降法optimizer.zero_grad()loss.backward()optimizer.step()# 记录train_loss += loss.item()train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()train_acc /= sizetrain_loss /= batch_sizereturn train_acc, train_loss

2、构建测试集

def test(dataloader, model, loss_fn):size = len(dataloader.dataset)batch_size = len(dataloader)test_acc, test_loss = 0, 0 with torch.no_grad():for X, y in dataloader:X, y = X.to(device), y.to(device)pred = model(X)loss = loss_fn(pred, y)test_loss += loss.item()test_acc += (pred.argmax(1) == y).type(torch.float).sum().item()test_acc /= sizetest_loss /= batch_sizereturn test_acc, test_loss

3、设置超参数

loss_fn = nn.CrossEntropyLoss()  # 损失函数     
learn_lr = 1e-4             # 超参数
optimizer = torch.optim.Adam(model.parameters(), lr=learn_lr)   # 优化器

4、模型训练

train_acc = []
train_loss = []
test_acc = []
test_loss = []epoches = 10for i in range(epoches):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)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)# 输出template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}')print(template.format(i + 1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))print("Done")
Epoch: 1, Train_acc:96.9%, Train_loss:0.289, Test_acc:100.0%, Test_loss:0.117
Epoch: 2, Train_acc:100.0%, Train_loss:0.025, Test_acc:100.0%, Test_loss:0.011
Epoch: 3, Train_acc:100.0%, Train_loss:0.007, Test_acc:100.0%, Test_loss:0.006
Epoch: 4, Train_acc:100.0%, Train_loss:0.004, Test_acc:100.0%, Test_loss:0.003
Epoch: 5, Train_acc:100.0%, Train_loss:0.003, Test_acc:100.0%, Test_loss:0.003
Epoch: 6, Train_acc:100.0%, Train_loss:0.002, Test_acc:100.0%, Test_loss:0.002
Epoch: 7, Train_acc:100.0%, Train_loss:0.002, Test_acc:100.0%, Test_loss:0.002
Epoch: 8, Train_acc:100.0%, Train_loss:0.002, Test_acc:100.0%, Test_loss:0.001
Epoch: 9, Train_acc:100.0%, Train_loss:0.001, Test_acc:100.0%, Test_loss:0.001
Epoch:10, Train_acc:100.0%, Train_loss:0.001, Test_acc:100.0%, Test_loss:0.001
Done

5、结果可视化

import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息epochs_range = range(epoches)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 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= Loss')
plt.show()


在这里插入图片描述


效果比ResNet50好

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TikTok隐私保护措施:确保用户安全

TikTok隐私保护措施:确保用户安全 在这个信息爆炸的时代,社交媒体平台的隐私保护问题日益成为公众关注的焦点。TikTok,作为全球领先的短视频平台,拥有庞大的用户群体,因此,其隐私保护措施显得尤为重要。本…

FFmpeg-chapter3-读取视频流(原理篇)

ffmpeg网站:About FFmpeg 1 库介绍 (1)libavutil是一个包含简化编程函数的库,包括随机数生成器、数据结构、数学例程、核心多媒体实用程序等等。 (2)libavcodec是一个包含音频/视频编解码器的解码器和编…

【Redis】Mac系统一键安装redis

要在 macOS 上一键安装 Redis,可以使用 Homebrew(一个流行的包管理工具)来简化安装过程。下面是可以执行的安装脚本: 安装脚本: #!/bin/bash# 检查 Homebrew 是否已安装,如果没有安装,则安装 …

P1149 [NOIP 2008 提高组] 火柴棒等式c/c++

P1149 [NOIP 2008 提高组] 火柴棒等式c/c 题目描述 给你 n 根火柴棍,你可以拼出多少个形如 ABC 的等式?等式中的 A、B、C 是用火柴棍拼出的整数(若该数非零,则最高位不能是 0)。用火柴棍拼数字 0∼9 的拼法如图所示&a…

七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)

七星棋牌源码 是一款运营级的棋牌产品,覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区,支持 安卓、iOS 双端,并且 全开源。这个版本是 修复优化后的二开版本,新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…

安全模块设计:token服务、校验注解(开启token校验、开启签名校验、允许处理API日志)、获取当前用户信息的辅助类

文章目录 引言pom.xmlI 校验注解ApiValidationII token服务TokenService获取当前用户信息的辅助类III 域登录接口响应数据登陆用户信息引言 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/PO…

贪心算法精品题

1.找钱问题 本题的贪心策略在于我们希望就可能的保留作用大的5元 class Solution { public:bool lemonadeChange(vector<int>& bills) {std::map<int ,int> _map;for(auto ch:bills){if(ch 5) _map[ch];else if(ch 10){if(_map[5] 0) return false;else{_m…

辛格迪客户案例 | 鼎康生物电子合约系统(eSign)项目

01 案例企业 鼎康(武汉)生物医药有限公司于2013年06月19日成立 &#xff0c;是一家总部位于湖北武汉的CDMO公司&#xff0c;坚持以客户为中心&#xff0c;以及时、经济和高质量为服务导向。鼎康生物拥有先进的150,000平方英尺的生产厂房&#xff0c;生产设施位于中国武汉的Bio…

多个pdf合并成一个pdf的方法

将多个PDF文件合并优点&#xff1a; 能更容易地对其进行归档和备份.打印时可以选择双面打印&#xff0c;减少纸张的浪费。比如把住宿发票以及滴滴发票、行程单等生成一个pdf&#xff0c;双面打印或者无纸化办公情况下直接发送给财务进行存档。 方法: 利用PDF24 Tools网站 …

算法-数据结构(图)-迪杰斯特拉最短逻辑算法( Dijkstra)

迪杰斯特拉算法&#xff08;Dijkstras Algorithm&#xff09; 是一种用于计算单源最短路径的经典算法&#xff0c;由荷兰计算机科学家 艾兹赫尔迪杰斯特拉&#xff08;Edsger W. Dijkstra&#xff09; 于1956年提出。它的主要目标是找到从图中的某个源节点到所有其他节点的最短…

windows设置暂停更新时长

windows设置暂停更新时长 win11与win10修改注册表操作一致 &#xff0c;系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值&#xff0c;名称为FlightSettingsMaxPauseDays 根据需求填写数…

降维攻击!PCA与随机投影优化高维KNN

引言&#xff1a;高维数据的“冰山困境” 假设你正在处理一个电商平台的商品图片分类任务&#xff1a;每张图片被提取为1000维的特征向量&#xff0c;100万条数据的距离计算让KNN模型陷入“维度地狱”——计算耗时长达数小时&#xff0c;且内存占用超过10GB。 破局关键&#…

在ubuntu 24.04.2 通过 Kubeadm 安装 Kubernetes v1.31.6

文章目录 1. 简介2. 准备3. 配置 containerd4. kubeadm 安装集群5. 安装网络 calico 插件 1. 简介 本指南介绍了如何在 Ubuntu 24.04.2 LTS 上安装和配置 Kubernetes 1.31.6 集群&#xff0c;包括容器运行时 containerd 的安装与配置&#xff0c;以及使用 kubeadm 进行集群初始…

信刻光盘安全隔离与信息交换系统让“数据摆渡”安全高效

随着数据传输、存储及信息技术的飞速发展&#xff0c;信息安全保护已成为重中之重。各安全领域对跨网数据交互的需求日益迫切&#xff0c;数据传输的安全可靠性成为不可忽视的关键。为满足业务需求并遵守保密规范&#xff0c;针对于涉及重要秘密信息&#xff0c;需做到安全的物…

6.6.5 SQL访问控制

文章目录 GRANT授予权限REVOKE回收权限 GRANT授予权限 GRANT语句可以给用户授予权限&#xff0c;基本格式是GRANT 权限 TO 用户。在授权时&#xff0c;WITH GRANT OPTION是可选项&#xff0c;有此句话&#xff0c;被授予权限的用户还能把权限赋给其他用户。 REVOKE回收权限 RE…

蓝桥真题讲解

目录 第一题 题目链接 题目解析 代码原理 代码编写 本题总结 第二题 题目链接 题目解析 代码原理 代码编写 本题总结 第三题 题目链接 题目解析 代码原理 代码编写 本题总结 第一题 题目链接 题目解析 代码原理 图一 图二 图二中的红色字&#xff0c;请仔…

Allegro PCB元件库文件引起的问题-看不见器件,但是不能预览,也就不能放置了

PCB元件库必须包含PCB&#xff08;.psm, .dra)文件&#xff0c;和PAD&#xff08;.pad)文件 在Allegro里Path设置注意事项&#xff1a; 针对psmpath & padpath会有多个文件夹地址的情况。在放一个新的元件到PCB&#xff0c;需要把对应的元件的PCB & PAD地址都放在第一…

Prompt Engineering for Large Language Models

题目 大型语言模型的快速工程 简介 随着 OpenAI 的 ChatGPT 和 Google 的 Bard 等软件的普及&#xff0c;大语言模型&#xff08;LLM&#xff09;已经渗透到生活和工作的许多方面。例如&#xff0c;ChatGPT 可用于提供定制食谱&#xff0c;建议替换缺失的成分。它可用于起草研…

python-leetcode-使用最小花费爬楼梯

746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 解法 1&#xff1a;动态规划&#xff08;O(n) 时间&#xff0c;O(n) 空间&#xff09; class Solution:def minCostClimbingStairs(self, cost: List[int]) -> int:n len(cost)dp [0] * (n 1) # 额外多…

服务器IPMI用户名、密码批量检查

背景 大规模服务器部署的时候&#xff0c;少不了较多的网管和监测平台&#xff0c;这些平台会去监控服务器的性能、硬件等指标参数&#xff0c;为了便于管理和控制&#xff0c;则需要给服务器IPMI带外管理添加较多的用户&#xff0c;这就需要对较多的服务器检查所对应的IPMI用…