百度飞桨第3课|深度学习模型训练和关键参数调优详解

目录

一、模型选择:

1.回归任务

2.分类任务

3.场景任务

二、模型训练:

1.基于高层API训练模型

2.使用PaddleX训练模型

3.模型训练通用配置基本原则

三、超参优化:

1.超参优化的基本概念

2.手动调整超参数的四大方法

四、效果展示:

1.可视化输入与输出

2.巧用VisualDL

3.权重可视化

五、总结与升华:


一、模型选择:

1.回归任务

  • 人脸关键点检测

        人脸关键点检测任务中,输出为 人脸关键点的数量x2,即每个人脸关键点的横坐标与纵坐标。在模型组网时,主要使用2个模块,分别是Inception模块和空间注意力模块。增加空间注意力模块是为了提高模型效果。

        Inception模块

import paddle
import paddle.nn as nn

# GoogLeNet加BN层加速模型收敛
class Inception(nn.Layer): # 定义Inception块(Inception v1)
    def __init__(self,c1, c2, c3, c4):
        super(Inception, self).__init__()

        self.relu = nn.ReLU()
        self.p1_1 = nn.Conv2D(c1[0], c1[1], 1)
        self.p2_1 = nn.Conv2D(c1[0], c2[0], 1)
        self.p2_2 = nn.Conv2D(c2[0], c2[1], 3, padding=1)
        self.p3_1 = nn.Conv2D(c1[0], c3[0], 1)
        self.p3_2 = nn.Conv2D(c3[0], c3[1], 5, padding=2)
        self.p4_1 = nn.MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.p4_2 = nn.Conv2D(c1[0], c4, 1)

    def forward(self, x):
        p1 = self.relu(self.p1_1(x))
        p2 = self.relu(self.p2_2(self.p2_1(x)))
        p3 = self.relu(self.p3_2(self.p3_1(x)))
        p4 = self.relu(self.p4_2(self.p4_1(x)))

        return paddle.concat([p1, p2, p3, p4], axis=1)

        空间注意力模块

import paddle
import paddle.nn as nn

# 空间注意力机制
class SAM_Module(nn.Layer):  
    def __init__(self):  
        super(SAM_Module, self).__init__()  
        self.conv_after_concat = nn.Conv2D(in_channels=2, out_channels=1, kernel_size=7, stride=1, padding=3)  
        self.sigmoid_spatial = nn.Sigmoid()  

    def forward(self, x):  
        # Spatial Attention Module  
        module_input = x  
        avg = paddle.mean(x, axis=1, keepdim=True)  
        mx = paddle.argmax(x, axis=1, keepdim=True)
        mx = paddle.cast(mx, 'float32')
        x = paddle.concat([avg, mx], axis=1)
        x = self.conv_after_concat(x)  
        x = self.sigmoid_spatial(x)  
        x = module_input * x  

        return x  

2.分类任务

  • 图像分类

3.场景任务

        这里说的场景任务是针对某一个特定的场景开发的深度学习任务,相比于回归和分类任务来说,场景任务的难度更高。这里说的场景任务包括但不限于目标检测、图像分割、文本生成、语音合成、强化学习等。

  • 目标检测

        PaddleX里的目标检测模型,这里选择骨干网络为DarkNet53的YOLO-V3模型: 

import paddlex as pdx

yolo_v3 = pdx.det.YOLOv3(
    num_classes=2, 
    backbone='DarkNet53'
)

yolo_v3.get_model_info()
{'version': '1.3.11',
 'Model': 'YOLOv3',
 '_Attributes': {'model_type': 'detector',
  'num_classes': 2,
  'labels': None,
  'fixed_input_shape': None},
 '_init_params': {'num_classes': 2,
  'backbone': 'DarkNet53',
  'anchors': None,
  'anchor_masks': None,
  'ignore_threshold': 0.7,
  'nms_score_threshold': 0.01,
  'nms_topk': 1000,
  'nms_keep_topk': 100,
  'nms_iou_threshold': 0.45,
  'label_smooth': False,
  'train_random_shapes': [320, 352, 384, 416, 448, 480, 512, 544, 576, 608],
  'input_channel': 3},
 'completed_epochs': 0}
  • 人像分割

        基于PaddleX核心分割模型 Deeplabv3+Xcetion65 & HRNet_w18_small_v1 实现人像分割,PaddleX提供了人像分割的预训练模型,可直接使用,当然也可以根据自己的数据做微调。

  • 文字识别

        基于chinese_ocr_db_crnn_mobile实现文字识别,识别图片当中的汉字,该Module是一个超轻量级中文OCR模型,支持直接预测。

import paddlehub as hub
import cv2

ocr = hub.Module(name="chinese_ocr_db_crnn_mobile")
result = ocr.recognize_text(images=[cv2.imread('/home/aistudio/work/OCR/ocrdemo.png')], 
                            output_dir='/home/aistudio/work/OCR/ocr_result', 
                            visualization=True)


 


二、模型训练:

