深度学习训练技巧总结

参考:

技巧链接一!重要
技巧链接二!重要
技巧链接三!重要

模型训练技巧最直接的就是几个超参数的设置

根据图片大小来选择网络和超参数

如果图片不是很大比如3030,这种情况下做分类就不能用VGG和Resnet这样的网络。此时要么把图像变大要么就是选择小的网络,或者把VGG里pooling的步长设置为1试试,如果类别不多(没有上千),那么直接使用小网络,如果是100100这样的大图片就采用VGG和Resnet这样的大网络。

根据图片类别数和数量来选择batch_size

如果训练样本少,少于1000,那么直接使用全梯度下降,不需要用批梯度下降。用批梯度的目的是为了加快训练速度,所以当训练样本少的时候是没有必要使用批梯度下降的。只是用全梯度下降反向传播一次需要很久的时间,训练起来很慢。若训练类别很多,那么bacth_size一定不要太小,例如若是上千的类别数,那么bacth_size值就设置为为128,否则震荡会很严重。

根据网络规模和loss下降速率来选择学习率

学习率的选择一般是0.001 0.0001 0.00001 0.000001等中的一个值,选择哪个值的最根本的依据是网络很复杂的时候学习率不能太低,否则传到后面的时候就会基本没梯度了。三五层的网络学习率基本要小于1*e^(-5),不然会下降过快导致震荡。初始学习率可以随意选择来尝试试探,如果发现loss下降得过快,那么要减少学习率。如果发现loss降低不下去,就适当增加学习率。

深度学习的训练过程

深度学习的训练过程大同小异,一般可以分为如下几步:

  1. 定义算法公式,也就是神经网络的前向算法,一般使用现成的网络,例如inceptionV4,mobilenet等。
  2. 定义loss,选择优化器,让loss最小。
  3. 对数据迭代训练,让loss最小。
  4. 在测试集或者验证集上对准确率评估

深度学习模型训练过程中常遇到的问题

问题一:收敛速度慢,训练时间长
  1. 深度学习训练过程就是一个不断调参的过程,收敛速度慢、训练时间长会使得相同总训练时间内迭代次数少,从而影响准确率。另外训练次数变少,使得尝试超参数的次数变少。
解决办法一:设置合理的初始化权重和偏置
  1. 深度学习通过前向计算和反向传播,不断调整参数,来提取最优特征。调整的参数就是权重和偏置。根据奥卡姆剃刀法则,模型越简单越好,以线性函数这种最简单的表达式来提取特征。即f(x)=wx+b。深度学习训练时几乎所有的工作量都是用来求解w和b。训练本质也就是调整w和b的过程。
  2. 一般使用截断的正态分布(也叫作高斯分布)来初始化w。
    如下
# 权重weight,标准差0.1。truncated_normal截断的正态分布来初始化weight。权重初始化很有讲究的,会决定学习的快慢
def weight_variable(shape, vname):
  initial = tf.truncated_normal(shape, stddev=0.1, name=vname)
  return tf.Variable(initial)

tf.truncated_normal定义如下

tf.truncated_normal(
    shape,			# 正态分布输出数据结构,1维tensor
    mean=0.0,		# 平均值,默认为0.我们一般取默认值0
    stddev=1.0,		# 标准差
    dtype=tf.float32,		# 输出数据类型
    seed=None,		# 随机分布都会有一个seed来决定分布
    name=None
)
  1. 下图左图为标准正态分布,也叫作高斯分布。利用TensorFlow中的tf.random_normal()可以得到x取值范围从负无穷到正无穷的值。所以的y值加起来为1。初始化w时,没必要将其初始化为很大或者很小的值,所以更倾向于使用截断正态分布,如下图中的右图。截断正态分布和标准正态分布的区别是:限制了x取值必须在[-2 x stddev, 2 x stddev]之间。
  2. f(x)=wx+b,b由于是加和关系,对收敛速度影响不大,一般初始化为0.如下所示
# 偏置量bias,初始化为0,偏置可直接使用常量初始化
def bias_variable(shape, vname):
  initial = tf.constant(0, shape=shape, name=vname)
  return tf.Variable(initial)

解决办法二:优化学习率
  1. ,模型训练就是不断尝试和调试w和b,每次调整的幅度是多少,关系到学习率。w和b是在一定范围内调整的,增大学习率就减少了迭代次数,但学习率太大,也容易越过局部最优点,降低准确率。
  2. 所以,一般采用,一开始学习率大,从而加速收敛,训练后期学习率小一点,从而稳定地落入局部最优点。使用Adam,Adagrad等自适应优化算法,就可以实现学习率的自适应调整。从而保证准确率的同时加快收敛速度。
