【飞桨】phy的PaddlePaddle深度学习实践week1

day1初步认识神经网络

神经网络的基本概念

神经元:神经网络中的每个节点,由加权和非线性变换(激活函数)组成。
多层链接:大量神经元按层次分布,形成多层结构成为神经网络
前向计算:由输入->输出。

模型结构三要素

模型假设->评价函数(损失函数)->优化算法

模型损失和优化

Loss函数以参数(w, b) 为自变量,令Loss取极小值使得更符合样本数据。
方法1:取导求极小
方法2: 梯度下降法
步骤:
1.随机选一组初始值。
2.选取下一个点使得Loss’<Loss,且下降趋势尽量快->梯度的反方向是函数值下降最快方向
3.重复步骤2直到损失函数几乎不下降。

day2

梯度下降的代码实现

定义损失函数如下:
L = 1 2 N ∑ i = 1 n ( y i − z i ) 2 . L =\frac{1}{2N}\sum_{i=1}^n (y_i-z_i)^2. L=2N1i=1n(yizi)2.
其中, z i = ∑ j = 0 n x i j ∗ w j + b z_i=\sum_{j=0}^nx_i^j*w_j+b zi=j=0nxijwj+b是网络对第i个样本的预测值(共有n个参数)

梯度 g r a d i e n t = ( ∂ L ∂ w j , . . . ∂ L ∂ w n , ∂ L ∂ b ) gradient=(\frac{\partial L}{\partial w_j}, ...\frac{\partial L}{\partial w_n},\frac{\partial L}{\partial b}) gradient=(wjL,...wnL,bL)
带入损失函数,求偏导得
∂ L ∂ w j = 1 N ∑ i = 1 N ( z i − y i ) x i j \frac{\partial L}{\partial w_j}=\frac{1}{N}\sum_{i=1}^N(z_i-y_i)x_i^j wjL=N1i=1N(ziyi)xij
∂ L ∂ b = 1 N ∑ i = 1 N ( z i − y i ) \frac{\partial L}{\partial b}=\frac{1}{N}\sum_{i=1}^N(z_i-y_i) bL=N1i=1N(ziyi)
得梯度值。梯度方向是LOSS函数下降最快的方向,根据梯度函数更新参数值。
代码实现步骤:
前向计算->计算损失值->计算梯度->更新参数值

使用飞桨重写房价模型

飞桨支持的两种深度学习建模编写方式。

  1. 静态图模式(声明式编程范式,类比C++):先编译后执行。用户需预先定义完整的网络结构,再对网络结构进行编译优化后,才能执行获得计算结果,性能更好,便于部署。

  2. 动态图模式(命令式编程范式,类比Python):解析式的执行方式。用户无需预先定义完整的网络结构,每写一行网络代码,即可同时获得计算结果,方便调试。

数据处理不依赖框架,与使用Python构建相同。
在飞桨框架下实现梯度下降只需定义SGD。前向计算、计算损失和反向传播梯度,每个操作1-2行代码即可实现。

day3-4手写数字识别

使用飞桨框架构建神经网络的步骤:

数据处理->模型设计->训练配置->训练过程->模型保存

数据处理

使用飞桨提供的多个封装好的数据集API可直接获取处理好的训练集。

trainset = paddle.dataset.mnist.train()
train_reader = paddle.batch(trainset, batch_size=8)

将MINIST数据集分批次,每批读取数量为8.