1.基于高层API训练模型

        通过Model.prepare接口来对训练进行提前的配置准备工作,包括设置模型优化器,Loss计算方法,精度计算方法等。

import paddle.vision as vision
import paddle
import paddle.vision.transforms as transforms
from paddle.vision.transforms import Normalize

# 使用paddle.Model完成模型的封装
model = paddle.Model(Net)

# 为模型训练做准备,设置优化器,损失函数和精度计算方式
model.prepare(optimizer=paddle.optimizer.Adam(parameters=model.parameters()),
              loss=paddle.nn.CrossEntropyLoss(),
              metrics=paddle.metric.Accuracy())

# 调用fit()接口来启动训练过程
model.fit(train_dataset,
          epochs=1,
          batch_size=64,
          verbose=1)

normalize = transforms.Normalize(
    [0.4914*255, 0.4822*255, 0.4465*255], [0.2023*255, 0.1994*255, 0.2010*255])

trainTransforms = transforms.Compose([
                transforms.RandomCrop(32, padding=4),
                transforms.RandomHorizontalFlip(), 
                transforms.Transpose(),
                normalize
            ])

testTransforms = transforms.Compose([
                transforms.Transpose(),
                normalize
            ])

trainset = vision.datasets.Cifar10(mode='train', transform=trainTransforms)
trainloader = paddle.io.DataLoader(trainset, batch_size=128, num_workers=0, shuffle=True)
testset = vision.datasets.Cifar10(mode='test', transform=testTransforms)
testloader = paddle.io.DataLoader(testset, batch_size=128, num_workers=0, shuffle=True)

# 调用飞桨框架的VisualDL模块,保存信息到目录中。
callback = paddle.callbacks.VisualDL(log_dir='gMLP_log_dir')

def create_optim(parameters):
    step_each_epoch = len(trainloader) // 128
    lr = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=0.25,
                                                  T_max=step_each_epoch * 120)

    return paddle.optimizer.Adam(learning_rate=lr,
                                 parameters=parameters,
                                 weight_decay=paddle.regularizer.L2Decay(3e-4))

model.prepare(create_optim(model.parameters()),  # 优化器
              paddle.nn.CrossEntropyLoss(),        # 损失函数
              paddle.metric.Accuracy(topk=(1, 5))) # 评估指标

model.fit(trainloader,
          testloader,
          epochs=120,
          eval_freq=2,
          shuffle=True, 
          save_dir='gMLP_case1_chk_points/',
          save_freq=20,
          batch_size=128,
          callbacks=callback,
          verbose=1)

2.使用PaddleX训练模型

        YOLOv3模型的训练接口示例,函数内置了piecewise学习率衰减策略和momentum优化器。

from paddlex.det import transforms
import paddlex as pdx

# 下载和解压昆虫检测数据集
insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz'
pdx.utils.download_and_decompress(insect_dataset, path='./')

# 定义训练和验证时的transforms
# API说明 https://paddlex.readthedocs.io/zh_CN/develop/apis/transforms/det_transforms.html
train_transforms = transforms.Compose([
    transforms.MixupImage(mixup_epoch=250), transforms.RandomDistort(),
    transforms.RandomExpand(), transforms.RandomCrop(), transforms.Resize(
        target_size=608, interp='RANDOM'), transforms.RandomHorizontalFlip(),
    transforms.Normalize()
])

eval_transforms = transforms.Compose([
    transforms.Resize(
        target_size=608, interp='CUBIC'), transforms.Normalize()
])

# 定义训练和验证所用的数据集
# API说明:https://paddlex.readthedocs.io/zh_CN/develop/apis/datasets.html#paddlex-datasets-vocdetection
train_dataset = pdx.datasets.VOCDetection(
    data_dir='insect_det',
    file_list='insect_det/train_list.txt',
    label_list='insect_det/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
    data_dir='insect_det',
    file_list='insect_det/val_list.txt',
    label_list='insect_det/labels.txt',
    transforms=eval_transforms)

# 可使用VisualDL查看训练指标,参考https://paddlex.readthedocs.io/zh_CN/develop/train/visualdl.html
num_classes = len(train_dataset.labels)

# API说明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#paddlex-det-yolov3
model = pdx.det.YOLOv3(num_classes=num_classes, backbone='DarkNet53')
# API说明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#id1
# 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html
model.train(
    num_epochs=270,
    train_dataset=train_dataset,
    train_batch_size=8,
    eval_dataset=eval_dataset,
    learning_rate=0.000125,
    lr_decay_epochs=[210, 240],
    save_dir='output/yolov3_darknet53',
    use_vdl=True)

3.模型训练通用配置基本原则

  1. 每个输入数据的维度要保持一致,且一定要和模型输入保持一致。
  2. 配置学习率衰减策略时,训练的上限轮数一定要计算正确。
  3. BatchSize不宜过大,太大容易内存溢出,且一般为2次幂。

三、超参优化:

1.超参优化的基本概念

超参数

模型的超参数指的是模型外部的配置变量,是不能通过训练的进行来估计其取值不同的,且不同的训练任务往往需要不同的超参数。

