Hyperparmeter tuning

神经网络和深度学习[1-2]
神经网络和深度学习[1-3]
神经网络和深度学习[1-4]
改善深层神经网络:超参数调试、正则化以及优化【2-1】
改善深层神经网络:超参数调试、正则化以及优化【2-2】
改善深层神经网络:超参数调试、正则化以及优化【2-3】
结构化机器学习项目 3
Ng的深度学习视频笔记,长期更新

3.1 Tuning process

此节讲解关于如何系统组织超参调试过程的技巧,从学习率,momentum,或者是Adam优化算法中的,层数(layers),隐藏层单元的数量(hidden units),学习衰退率(decayRate),还有Mini-batch大小。如下图所示,红色部分框最重要,其次是黄色框部分,然后是紫色框部分,而几乎不用调试,一般为0.9,0.999,
dl0701
调试参数的过程:先用间隔比较大的区域来选取参数,从其中选择比较优的参数,继续缩小范围即可,如下图:
dl0702

3.2 Using an appropriate scale to pick hyperparameters

上一节讲到,随机取值可以提升搜索效率,但是随机取值并不是在有效范围内的随机均匀取值,而是选择合适的标尺,探究这些超参数。
对于隐藏层单元的个数,可以随机的在指定范围内取点,以及选取layers的个数,也是可以随机选取的,但是对于超参数而言不适合。比如假设选取的值在0.0001到1之间,如果随机取点,则有90%的数值落到0.1到1之间,而0.0001到0.1之间只有10%的搜索资源,显然是不合理的,这里不使用线性轴,而是使用如下轴,0.0001~0.001,0.001~0.01,0.01~0.1,0.1~1,然后对每个区域均匀随机取点,这样在0.0001~0.001之间就会有更多的搜索资源可以用。
dl0703
用python如下实现:

1
2
r=-4*np.random.rand()
a=10**r

左边为,右边为.
对于计算指数加权平均值,假设的取值在0.9~0.999之间的某个值(我们要搜索的值),这里回忆一下,取0.9就相当于10个值的平均,取0.999就相当于在1000个值总取平均,因此如果要在该范围内搜索,就不能用线性轴取值,此时可以考虑,这样范围就变成0.001~0.1之间了,用上面的指数即可。这个直观的理解就是,当接近于1时,就会对细微的变化变得很敏感,所以在整个取值过程中,当接近1的区间,需要更加密集的取值。

3.4 Normalizing activations in a network

到现在为止,已经讲到了很多关于如何搜索最优超参数的内容。Batch归一化会使模型的参数搜索问题变得很容易,使神经网络对超参数的选择更加稳定,超参数的范围会更庞大,工作效果会很好。之前讲到过的归一化问题,就是将输入的特征归一化后带来的后果是将椭圆形转变得更圆,这样梯度下降曲线就会沿着最短路径走。但是对于深层网络,每一层的输出相当于下一层的输入,我们并不能保证当前层的输出数据就一定是归一化的,这里我们需要对Z处理,如下图所示,将进行修正【注意这里是对处理,针对的是不同的样本的输出值,对于批量梯度而言】,但是我们不想让隐藏单元总是罕有平均值0和方差1,也许隐藏单元有了不同的分布会有意义,这里需要加上学习参数,其作用是可以随意设置的平均值,这里如果,这样就会回到原来的数值,通过设置的值,可以使你构造含其它平均值和方差的隐藏单元值。通过使用Batch归一化一些隐藏单元值中的平均值和方差(或许你不需要使的其0均值,1方差,而是更大的方差,或者均值),比如输入函数是Sigmoid函数,我们希望数据分散一点,以便能够利用Sigmoid的非线性性,这样方差就不应该是1,这就是为什么有了,你可以确保所有的值可以是你想赋予的任意值,或者它的作用是保证隐藏的单元已使均值和方差标准化,应该是说可以控制均值和方差。
dl0704

3.5 Fitting Batch Norm into a neural network

这节讲Batch在深度网络训练中的拟合,如下图所示,第一层输入的X经过权重后得到的Z,需要作归一化处理,然后进入到激活函数中,作为第二层的输入…
这样网络的参数就是,然后加入新的参数(这里的 和之前的不一样),可以使用梯度更新来变换,即,也可以使用Adam或RMS prop或momentum来更新参数
dl0705
Batch归一化通常和训练集的mini-batch一起使用,应用Batch的归一化,用第一个mini-batch 计算,归一化;然后继续第二个mini-batch…
这里需要注意一点,对于,即,我们归一化的过程是先将的结果变为均值为0,方差为1的数据,然后再用放缩,这就说明不管大小多少,因为不同的样本对应的是相同的(即常数项),即均值会包含该项,而我们归一化后是减去均值,也就是说的作用被抵消,因此做Batch归一化的时候其实可以消除这个参数。
下面是Batch归一化与mini-batch一起使用的梯度下降算法,现在我才有点理解之前为什么会提到更新,以及用上面Adam来更新的意义。
对于每一个Mini-Batch的输入,对其每个隐藏层,前向传播中使用Batch归一化来得到,在反向传播中更新参数,最后更新参数。
dl0706