for batch_id, data in enumerate(train_reader()):
    img_data = np.array([x[0] for x in data]).astype('float32')
    label_data = np.array([x[1] for x in data]).astype('float32'print("图像数据形状和对应数据为:", img_data.shape, img_data[0])
    print("图像标签形状和对应数据为:", label_data.shape, label_data[0])
    break

迭代读取数据。有一个还待解决的问题就是如何打乱数据顺序,以便提高训练的有效性。这里我在实践作业里尝试多次,因为不太掌握数据读取器的使用方法,目前还未能修改成功。

模型设计

  • 网络模型
    面对不同的问题,应采用不同的模型进行训练。房价预测是简单的线性问题,而数字识别却涉及到二维像素的关系信息,因此应选用更复杂的模型,也就是卷积神经网络。
    在这里插入图片描述
    比较经典全连接神经网络和卷积神经网络的损失变化,可以发现卷积神经网络的损失值下降更快,且最终的损失值更小。
  • 损失函数
    房价预测是回归任务,而手写数字识别是分类任务,使用均方误差作为分类任务的损失函数存在逻辑和效果上的缺欠。
    房价可以是大于0的任何浮点数,而手写数字识别的输出只可能是0-9之间的10个整数,相当于一种标签。
    在房价预测的案例中,由于房价本身是一个连续的实数值,因此以模型输出的数值和真实房价差距作为损失函数(loss)是符合道理的。但对于分类问题,真实结果是分类标签,而模型输出是实数值,导致以两者相减作为损失不具备物理含义。
    分类任务本质上是“某种特征组合下的分类概率”,在模型输出为分类标签的概率时,直接以标签和概率做比较也不够合理,人们更习惯使用交叉熵误差作为分类问题的损失衡量。 交叉熵损失函数的设计是基于最大似然思想:最大概率得到观察结果的假设是真的。

训练配置

单GPU训练

飞桨动态图通过fluid.dygraph.guard(place=None)里的place参数,设置在GPU上训练还是CPU上训练。

with fluid.dygraph.guard(place=fluid.CPUPlace()) 
with fluid.dygraph.guard(place=fluid.CUDAPlace(0))

分布式训练

  • 模型并行
    将一个网络模型拆分为多份,拆分后的模型分到多个设备上(GPU)训练,每个设备的训练数据是相同的。
    应用场景:模型架构过大,网络模型的结构设计相对独立。
  • 数据并行
    读取多份数据,读取到的数据输入给多个设备(GPU)上的模型,每个设备上的模型是完全相同的,飞桨采用的就是这种方式。

由于输入数据不同,计算出的梯度是不同的,训练过程中应同步各设备上的梯度。梯度同步有两种方式:PRC通信方式和NCCL2通信方式(Nvidia Collective multi-GPU Communication Library)。

训练过程

优化的五个关键环节:

  1. 计算分类准确率,观测模型训练效果。
    交叉熵损失函数只能作为优化目标,无法直接准确衡量模型的训练效果。准确率可以直接衡量训练效果,但由于其离散性质,不适合做为损失函数优化神经网络。
  2. 检查模型训练过程,识别潜在问题。
    如果模型的损失或者评估指标表现异常,通常需要打印模型每一层的输入和输出来定位问题,分析每一层的内容来获取错误的原因。
  3. 加入校验或测试,更好评价模型效果。
    理想的模型训练结果是在训练集和验证集上均有较高的准确率,如果训练集上的准确率高于验证集,说明网络训练程度不够;如果验证集的准确率高于训练集,可能是发生了过拟合现象。通过在优化目标中加入正则化项的办法,解决过拟合的问题。
  4. 加入正则化项,避免模型过拟合。
    飞桨框架支持为整体参数加入正则化项,这是通常的做法。此外,飞桨框架也支持为某一层或某一部分的网络单独加入正则化项,以达到精细调整参数训练的效果。
  5. 可视化分析。
    用户不仅可以通过打印或使用matplotlib库作图,飞桨还提供了更专业的可视化分析工具VisualDL,提供便捷的可视化分析方法。

保存模型

将训练好的模型保存到磁盘文件的方法。应用程序可以随时加载模型,完成预测任务。但是在日常训练工作中,我们会遇到一些突发情况,导致训练过程主动或被动的中断。飞桨支持从上一次保存状态开始继续训练,只要我们随时保存训练过程中的模型状态,就不用从初始状态重新训练。

进行恢复训练的程序不仅要保存模型参数,还要保存优化器参数。这是因为某些优化器含有一些随着训练过程变换的参数,例如Adam, AdaGrad等优化器采用可变学习率的策略,随着训练进行会逐渐减少学习率。这些优化器的参数对于恢复训练至关重要。
要点:

  • 保存模型时同时保存模型参数和优化器参数。
  • 恢复参数时同时恢复模型参数和优化器参数。

总结

通过这几天的学习,我对利用飞桨完成一个深度学习模型有了一个初步的了解和实践。在讲师们的指导下,每日完成打卡作业和学习笔记,我不仅感觉到开始踏入一个全新,有趣,实用的领域,也感受到自己一点一点进步的快乐。接下来还会和同学们一起学习,大家都加油呀!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值