【深度学习项目三】ResNet50多分类任务【十二生肖分类】

2023-12-29 20:38

本文主要是介绍【深度学习项目三】ResNet50多分类任务【十二生肖分类】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关文章:
【深度学习项目一】全连接神经网络实现mnist数字识别
【深度学习项目二】卷积神经网络LeNet实现minst数字识别
【深度学习项目三】ResNet50多分类任务【十二生肖分类】
『深度学习项目四』基于ResNet101人脸特征点检测
项目链接:https://aistudio.baidu.com/aistudio/projectdetail/1930877

1. 卷积神经网络简介

1.1 AlexNet

贡献:

  • 引入ReLU作为激活函数
  • Dropout层
  • Max Pooling
  • GPU加速
  • 数据增强(截取、水平翻转)

1.2 VGG

1.3 GoogleNet

全连接层对输入输出大小有限制,用池化层代替没有约束。

1.4 ResNet

  • 残差结构解决梯度消失问题,多个路径前向传播。
  • 层数改变如图左下角,主要是为了减少计算开销,既减少参数。

2. 数据集介绍

按照12生肖在网上”下载的12种动物照片

训练样本量| 7,096张

验证样本量| 639张

测试样本量| 656张

加载使用方式|自定义数据集

2.1 数据标注

数据集分为train、valid、test三个文件夹,每个文件夹内包含12个分类文件夹,每个分类文件夹内是具体的样本图片。