3.6 Why does Batch Norm work?

为什么Batch归一化会有效果,一个原因是你已经看到如何归一化输入特征值x,使其均值为0,方差为1一样,即让这些特征获得一个相似范围的值,可以加速学习。所以batch归一化起作用的原因,直观一点就是它在做类似的工作。
batch归一化有效的第二个原因是它可以使权重比训练的网络更滞后或者更深。也就是说比如第10层的网络权重相比于第一层的权重更能承受数据集的变化。[不是很明白,下面有解释]
dl0707
举例说明,如上图,假设我们已经在所有黑猫的图像上训练了数据集,如果现在要把此网络用在有色猫上,如下图所示,左边数据集正样本全是黑猫的情况,黑猫数据训练集显示如图中坐标所示(黑色表示负样本,红色表示正样本),有色猫训练集如右边图所示。我们无法期待在左边训练得很好的模型同样在右边运行得很好,即使存在运行都很好的同一个函数,如图中绿色线所示,但是我们期待学习算法会发现这个模型,如果只有左边数据的话。使数据改变分布,叫做covariate shift,这个意思是说如果你已经学到了一些x到y的映射,如果x的分布改变了,那么你可能需要重新训练你的学习算法,在神经网络中,covariate shift会导致模型预测效果变差。那么covariate shift问题是如何应用到神经网络的呢?[感觉这句话放到这好奇怪,也没提到covariate shift问题的解决方案啊,原文是So,how does this problem of covariate shift apply to a neural network?,虽然翻译的没毛病,但是我觉的这句话的意思应该是:那么covariate shift 问题在神经网络上是怎么表现的呢?]
如下图所示的深度网络:
dl0708
从第三层来看学习过程,它从第二层取得输出值,然后使最后的尽量接近真实值。先遮住左边的,第三层的工作是找到一种方式,使这些值映射到。那么可以说是因为参数,使得网络模型不错。
dl0709
现在将网络的左边揭开,这个网络的参数还有,如果这些参数改变的话,也会改变,那么从第三层的角度来看,这些隐藏单元的值在不断改变,这就是神经网络的covariate shift问题。
dl0710
那么batch归一化如何影响这个过程的呢?batch归一化的作用是它减少了隐藏值分布变化的数量【这里意思应该是说隐藏层数据被规范到一个范围】。batch归一化可以确保无论怎么变化,其均值和方差保持不变。它限制了前层参数的更新会影响数值分布的程度,使这些值变得更加稳定,也可以理解成它减弱了前层参数的作用和后层参数的作用之间的联系,使得网络每层都可以自己学习。对于后一层而言,前层不会左右移动太多,这样使得后层学习工作变得更容易。
batch还有一个作用是它有轻微的正则效果,给隐藏层添加了噪声(因为标准差的缩放和减去均值带来的额外噪声),使得后面层不过分依赖任何一个影藏单元,类似dropout的效果。如果用比较大的Mini-batch,这样噪声就减少,减少了正则化的效果。

3.8 Softmax

Softmax用于多分类模型的输出层,之前有讲到过该公式。如下图所示,没有隐藏层,直接使用softmax作为输出层的效果,分别是3分类,4分类,5分类,6分类的例子。每两个类别之间都是线性的:
dl0711
下面介绍Loss function,如下图所示,假设输出层有4个神经元,这里实际为,预测输出为,损失函数使用,可以发现对于中错误的输出行,并不会计算到损失函数中,损失函数只关心正确分类的行对应的概率值,而概率值越大,那么损失函数就越接近于0,也就是说要最小化损失函数,这样正确类别对应的概率才会最大。成本函数如右边所示。
dl0712
虽然最后的输出函数由原来的Sigmoid函数变为现在的Softmax函数,但是在反向传播的过程中,梯度求解并不会有影响,即
可以这样理解,Softmax函数如下:

这里如果C=2,那么Softmax就是一个Sigmoid函数:

只是的行变为C行了,每行的计算过程和之前二分类是一样的。

大作业 with tensorflow

作业地址:Tensorflow Tutorial
数据集:deeplearning.ai
按照作业的顺序,这里先简单的介绍tensorflow的使用,部分摘自tensorflow,然后给出tensorflow训练多分类的代码

tensorflow的核心程序由下面两个分离的部分组成

  1. Building the computational graph.
  2. Running the computational graph.

常量
没有输入,输出为存储的值

1
y_hat = tf.constant(36, name='y_hat') #定义常量,y_hat为36

打印存储的值

1
Tensor("Const:0", shape=(), dtype=int32)

上面并没有输出36,这里我们需要使用Session来运行计算图,得到结果,如下所示:

1
2
sess = tf.Session()
print(sess.run(y_hat))

如果觉得有帮助,给我打赏吧!