超参数不同,最终得到的模型也是不同的。

一般来说,超参数有:学习率迭代次数网络的层数每层神经元的个数等等。

常见的超参数有以下三类:

  1. 网络结构,包括神经元之间的连接关系、层数、每层的神经元数量、激活函数的类型等 .
  2. 优化参数,包括优化方法、学习率、小批量的样本数量等 .
  3. 正则化系数

实践中,当你使⽤神经⽹络解决问题时,寻找好的超参数其实是一件非常困难的事情,对于刚刚接触的同学来说,都是"佛系调优",这也是一开始就"入土"的原因,没有依据的盲目瞎调肯定是不行的。

2.手动调整超参数的四大方法

1)使用提前停止来确定训练的迭代次数

2)让学习率从高逐渐降低

3)宽泛策略

4)小批量数据(mini-batch)大小不必最优


四、效果展示:

1.可视化输入与输出

        直接可视化输入与输出是最直接的方法。

import numpy as np
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(PATH_TO_IMAGE)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

plt.imshow(img)
plt.show()

2.巧用VisualDL

VisualDL可视化流程

  1. 创建日志文件:

*为了快速找到最佳超参,训练9个不同组合的超参实验,创建方式均相同如下:

writer = LogWriter("./log/lenet/run1")
  1. 训练前记录每组实验的超参数名称和数值,且记录想要展示的模型指标名称
writer.add_hparams({'learning rate':0.0001, 'batch size':64, 'optimizer':'Adam'}, ['train/loss', 'train/acc'])

注意:这里记录的想要展示的模型指标为'train/loss'和 'train/acc',后续切记需要用add_scalar接口记录对应数值

  1. 训练过程中插入作图语句,记录accuracy和loss的变化趋势,同时将展示于Scalar和HyperParameters两个界面中:
writer.add_scalar(tag="train/loss", step=step, value=cost)

writer.add_scalar(tag="train/acc", step=step, value=accuracy)
  1. 记录每一批次中的第一张图片:
img = np.reshape(batch[0][0], [28, 28, 1]) * 255

writer.add_image(tag="train/input", step=step, img=img)
  1. 记录训练过程中每一层网络权重(weight)、偏差(bias)的变化趋势:
writer.add_histogram(tag='train/{}'.format(param), step=step, values=values)
  1. 记录分类效果--precision & recall曲线:
writer.add_pr_curve(tag='train/class_{}_pr_curve'.format(i),
                     labels=label_i,
                     predictions=prediction_i,
                     step=step,
                     num_thresholds=20)

writer.add_roc_curve(tag='train/class_{}_pr_curve'.format(i),
                     labels=label_i,
                     predictions=prediction_i,
                     step=step,
                     num_thresholds=20)
  1. 保存模型结构:
fluid.io.save_inference_model(dirname='./model', feeded_var_names=['img'],target_vars=[predictions], executor=exe)

3.权重可视化


五、总结与升华:

  • 本文最重要的地方在于神经网络工作的基本原理,只有搞懂了原理,才能更好地进行超参优化,得到的模型效果才会更好。
  • 对于模型组网,最重要的是学会使用SubClass形式组网,使用套件虽然简单,但是可定制化程度较低,如果是科研需要,建议一定要学会用SubClass形式组网。
  • 模型训练是本文中最简单的部分,只需要按照文档在操作即可,但是超参数的选择有很多讲究,超参的好坏往往会影响模型的最终结果
  • 效果展示是一个项目的加分项,如果是科研需要,那么你也需要可视化地展示你的工作成果,这也是十分重要的

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark 参数调优是指通过调整Spark的配置参数,优化Spark应用程序的性能和稳定性。Spark参数调优需要根据具体的应用场景和数据特点进行调整,以达到最佳的性能和效果。 常见的Spark参数调优包括: 1. 内存管理参数调优:包括堆内存大小、堆外内存大小、内存分配模式等。 2. 并行度参数调优:包括并行度、分区数、线程数等。 3. 磁盘IO参数调优:包括磁盘读写缓存大小、磁盘读写并发数等。 4. 网络参数调优:包括网络带宽、网络拓扑结构、网络传输协议等。 5. 数据倾斜参数调优:包括数据倾斜检测、数据倾斜解决方案等。 6. 调度器参数调优:包括任务调度策略、任务优先级、任务队列等。 7. 序列化参数调优:包括序列化方式、序列化缓存大小等。 8. 其他参数调优:包括JVM参数、日志级别、调试模式等。 在进行Spark参数调优时,需要注意以下几点: 1. 首先要了解应用程序的数据特点和处理流程,根据实际情况进行参数调优。 2. 调优时要进行实验验证,通过对比不同参数配置下的性能指标,选择最优的参数配置。 3. 调优时要注意参数之间的相互影响,不能单独调整某个参数而忽略其他参数的影响。 4. 调优时要注意系统资源的限制,不能过度调优导致系统资源不足或者过度消耗系统资源。 总之,Spark参数调优是一个复杂的过程,需要根据具体情况进行调整,不断优化Spark应用程序的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值