解决办法三:网络节点输入值正则化batch normalization(批标准化)
  1. 神经网络训练时,每一层的输入分布都在变化,不论输入值是大还是小,学习率都是相同的,这是很浪费效率的,当输入值很小时,为了保证精细调整,学习率不能设置太大,如果让输入值标准化落到某一个范围内,如[0,1]之间,这样就不用为太小的输入值犯愁。
  2. 学习的是输入的特征分布,而不是绝对值,所以可以对每一个mini-batch数据内部进行标准化,使它们规范化到[0,1]之间。这就是bacth normalization正则化。
  3. inceptionV2在每个卷积层后,使用一个BN层,从而使得学习率可以设定为一个较大的值,使用了BN之后的inceptionV2,只需要以前的1/14的迭代次数就能达到之前的准确值,加快了收敛速度。
  4. Normalization时,选的平均值跟标准差希望它代表的是整个training set全体。但是实际上统计整个training set全体的statistics是非常耗费时间的。所以实际上算平均值和标准差的时候,只会在batch里面算。所以batch size一定要够大,如果太小的话Batch Normalization的性能就会很差,因为你没有办法从一个batch里面估测整个data集,可以想象极端case,如果batch size=1,则不能apply BN想法。
解决办法四:采用更先进的网络结构,减少参数量
  1. 训练速度慢,归根结底是网络结构参数多,减少参数量,可以大大加快收敛速度。采用先进的网络结构可以可以用更少的参数数量达到更高的精度。如何用更少的参数数量达到更高的精度,有如下几种方法:

方法一: 使用小卷积核代替大卷积核
VGGNet全部使用33的小卷积核,来代替AlexNet中的1111和55等大卷积核。小卷积核虽然参数量少,但也会带来特征面积捕获过小的问题。inception net认为越往后的卷积层,应该捕获更多更高阶的抽象特征。因此它在靠后的卷积层中使用的55等大面积的卷积核的比率较高,而在前面几层卷积层中,更多使用的是11和33的卷积核。

方法二: 使用两个串联小卷积核来代替大卷积核
inceptionV2中提出两个33的卷积核代替一个55的卷积核,在效果相同的情况下,参数量仅为原先的332/5*5=18/25
方法三: 1 * 1卷积核的使用
1 * 1卷积核是性价比最高的卷积,它在参数量为1的情况下,同样能够提供线性变换、relu激活、输入输出channel变换。是VGGNet提出的1 * 1卷积核。
方法四: 非对称卷积核的使用
inceptionV3中将一个7 * 7的卷积拆分成了一个1 * 7和一个7 * 1的卷积核,卷积效果相同的情况下,参数量大大减小,而且还提高了卷积的多样性。
方法五: depthwise卷积的使用
mobileNet中将一个3 * 3的卷积拆分成了串联的一个3 * 3 depthwise卷积和一个1 * 1正常卷积。对于输入channel为M,输出为N的卷积,正常情况下,每个输出channel均需要M个卷积核对输入的每个channel进行卷积、并叠加。也就是需要M * N个卷积。而在depthwise卷积中,输出channel和输入相同,每个输入channel仅需要一个卷积核,而将channel变换的工作交给了1 * 1卷积核。这个方法在参数量减少到之前的1/9的情况下,精度仍能达到80%。
方法六:全局平均池化代替全连接层
AlexNet和VGGNet中,全连接层几乎占据了90%的参数量,inceptionV1使用全局平均池化来代替最后的全连接层。使得其在

  • 48
    点赞
  • 335
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
训练集数据输入到神经网络中通常需要以下几个步骤: 1. 数据加载:首先,您需要将训练集的数据加载到内存中,可以使用适合您数据类型的工具或库来完成此操作。例如,对于图像数据,您可以使用OpenCV、PIL或TensorFlow等库来加载图像数据。 2. 数据预处理:在将数据输入神经网络之前,通常需要对数据进行预处理。这可能包括将图像数据转换为张量、进行归一化、调整大小或进行数据增强等。您可以使用相应的库和函数来完成这些预处理操作。 3. 数据批处理:为了高效地训练神经网络,通常会将数据划分为小批量进行训练(称为mini-batch)。您可以使用数据生成器、数据迭代器或批处理函数等方法来生成小批量数据,并将其输入到神经网络中。 4. 前向传播:通过将数据传递给神经网络的输入层,经过一系列的计算和变换,网络会生成输出结果。这个过程称为前向传播。您可以调用神经网络模型的前向传播函数或方法来执行此操作。 5. 计算损失:在前向传播之后,您需要计算模型的预测结果与真实标签之间的损失。损失函数的选择取决于您的任务类型,例如交叉熵损失、均方误差等。 6. 反向传播和梯度更新:根据损失值,通过反向传播算法计算每个模型参数的梯度,并使用优化算法(如随机梯度下降)来更新模型参数,以减小损失。 7. 迭代训练:重复执行步骤3至6,将不同的批量数据输入到网络中,并进行前向传播、损失计算、反向传播和梯度更新,直到达到预定的训练轮数或达到停止条件。 这些是将训练集数据输入神经网络的基本步骤。具体实现的代码会根据您使用的深度学习框架和任务类型而有所不同。如果您有具体的任务和深度学习框架,我可以为您提供更具体的代码示例和指导。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值