深度学习 有两个非常重要的特性:多层和非线性
非线性:
线性模型的输出结果为输入的加权和。
线性模型的最大特点是任意线性模型的组合仍然还是线性模型
。所以,只通过线性变化,任意层的全连接神经网络和单层神经网络的表达能力没有什么区别,而且他们都是线性模型。
对于非线性可分问题,线性模型效果不好。
可以使用激活函数
实现去线性化,通过将每个神经元的输出通过一个非线性函数可是实现去线性化,同时还可以加入偏置项。
常用的非线性激活函数:ReLU函数、sigmoid函数和tanh函数。在Tensorflow中可使用:tf.nn.relu
、tf.sigmoid
和tf.tanh
表示。
多层:
多层神经网络可以解决异或运算。
深层神经网络有组合特征提取的功能,对于不易提取特征的向量有很大的帮助。
损失函数
神经网络模型的效果及优化的目标是通过损失函数(loss function)定义的。
- 对于二分类问题可以通过设置阈值来进行分类。
- 对于多分类问题,通常的方法是设置n个输出节点,其中n为类别的个数,对于每一个样例,神经网络得到一个n维数组作为输出结果。
如何判断一个输出向量和期望的向量之间有多近呢?
- 在分类问题中,通常使用
交叉熵(corss entropy)
评判,交叉熵刻画了两个概率分布之间的距离,交叉熵越小,两个概率分布越接近。但是神经网络的输出却不一定是一个概率分布,Tensorflow中通常使用Softmax回归作为一个额外的处理层将神经网络的输出变成一个概率分布(将参数去掉了)。
Tensorflow将交叉熵和softmax进行了统一封装,tf.nn.softmax_cross_entropy_with_logits(y, y_)
,y代表原始神经网络的输出,y_给出了标准答案。在只有一个正确答案的分类问题中,Tensorflow提供了tf.nn.spare_softmax_cross_entropy_with_logits()
进一步加速计算过程。 - 对于回归问题,神经网络一般只有一个输出节点(预测值),常用的损失函数是
均方误差(MSE,mean squared error)
。
Tensorflow中可通过tf.reduce_mean(tf.square(y_ - y)
实现。
Tensorflow还可以优化任意的自定义的损失函数。
神经网络优化方法
梯度下降算法主要用于优化单个参数的取值,而反向传播算法给出了一个高效的方式在所有的参数上使用梯度下降算法。
在实际应用中,梯度下降算法
是最常用的神经网络的优化方法,梯度下降算法会迭代更新参数theta,不断沿着梯度的反方向让参数朝着总损失更小的方向更新。
- 梯度下降算法并不能保证被优化的函数达到全局最优解,只有损失函数为凸函数时,梯度下降算法才能保证达到全局最优。
- 梯度下降算法计算时间太长,因为在每一轮迭代中要计算全部训练数据上的损失函数。
为了加速训练过程,可以使用随机梯度下降算法(stochastic gradient descent)
,在每一轮的迭代中,SGD随机优化某一条训练数据上的损失函数,但使用SGD优化的神将网络甚至可能无法达到局部最优。
为了综合以上二者的优缺点,是以应用中一般采用二者的折中算法——每次计算一小部分训练数据的损失函数。
神经网络的进一步优化
学习率的设置:
在训练过程中,需要设置学习率(learning rate)
控制参数更新的速度。使模型在训练的前期快速接近较优解,又可以保证模型训练后期不会出现太大的波动,从而更快接近局部最优。
- 如果更新幅度过大,可能导致参数在极优值的两侧来回移动或者发散。
- 当学习率过小时,虽然能收敛,但是大大降低了优化速度。
Tensorflow使用一种灵活的学习率设置方法——指数衰减法。
tf.train.exponential_decay()
实现了指数衰减学习率。
global_step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(
0.1, global_step, 100, 0.96, staircase=True)
learning_step = tf.train.GradientDescentOptimizer(learning_rate).
minimize(my_loss, global_step=global_step)
设定初始学习速率为0.1,指定了staircase=True,所以每 训练100轮后学习率乘以0.96。在minimize()中传入了global_step将自动更新global_step参数,从而使得学习率也得到了相应更新。
过拟合问题:
避免过拟合,常用的方法是正则化(regularization)
,其思想是在损失函数中加入刻画模型复杂程度的指标。
一般来说,模型的复杂度只由权重w决定,常用的刻画模型复杂度的函数R(w)
有两种:
- L1正则化,L1正则化可以让参数变得更稀疏(更多w=0),这样可以达到类似特征选取的功能。同时L1的计算公式不可导。
- L2正则化,L2不会让参数变得更稀疏,因为当参数很小时,比如w=0.001,这个参数的平方基本就可以忽略了,于是不会进步将其调整为0。L2正则化公式可导,所有优化更加简洁。
Tensorflow中可以优化带正则化的损失函数:
w = tf.Variable(rf.randon_mormal([2,1])
loss = rf.reduce_mean(tf.square(y_ - y) +
tf.contrib.layers.l2_regularization(lambda)(w)
loss的第二部分就是正则化,防止模型过度拟合训练数据中的随机噪声。lambda表示正则化项的权重,w为需要计算正则化的损失参数。也可以使用L1正则化,tf.contrib.layers.l2_regularization(lambda)(w)
。
滑动平滑模型:
使用滑动平均模型在一定程度上可以提高模型在测试数据上的表现。
Tensorflow使用tf.train.ExponentialMovingAverage()来实现滑动平均模型。