.
├── test|train|valid
│   ├── dog
│   ├── dragon
│   ├── goat
│   ├── horse
│   ├── monkey
│   ├── ox
│   ├── pig
│   ├── rabbit
│   ├── ratt
│   ├── rooster
│   ├── snake
│   └── tiger我们对这些样本进行一个标注处理,最终生成train.txt/valid.txt/test.txt三个数据标注文件。```python
config.py
__all__ = ['CONFIG', 'get']CONFIG = {'model_save_dir': "./output/zodiac",'num_classes': 12,'total_images': 7096,'epochs': 20,'batch_size': 32,'image_shape': [3, 224, 224],'LEARNING_RATE': {'params': {'lr': 0.00375             }},'OPTIMIZER': {'params': {'momentum': 0.9},'regularizer': {'function': 'L2','factor': 0.000001}},'LABEL_MAP': ["ratt","ox","tiger","rabbit","dragon","snake","horse","goat","monkey","rooster","dog","pig",]
}def get(full_path):for id, name in enumerate(full_path.split('.')):if id == 0:config = CONFIGconfig = config[name]return config
import io
import os
from PIL import Image
from config import get# 数据集根目录
DATA_ROOT = 'signs'# 标签List
LABEL_MAP = get('LABEL_MAP')# 标注生成函数
def generate_annotation(mode):# 建立标注文件with open('{}/{}.txt'.format(DATA_ROOT, mode), 'w') as f:# 对应每个用途的数据文件夹,train/valid/testtrain_dir = '{}/{}'.format(DATA_ROOT, mode)# 遍历文件夹,获取里面的分类文件夹for path in os.listdir(train_dir):# 标签对应的数字索引,实际标注的时候直接使用数字索引label_index = LABEL_MAP.index(path)# 图像样本所在的路径image_path = '{}/{}'.format(train_dir, path)# 遍历所有图像for image in os.listdir(image_path):# 图像完整路径和名称image_file = '{}/{}'.format(image_path, image)try:# 验证图片格式是否okwith open(image_file, 'rb') as f_img:image = Image.open(io.BytesIO(f_img.read()))image.load()if image.mode == 'RGB':f.write('{}\t{}\n'.format(image_file, label_index))except:continuegenerate_annotation('train')  # 生成训练集标注文件
generate_annotation('valid')  # 生成验证集标注文件
generate_annotation('test')   # 生成测试集标注文件

2.2 数据集定义

接下来我们使用标注好的文件进行数据集类的定义,方便后续模型训练使用。

2.2.1 导入相关库

import paddle
import numpy as np
from config import get

HWC和CHW区别

  • C代表:输入通道数
  • H/W分别代表图片的高、宽

NCHW

  • N代表样本数

to_tensor

paddle.vision.transforms.to_tensor(pic, data_format=‘CHW’)[源代码]

将 PIL.Image 或 numpy.ndarray 转换成 paddle.Tensor。

  • 形状为 (H x W x C)的输入数据 PIL.Image 或 numpy.ndarray 转换为 (C x H x W)。 如果想保持形状不变,可以将参数 data_format 设置为 ‘HWC’。
  • 同时,如果输入的 PIL.Image 的 mode 是 (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) 其中一种,或者输入的 numpy.ndarray 数据类型是 ‘uint8’,那个会将输入数据从(0-255)的范围缩放到 (0-1)的范围。其他的情况,则保持输入不变。

2.2.2 导入数据集的定义实现

我们数据集的代码实现是在dataset.py中。

import paddle
import paddle.vision.transforms as T
import numpy as np
from config import get
from PIL import Image__all__ = ['ZodiacDataset']# 定义图像的大小
image_shape = get('image_shape') #'image_shape': [3, 224, 224],
IMAGE_SIZE = (image_shape[1], image_shape[2])class ZodiacDataset(paddle.io.Dataset):"""十二生肖数据集类的定义"""def __init__(self, mode='train'):"""初始化函数"""assert mode in ['train', 'test', 'valid'], 'mode is one of train, test, valid.' #判断参数合法性self.data = []"""根据不同模式选择不同的数据标注文件"""with open('signs/{}.txt'.format(mode)) as f:for line in f.readlines():info = line.strip().split('\t')if len(info) > 0:self.data.append([info[0].strip(), info[1].strip()])#进行切分形成数组,每个数组包含图像的地址和labelif mode == 'train':self.transforms = T.Compose([T.RandomResizedCrop(IMAGE_SIZE),    # 随机裁剪大小,裁剪地方不同等于间接增加了数据样本 300*300-224*224T.RandomHorizontalFlip(0.5),        # 随机水平翻转,概率0.5,也是等于得到一个新的图像T.ToTensor(),                       # 数据的格式转换和标准化 HWC => CHW  T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 图像归一化])else:  #评估模式:没必要进行水平翻转增加样本量了,主要是想看看效果self.transforms = T.Compose([T.Resize(256),                 # 图像大小修改T.RandomCrop(IMAGE_SIZE),      # 随机裁剪,T.ToTensor(),                  # 数据的格式转换和标准化 HWC => CHWT.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])   # 图像归一化])def __getitem__(self, index):"""根据索引获取单个样本"""image_file, label = self.data[index]image = Image.open(image_file)
#转成RGB模式,三通道的if image.mode != 'RGB':image = image.convert('RGB')image = self.transforms(image)#得到预处理后的结果return image, np.array(label, dtype='int64')#对label做个数据转换,int类型转成numpydef __len__(self):"""获取样本总数"""return len(self.data)
from dataset import ZodiacDataset

2.3.3 实例化数据集类

根据所使用的数据集需求实例化数据集类,并查看总样本量。

train_dataset = ZodiacDataset(mode='train')
valid_dataset = ZodiacDataset(mode='valid')print('训练数据集:{}张;验证数据集:{}张'.format(len(train_dataset), len(valid_dataset)))

3.模型选择和开发

3.1 网络构建

本次我们使用ResNet50网络来完成我们的案例实践。

1)ResNet系列网络

2)ResNet50结构

3)残差区块

4)ResNet其他版本

network = paddle.vision.models.resnet50(num_classes=get('num_classes'), pretrained=True)
#pretrained=True使用别人已经训练好的预训练模型进行训练网络
model = paddle.Model(network)
model.summary((-1, ) + tuple(get('image_shape')))
-------------------------------------------------------------------------------Layer (type)         Input Shape          Output Shape         Param #    
===============================================================================Conv2D-1        [[1, 3, 224, 224]]   [1, 64, 112, 112]        9,408     BatchNorm2D-1    [[1, 64, 112, 112]]   [1, 64, 112, 112]         256      ReLU-1        [[1, 64, 112, 112]]   [1, 64, 112, 112]          0       MaxPool2D-1     [[1, 64, 112, 112]]    [1, 64, 56, 56]           0       Conv2D-3        [[1, 64, 56, 56]]     [1, 64, 56, 56]         4,096     BatchNorm2D-3     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      ReLU-2         [[1, 256, 56, 56]]    [1, 256, 56, 56]          0       Conv2D-4        [[1, 64, 56, 56]]     [1, 64, 56, 56]        36,864     BatchNorm2D-4     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      Conv2D-5        [[1, 64, 56, 56]]     [1, 256, 56, 56]       16,384     BatchNorm2D-5     [[1, 256, 56, 56]]    [1, 256, 56, 56]        1,024     Conv2D-2        [[1, 64, 56, 56]]     [1, 256, 56, 56]       16,384     BatchNorm2D-2     [[1, 256, 56, 56]]    [1, 256, 56, 56]        1,024     BottleneckBlock-1   [[1, 64, 56, 56]]     [1, 256, 56, 56]          0       Conv2D-6        [[1, 256, 56, 56]]    [1, 64, 56, 56]        16,384     BatchNorm2D-6     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      ReLU-3         [[1, 256, 56, 56]]    [1, 256, 56, 56]          0       Conv2D-7        [[1, 64, 56, 56]]     [1, 64, 56, 56]        36,864     BatchNorm2D-7     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      Conv2D-8        [[1, 64, 56, 56]]     [1, 256, 56, 56]       16,384     BatchNorm2D-8     [[1, 256, 56, 56]]    [1, 256, 56, 56]        1,024     BottleneckBlock-2   [[1, 256, 56, 56]]    [1, 256, 56, 56]          0       Conv2D-9        [[1, 256, 56, 56]]    [1, 64, 56, 56]        16,384     BatchNorm2D-9     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      ReLU-4         [[1, 256, 56, 56]]    [1, 256, 56, 56]          0       Conv2D-10       [[1, 64, 56, 56]]     [1, 64, 56, 56]        36,864     BatchNorm2D-10     [[1, 64, 56, 56]]     [1, 64, 56, 56]          256      Conv2D-11       [[1, 64, 56, 56]]     [1, 256, 56, 56]       16,384     BatchNorm2D-11     [[1, 256, 56, 56]]    [1, 256, 56, 56]        1,024     BottleneckBlock-3   [[1, 256, 56, 56]]    [1, 256, 56, 56]          0       Conv2D-13       [[1, 256, 56, 56]]    [1, 128, 56, 56]       32,768     BatchNorm2D-13     [[1, 128, 56, 56]]    [1, 128, 56, 56]         512      ReLU-5         [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-14       [[1, 128, 56, 56]]    [1, 128, 28, 28]       147,456    BatchNorm2D-14     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      Conv2D-15       [[1, 128, 28, 28]]    [1, 512, 28, 28]       65,536     BatchNorm2D-15     [[1, 512, 28, 28]]    [1, 512, 28, 28]        2,048     Conv2D-12       [[1, 256, 56, 56]]    [1, 512, 28, 28]       131,072    BatchNorm2D-12     [[1, 512, 28, 28]]    [1, 512, 28, 28]        2,048     BottleneckBlock-4   [[1, 256, 56, 56]]    [1, 512, 28, 28]          0       Conv2D-16       [[1, 512, 28, 28]]    [1, 128, 28, 28]       65,536     BatchNorm2D-16     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      ReLU-6         [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-17       [[1, 128, 28, 28]]    [1, 128, 28, 28]       147,456    BatchNorm2D-17     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      Conv2D-18       [[1, 128, 28, 28]]    [1, 512, 28, 28]       65,536     BatchNorm2D-18     [[1, 512, 28, 28]]    [1, 512, 28, 28]        2,048     BottleneckBlock-5   [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-19       [[1, 512, 28, 28]]    [1, 128, 28, 28]       65,536     BatchNorm2D-19     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      ReLU-7         [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-20       [[1, 128, 28, 28]]    [1, 128, 28, 28]       147,456    BatchNorm2D-20     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      Conv2D-21       [[1, 128, 28, 28]]    [1, 512, 28, 28]       65,536     BatchNorm2D-21     [[1, 512, 28, 28]]    [1, 512, 28, 28]        2,048     BottleneckBlock-6   [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-22       [[1, 512, 28, 28]]    [1, 128, 28, 28]       65,536     BatchNorm2D-22     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      ReLU-8         [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-23       [[1, 128, 28, 28]]    [1, 128, 28, 28]       147,456    BatchNorm2D-23     [[1, 128, 28, 28]]    [1, 128, 28, 28]         512      Conv2D-24       [[1, 128, 28, 28]]    [1, 512, 28, 28]       65,536     BatchNorm2D-24     [[1, 512, 28, 28]]    [1, 512, 28, 28]        2,048     BottleneckBlock-7   [[1, 512, 28, 28]]    [1, 512, 28, 28]          0       Conv2D-26       [[1, 512, 28, 28]]    [1, 256, 28, 28]       131,072    BatchNorm2D-26     [[1, 256, 28, 28]]    [1, 256, 28, 28]        1,024     ReLU-9        [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-27       [[1, 256, 28, 28]]    [1, 256, 14, 14]       589,824    BatchNorm2D-27     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-28       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-28    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     Conv2D-25       [[1, 512, 28, 28]]   [1, 1024, 14, 14]       524,288    BatchNorm2D-25    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     BottleneckBlock-8   [[1, 512, 28, 28]]   [1, 1024, 14, 14]          0       Conv2D-29      [[1, 1024, 14, 14]]    [1, 256, 14, 14]       262,144    BatchNorm2D-29     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     ReLU-10       [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-30       [[1, 256, 14, 14]]    [1, 256, 14, 14]       589,824    BatchNorm2D-30     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-31       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-31    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     BottleneckBlock-9  [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-32      [[1, 1024, 14, 14]]    [1, 256, 14, 14]       262,144    BatchNorm2D-32     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     ReLU-11       [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-33       [[1, 256, 14, 14]]    [1, 256, 14, 14]       589,824    BatchNorm2D-33     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-34       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-34    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     
BottleneckBlock-10  [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-35      [[1, 1024, 14, 14]]    [1, 256, 14, 14]       262,144    BatchNorm2D-35     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     ReLU-12       [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-36       [[1, 256, 14, 14]]    [1, 256, 14, 14]       589,824    BatchNorm2D-36     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-37       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-37    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     
BottleneckBlock-11  [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-38      [[1, 1024, 14, 14]]    [1, 256, 14, 14]       262,144    BatchNorm2D-38     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     ReLU-13       [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-39       [[1, 256, 14, 14]]    [1, 256, 14, 14]       589,824    BatchNorm2D-39     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-40       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-40    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     
BottleneckBlock-12  [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-41      [[1, 1024, 14, 14]]    [1, 256, 14, 14]       262,144    BatchNorm2D-41     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     ReLU-14       [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-42       [[1, 256, 14, 14]]    [1, 256, 14, 14]       589,824    BatchNorm2D-42     [[1, 256, 14, 14]]    [1, 256, 14, 14]        1,024     Conv2D-43       [[1, 256, 14, 14]]   [1, 1024, 14, 14]       262,144    BatchNorm2D-43    [[1, 1024, 14, 14]]   [1, 1024, 14, 14]        4,096     
BottleneckBlock-13  [[1, 1024, 14, 14]]   [1, 1024, 14, 14]          0       Conv2D-45      [[1, 1024, 14, 14]]    [1, 512, 14, 14]       524,288    BatchNorm2D-45     [[1, 512, 14, 14]]    [1, 512, 14, 14]        2,048     ReLU-15        [[1, 2048, 7, 7]]     [1, 2048, 7, 7]           0       Conv2D-46       [[1, 512, 14, 14]]     [1, 512, 7, 7]       2,359,296   BatchNorm2D-46      [[1, 512, 7, 7]]      [1, 512, 7, 7]         2,048     Conv2D-47        [[1, 512, 7, 7]]     [1, 2048, 7, 7]       1,048,576   BatchNorm2D-47     [[1, 2048, 7, 7]]     [1, 2048, 7, 7]         8,192     Conv2D-44      [[1, 1024, 14, 14]]    [1, 2048, 7, 7]       2,097,152   BatchNorm2D-44     [[1, 2048, 7, 7]]     [1, 2048, 7, 7]         8,192     
BottleneckBlock-14  [[1, 1024, 14, 14]]    [1, 2048, 7, 7]           0       Conv2D-48       [[1, 2048, 7, 7]]      [1, 512, 7, 7]       1,048,576   BatchNorm2D-48      [[1, 512, 7, 7]]      [1, 512, 7, 7]         2,048     ReLU-16        [[1, 2048, 7, 7]]     [1, 2048, 7, 7]           0       Conv2D-49        [[1, 512, 7, 7]]      [1, 512, 7, 7]       2,359,296   BatchNorm2D-49      [[1, 512, 7, 7]]      [1, 512, 7, 7]         2,048     Conv2D-50        [[1, 512, 7, 7]]     [1, 2048, 7, 7]       1,048,576   BatchNorm2D-50     [[1, 2048, 7, 7]]     [1, 2048, 7, 7]         8,192     
BottleneckBlock-15   [[1, 2048, 7, 7]]     [1, 2048, 7, 7]           0       Conv2D-51       [[1, 2048, 7, 7]]      [1, 512, 7, 7]       1,048,576   BatchNorm2D-51      [[1, 512, 7, 7]]      [1, 512, 7, 7]         2,048     ReLU-17        [[1, 2048, 7, 7]]     [1, 2048, 7, 7]           0       Conv2D-52        [[1, 512, 7, 7]]      [1, 512, 7, 7]       2,359,296   BatchNorm2D-52      [[1, 512, 7, 7]]      [1, 512, 7, 7]         2,048     Conv2D-53        [[1, 512, 7, 7]]     [1, 2048, 7, 7]       1,048,576   BatchNorm2D-53     [[1, 2048, 7, 7]]     [1, 2048, 7, 7]         8,192     
BottleneckBlock-16   [[1, 2048, 7, 7]]     [1, 2048, 7, 7]           0       
AdaptiveAvgPool2D-1  [[1, 2048, 7, 7]]     [1, 2048, 1, 1]           0       Linear-1           [[1, 2048]]            [1, 12]            24,588     
===============================================================================
Total params: 23,585,740
Trainable params: 23,479,500
Non-trainable params: 106,240
-------------------------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 261.48
Params size (MB): 89.97
Estimated Total Size (MB): 352.02
-------------------------------------------------------------------------------{'total_params': 23585740, 'trainable_params': 23479500}

4.模型训练和优化

CosineAnnealingDecay

class paddle.optimizer.lr.CosineAnnealingDecay(learningrate, Tmax, etamin=0, lastepoch=- 1, verbose=False)[源代码]

该接口使用 cosine annealing 的策略来动态调整学习率。

η t = η min ⁡ + 1 2 ( η max ⁡ − η min ⁡ ) ( 1 + cos ⁡ ( T c u r T max ⁡ π ) ) , T c u r ≠ ( 2 k + 1 ) T max ⁡ η t + 1 = η t + 1 2 ( η max ⁡ − η min ⁡ ) ( 1 − cos ⁡ ( 1 T max ⁡ π ) ) , T c u r = ( 2 k + 1 ) T max ⁡ \begin{aligned} \eta_{t} &=\eta_{\min }+\frac{1}{2}\left(\eta_{\max }-\eta_{\min }\right)\left(1+\cos \left(\frac{T_{c u r}}{T_{\max }} \pi\right)\right), & T_{c u r} \neq(2 k+1) T_{\max } \\ \eta_{t+1} &=\eta_{t}+\frac{1}{2}\left(\eta_{\max }-\eta_{\min }\right)\left(1-\cos \left(\frac{1}{T_{\max }} \pi\right)\right), & T_{c u r}=(2 k+1) T_{\max } \end{aligned} ηtηt+1=ηmin+21(ηmaxηmin)(1+cos(TmaxTcurπ)),=ηt+21(ηmaxηmin)(1cos(Tmax1π)),Tcur=(2k+1)TmaxTcur=(2k+1)Tmax

ηmax 的初始值为 learning_rate, Tcur 是SGDR(重启训练SGD)训练过程中的当前训练轮数。SGDR的训练方法可以参考文档 SGDR: Stochastic Gradient Descent with Warm Restarts. 这里只是实现了 cosine annealing 动态学习率,热启训练部分没有实现。

参数:

  • learning_rate (float) - 初始学习率,也就是公式中的 ηmax ,数据类型为Python float。
  • T_max (float|int) - 训练的上限轮数,是余弦衰减周期的一半
  • eta_min (float|int, 可选) - 学习率的最小值,即公式中的 ηmin 。默认值为0。
  • last_epoch (int,可选) - 上一轮的轮数,重启训练时设置为上一轮的epoch数。默认值为 -1,则为初始学习率。
  • verbose (bool,可选) - 如果是 True ,则在每一轮更新时在标准输出 stdout 输出一条信息。默认值为 False

返回:用于调整学习率的 CosineAnnealingDecay 实例对象

Momentum

class paddle.optimizer.Momentum(learningrate=0.001, momentum=0.9, parameters=None, usenesterov=False, weightdecay=None, gradclip=None, name=None)[源代码]

该接口实现含有速度状态的Simple Momentum 优化器
该优化器含有牛顿动量标志,公式更新如下:
更新公式如下:

参数:

  • learning_rate (float|_LRScheduler, 可选) -
    学习率,用于参数更新的计算。可以是一个浮点型值或者一个_LRScheduler类,默认值为0.001
  • momentum (float, 可选) - 动量因子
  • parameters (list, 可选) -指定优化器需要优化的参数。在动态图模式下必须提供该参数;在静态图模式下默认值为None,这时所有的参数都将被优化。
  • use_nesterov (bool, 可选) - 赋能牛顿动量,默认值False。
  • weight_decay (float|Tensor, 可选) - 权重衰减系数,是一个float类型或者shape为[1]
    ,数据类型为float32的Tensor类型。默认值为0.01
  • grad_clip (GradientClipBase, 可选) – 梯度裁剪的策略,支持三种裁剪策略: cn_api_fluid_clip_GradientClipByGlobalNorm 、 cn_api_fluid_clip_GradientClipByNorm 、 cn_api_fluid_clip_GradientClipByValue 。 默认值为None,此时将不进行梯度裁剪。
  • name (str, 可选)- 该参数供开发人员打印调试信息时使用,具体用法请参见 Name ,默认值为None

API参考链接
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/optimizer/momentum/Momentum_cn.html

EPOCHS = get('epochs')
BATCH_SIZE = get('batch_size')def create_optim(parameters):step_each_epoch = get('total_images') // get('batch_size')lr = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=get('LEARNING_RATE.params.lr'),T_max=step_each_epoch * EPOCHS)return paddle.optimizer.Momentum(learning_rate=lr,parameters=parameters,weight_decay=paddle.regularizer.L2Decay(get('OPTIMIZER.regularizer.factor'))) #正则化来提升精度# 模型训练配置
model.prepare(create_optim(network.parameters()),  # 优化器paddle.nn.CrossEntropyLoss(),        # 损失函数paddle.metric.Accuracy(topk=(1, 5))) # 评估指标# 训练可视化VisualDL工具的回调函数
visualdl = paddle.callbacks.VisualDL(log_dir='visualdl_log')# 启动模型全流程训练
model.fit(train_dataset,            # 训练数据集valid_dataset,            # 评估数据集epochs=EPOCHS,            # 总的训练轮次batch_size=BATCH_SIZE,    # 批次计算的样本量大小shuffle=True,             # 是否打乱样本集verbose=1,                # 日志展示格式save_dir='./chk_points/', # 分阶段的训练模型存储路径callbacks=[visualdl])     # 回调函数使用

top1 表示预测的第一个答案就是正确答案的准确率

top5 表示预测里面前五个包含正确答案的准确率

预测可视化:

4.1模型存储

将我们训练得到的模型进行保存,以便后续评估和测试使用。

model.save(get('model_save_dir'))

5 模型评估和测试

5.1 批量预测测试

5.1.1 测试数据集

predict_dataset = ZodiacDataset(mode='test')
print('测试数据集样本量:{}'.format(len(predict_dataset)))
from paddle.static import InputSpec# 网络结构示例化
network = paddle.vision.models.resnet50(num_classes=get('num_classes'))# 模型封装
model_2 = paddle.Model(network, inputs=[InputSpec(shape=[-1] + get('image_shape'), dtype='float32', name='image')])# 训练好的模型加载
model_2.load(get('model_save_dir'))# 模型配置
model_2.prepare()# 执行预测
result = model_2.predict(predict_dataset)
import matplotlib.pyplot as plt
# 样本映射
LABEL_MAP = get('LABEL_MAP')def show_img(img, predict):plt.figure()plt.title('predict: {}'.format(LABEL_MAP[predict_label]))image_file, label = predict_dataset.data[idx]image = Image.open(image_file)plt.imshow(image)plt.show()# 随机取样本展示
indexs = [50,150 , 250, 350, 450, 00]for idx in indexs:predict_label = np.argmax(result[0][idx])real_label = predict_dataset[idx][1]show_img(real_label,predict_label )print('样本ID:{}, 真实标签:{}, 预测值:{}'.format(idx, LABEL_MAP[real_label], LABEL_MAP[predict_label]))#或者不定义函数:
"""
import matplotlib.pyplot as plt
# 样本映射
LABEL_MAP = get('LABEL_MAP')# # 抽样展示
indexs = [50,150 , 250, 350, 450, 00]for idx in indexs:predict_label = np.argmax(result[0][idx])real_label = predict_dataset[idx][1]print('样本ID:{}, 真实标签:{}, 预测值:{}'.format(idx, LABEL_MAP[real_label], LABEL_MAP[predict_label]))image_file, label = predict_dataset.data[idx]image = Image.open(image_file)plt.figure()plt.title('predict: {}'.format(LABEL_MAP[predict_label]))plt.imshow(image)plt.show()
"""

在这里插入图片描述
样本ID:50, 真实标签:monkey, 预测值:monkey
在这里插入图片描述
样本ID:150, 真实标签:ratt, 预测值:ratt

在这里插入图片描述
样本ID:450, 真实标签:tiger, 预测值:tiger

6 模型部署

model_2.save('infer/zodiac', training=False)

总结

  • 本次讲解了四种卷积神经网络的由来,以及采用resnet50实现了十二生肖分类项目

  • 本次项目重点在于数据集自定义、以及创建优化器。来使模型更加灵活可改动也提高准确率和有助于模型快速收敛。

  • 这里还是推荐模型封装不要采用高层api 自己用Sub Class写法或者用Sequential写法。尝试写写看虽然层数比较多!

这篇关于【深度学习项目三】ResNet50多分类任务【十二生肖分类】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/550656

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss