IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【飞浆AI创造营】五 深度学习模型训练和关键参数调优详解 -> 正文阅读

[人工智能]【飞浆AI创造营】五 深度学习模型训练和关键参数调优详解

这次课的干货很多!!更像是paddle的一个tutorial,详细介绍了各种任务模型的用法。本次课从下面四个角度入手:模型选择、模型训练、超参优化、效果展示

模型选择

通常深度学习任务可以分为简单的回归任务、分类任务,以及更加困难的场景任务(目标检测、图像分割、文本生成、语音合成、强化学习等)。

paddle对此提供了丰富的模型库:

模型训练

可以分为两种:

基于高层API训练模型

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

import paddle

# 使用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)

?

Epoch 120/120
step 391/391 [==============================] - loss: 1.3216 - acc_top1: 0.6175 - acc_top5: 0.9607 - 311ms/step

Eval begin...
step 79/79 [==============================] - loss: 0.6662 - acc_top1: 0.6014 - acc_top5: 0.9587 - 92ms/step        
Eval samples: 10000

使用PaddleX训练模型

详细可以参考paddleX文档

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

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

超参优化

超参优化的基本概念

超参数

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

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

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

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

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

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

我们在使用某一网络时,一般是比较好的论文中出现过的,是证明过的,当然也可以直接套用,然后在这个基础上,调参。

可是如果识别的领域不同,比如同样是LeNet网络,在解决手写数字识别时使用的超参数能得到很好的效果,但是在做眼疾识别时,因为数据集的不同,虽然使用同样的超参数,但是效果可能并不理想。

目前不存在?种通用的关于正确策略的共同认知,这也是超参数调节的"玄学"之处。

  • 使用提前停止来确定训练的迭代次数
for epoch in range(MAX_EPOCH):
	// 训练代码
	print('{}[TRAIN]epoch {}, iter {}, output loss: {}'.format(timestring, epoch, i, loss.numpy()))
	if ():
		break
	model.train()

那么这个if条件判断就十分重要了,这里有两种方案:

  1. 分类准确率不再提升时
  2. loss降到一个想要的范围时
  3. 分类准确率不再提升时

我们需要再明确?下什么叫做分类准确率不再提升,这样方可实现提前停止。

我们知道,分类准确率在整体趋势下降的时候仍旧会抖动或者震荡。如果我们在准确度刚开始下降的时候就停止,那么肯定会错过更好的选择。?种不错的解决方案是如果分类准确率在?段时间内不再提升的时候终止。

当然这块用loss也是可以的,loss也是一个评判标准。

因为网络有时候会在很长时间内于?个特定的分类准确率附近形成平缓的局面,然后才会有提升。如果你想获得相当好的性能,第一种方案(分类准确率不再提升时)的规则可能就会太过激进了 —— 停止得太草率。

而本方案(loss降到一个想要的范围时)能很好地解决这一问题,但随之而来的问题就是不知不觉地又多了一个超参数,实际应用上,这个用于条件判断的loss值的选择也很困难。

  • 让学习率从高逐渐降低

我们?直都将学习速率设置为常量。但是,通常采用可变的学习速率更加有效。

如果学习率设置的过低,在训练的前期,训练速度会非常慢;而学习率设置地过高,在训练的后期,又会产生震荡,降低模型的精度:

所以最好是在前期使用一个较大的学习速率让权重变化得更快。越往后,我们可以降低学习速率,这样可以作出更加精良的调整。

?种自然的观点是使用提前终止的想法。就是保持学习速率为?个常量直到验证准确率开始变差,然后按照某个量下降学习速率。我们重复此过程若干次,直到学习速率是初始值的 1/1024(或者1/1000),然后终止训练。

  • 宽泛策略

在使用神经网络来解决新的问题时,?个挑战就是获得任何?种非寻常的学习,也就是说,达到比随机的情况更好的结果。

也许下面的方法能给你带来某些不一样的启发:

  1. 通过简化网络来加速实验进行更有意义的学习
  2. 通过更加频繁的监控验证准确率来获得反馈

