深度学习模型训练痛点及解决方法

1 模型训练基本步骤

进入了AI领域,学习了手写字识别等几个demo后,就会发现深度学习模型训练是十分关键和有挑战性的。选定了网络结构后,深度学习训练过程基本大同小异,一般分为如下几个步骤

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

下面我们来看深度学习模型训练中遇到的难点及如何解决

2 模型训练难点及解决方法

2.1 收敛速度慢

深度学习其实就是一个反复调整模型参数的过程,得力于GPU等硬件性能的提升,使得复杂的深度学习训练成为了可能。收敛速度过慢,训练时间过长,一方面使得相同总训练时间内的迭代次数变少,从而影响准确率,另一方面使得训练次数变少,从而减少了尝试不同超参数的机会。因此,加快收敛速度是一大痛点。那么怎么解决它呢?

2.1.1 设置合理的初始化权重w和偏置b

深度学习通过前向计算和反向传播,不断调整参数,来提取最优特征,以达到预测的目的。其中调整的参数就是weight和bias,简写为w和b。根据奥卡姆剃刀法则,模型越简单越好,我们以线性函数这种最简单的表达式来提取特征,也就是

​ f(x) = w * x + b

深度学习训练时几乎所有的工作量都是来求解神经网络中的w和b。模型训练本质上就是调整w和b的过程,如果将他们初始化为一个合理的值,那么就能够加快收敛速度。怎么初始化w和b呢?

我们一般使用截断的正态分布(也叫高斯分布)来初始化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
)

什么叫截断的正态分布呢,看下图就明白了

左图为标准正态分布,也叫高斯分布,利用TensorFlow中的tf.random_normal()即可得到x取值范围负无穷到正无穷内的值。所有的y值加起来概率为1。初始化w时,我们没必要将w初始化为很大或很小的数。故更倾向于使用截断正态分布,如右图。它和标准正态分布的区别在于,限制了x取值必须在[-2 x stddev, 2 x stddev]之间。

b由于是加和关系,对收敛速度影响不大。我们一般将它初始化为0,如下。

# 偏置量bias,初始化为0,偏置可直接使用常量初始化
def bias_variable(shape, vname):
  initial = tf.constant(0, shape=shape, name=vname)
  return tf.Variable(initial)

2.1.2 优化学习率

模型训练就是不断尝试和调整不同的w和b,那么每次调整的幅度是多少呢,这个就是学习率。w和b是在一定范围内调整的,那么增大学习率不就减少了迭代次数,也就加快了训练速度了吗?路虽长,步子迈大点不就行了吗?非也,步子迈大了可是会扯到蛋的!深度学习中也是如此,学习率太小,会增加迭代次数,加大训练时间。但学习率太大,容易越过局部最优点,降低准确率。

那有没有两全的解决方法呢,有!我们可以一开始学习率大一些,从而加速收敛。训练后期学习率小一点,从而稳定的落入局部最优解。使用Adam,Adagrad等自适应优化算法,就可以实现学习率的自适应调整,从而保证准确率的同时加快收敛速度。

原文链接

猜你喜欢

转载自blog.csdn.net/weixin_40581617/article/details/80537559
今日推荐