通过简化网络来加速实验进行更有意义的学习

假设,我们第?次遇到 MNIST 分类问题。刚开始,你很有激情,但是当模型完全失效时,你会就得有些沮丧。

此时就可以将问题简化,将十分类问题转化成二分类问题。丢开训练和验证集中的那些除了 0 和 1的那些图像,即我们只识别0和1。然后试着训练?个网络来区分 0 和 1。

这样一来,不仅仅问题比 10 个分类的情况简化了,同样也会减少 80% 的训练数据,这样就多出了 5 倍的加速。同时也可以保证更快的实验,也能给予你关于如何构建好的网络更快的洞察。

通过更加频繁的监控验证准确率来获得反馈

这个方法调的其实是输出:

if i % 200 == 0:
	timestring = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
	print('{}[VALID]epoch {}, iter {}, output loss: {}'.format(timestring, epoch, i, loss.numpy()))

对模型本身并没有任何关系,但是,你能得到更多并且更快地得到反馈,从而快速地实验其他的超参数,或者甚至近同步地进行不同参数的组合的评比。

这一点看似不重要,但对于超参数的调整来说,是很重要的一步

因为在实际的应用中,很容易会遇到神经网络学习不到任何知识的情况。你可能要花费若干天在调整参数上,仍然没有进展。所以在前期的时候,就应该从实验中尽可能早的获得快速反馈。直觉上看,这看起来简化问题和架构仅仅会降低你的效率。而实际上,这样能够将进度加快,因为你能够更快地找到传达出有意义的信号的网络。?旦你获得这些信号,你可以尝试通过微调超参数获得快速的性能提升。

这和人生中很多情况?样 —— 万事开头难。

  • 小批量数据(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()

?

巧用VisualDL

VisualDL文档:https://ai.baidu.com/ai-doc/AISTUDIO/Dk3e2vxg9#visualdl%E5%B7%A5%E5%85%B7

完整示例代码请参考:VisualDL2.2全新升级--可视化分析助力模型快速开发

VisualDL可视化流程

创建日志文件:

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

writer = LogWriter("./log/lenet/run1")

训练前记录每组实验的超参数名称和数值,且记录想要展示的模型指标名称

writer.add_hparams({'learning rate':0.0001, 'batch size':64, 'optimizer':'Adam'}, ['train/loss', 'train/acc'])

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

训练过程中插入作图语句,记录accuracy和loss的变化趋势,同时将展示于Scalar和HyperParameters两个界面中:

writer.add_scalar(tag="train/loss", step=step, value=cost)

writer.add_scalar(tag="train/acc", step=step, value=accuracy)

记录每一批次中的第一张图片:

img = np.reshape(batch[0][0], [28, 28, 1]) * 255

writer.add_image(tag="train/input", step=step, img=img)

记录训练过程中每一层网络权重(weight)、偏差(bias)的变化趋势:

writer.add_histogram(tag='train/{}'.format(param), step=step, values=values)

记录分类效果--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)

保存模型结构:

fluid.io.save_inference_model(dirname='./model', feeded_var_names=['img'],target_vars=[predictions], executor=exe)

?

3.权重可视化

InterpretDL源码:https://github.com/PaddlePaddle/InterpretDL

总结与升华

  • 本文最重要的地方在于神经网络工作的基本原理,只有搞懂了原理,才能更好地进行超参优化,得到的模型效果才会更好。
  • 对于模型组网,最重要的是学会使用SubClass形式组网,使用套件虽然简单,但是可定制化程度较低,如果是科研需要,建议一定要学会用SubClass形式组网。
  • 模型训练是本文中最简单的部分,只需要按照文档在操作即可,但是超参数的选择有很多讲究,超参的好坏往往会影响模型的最终结果
  • 效果展示是一个项目的加分项,如果是科研需要,那么你也需要可视化地展示你的工作成果,这也是十分重要的。
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:38:15  更:2021-07-31 16:40:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/22 10:05:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码