吴恩达深度学习系列课程随记——Course2Week3

1.调试处理

调试什么:

学习率α是最重要的、最需要调节的超参数;其次是Momentum的β、隐藏单元和batch size;应用Adam算法时,一般不调节他的几个参数。

如何调试:

早期使用网格图枚举超参数组合,但不同超参数的重要性不同,并不应该如此枚举。我们可以随机选择点来测试。

策略:从粗糙到精细,即依据好结果出现的位置不断缩小搜索范围

2.为超参数选择合适的范围

层数、每层单元数:

数轴上你需要的范围均匀取值

学习率α:

记为10^r,让r在数轴上你需要的范围均匀取值

β:

如果需要在类似0.9-0.999的范围搜索,让r在数轴上你需要的范围均匀取值,结果取1-10^r

3.超参数调试实践:Pandas vs Caviar

两种搜索合适超参数的方式:

第一,计算资源不够,无法同时试验大量模型的情况。人们观察模型一段时间的表现,根据表现调整超参数,继续观察-调整。

第二,计算资源足够。人们同时试验大量模型,观察他们的学习曲线,直接选择最好的那一个。

第一种就叫Pandas(熊猫),第二种叫Caviar(鱼子酱)

4.归一化网络的激活函数

Batch归一化(Batch Norm):

归一化a来获取更好的效果,实际上归一化的是z。

具体过程如下(这里省略了层数的上标[l]):

\mu =\frac{1}{m}\sum z^{(i)}

\sigma ^{2}=\frac{1}{m}\sum (z^{(i)}-\mu )^{2}

z^{(i)}_{norm}=\frac{z^{(i)}-\mu}{\sqrt{\sigma^{2}+\epsilon}}

这时,每一个分量都有了均值0和方差1,但也许隐藏单元有不同分布会有意义,因此我们再处理:

\tilde{z}^{(i)}=\gamma z^{(i)}_{norm}+\beta

γ和β是可以调整的参数,在梯度下降类的算法中,也会在每次迭代中更新。

通过这两个参数,显然我们可以随意调整每一层中z的均值、方差。

5.将Batch Norm拟合进神经网络

应用上一节的算法即可。

注意这里的β们和之前Adam等算法的β没有关系。

应用时我们会发现,无论z=wx+b中b是多少,事实上归一化中都会被消去,因此如果使用Batch Norm,我们可以取消b这个参数

另外β^[l]和γ^[l]的维数都是(n^[l],1),对应每一层的每个单元其实都有不同的值

6.Batch Norm为什么奏效?

第一,类似对x的归一化,它可以加速学习

第二,在你训练网络的过程中,数据的分布可能改变了,这使得你需要重新训练网络,称为“Covariate shift”。体现在神经网络中,就是说前层的参数w和b会影响后层的a。

而Batch Norm归一化了方差和均值,一定程度上减弱这些影响,使各层显得更稳定,而且更加独立,这利于加速整体学习。

第三,Batch Norm有轻微的正则化效果。类似dropout,其调整过程给数据增加了噪声。迫使后层的单元对前层单元的依赖减小。你可以将它和dropout一起使用来获得更强的正则化效果。这里提到一个性质,更大的mini-batch会减弱dropout的效果。

最后,注意Batch Norm一次只能处理一个mini-batch。

7.测试时的Batch Norm(存疑)

你可能无法同时处理整个mini-batch的所有样本,因此需要用其他方法来获得μ和σ^2:指数加权平均数

你逐一处理每个mini-batch内的所有样本,每处理一个mini-batch,你将得到一个μ和σ^2,利用指数加权平均数来平均已经处理过的mini-batch的μ和σ^2,最后得到对于已经处理的所有mini-batch的μ和σ^2,利用它来进行最后的归一化。

8.Softmax回归

这是logistic回归的一般形式,用来处理多分类问题。

对应的神经网络中,其输出层有C个,表示需要把数据分成C类,输出值代表数据属于某一类的概率,其和应当为1,最大的那个就是你需要的类别对应的概率。

最后一层之前的处理与之前的神经网络没有很大不同,但最后一层要使用softmax激活函数:

Z^{[l]}=W^{[l]}a^{[l-1]}+b^{[l]}

t=e^{Z^{[l]}}

注意这里t的维数是C*1

a^{[l]}=\frac{t}{\sum t_{i}}

a的维数也是C*1,代表数据属于每一类的概率

9.训练一个Softmax分类器

hardmax:

区别于softmax,会把z的最大分量变为1,其他的变为0,再处理

损失函数:

L(\hat{y},y)=-\sum y_{j}log\hat{y_{j}}

在多分类问题的标记y中,只有表示正确的分类的那个分量是1,其他都是0,整个Y矩阵是C*m的

那么要最小化损失函数,实际上就是最大化正确分类的那个log项,即最大化那个yhat。

10.深度学习框架

对大多数人而言,从零开始实现所有算法不现实,因此我们需要框架。

选择标准:便于编程、运行速度、是否真的开放

11.TensorFlow

导入需要的包:

import numpy as np
import tensorflow as tf

定义参数w:

w = tf.Variable(0,dtype = tf.float32)

定义损失函数:

cost=tf.add(tf.add(w**2,tf.multiply(-10.,w)),25)

梯度下降法(学习率0.01):

train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)

惯用表达式:

init = tf.global_variables_initializer() 
# get a TensorFlow session
session = tf.Session() 
# initialize global variables
session.run(init)

让TensorFlow评估一个变量: 
 

session.run(w)

上面的这一行将 w 初始化为 0,并定义损失函数,如果用print输出,会得到0

运行梯度下降:

for i in range(1000):
    session.run(train)

事实上,tensorflow重载了运算符,下面两种写法等价:

cost=tf.add(tf.add(w**2,tf.multiply(-10.,w)),25)
cost=w**2-10*w+25

把训练数据加入程序,即告诉程序先把place给hold一下,稍后提供数值:

x = tf.placeholder(tf.float32,[3,1])

我们这里把之前函数的系数变成数据:

cost = x[0][0]*w**2 +x[1][0]*w + x[2][0]

定义一个数组存x:

coefficient = np.array([[1.],[-10.],[25.]])

提供给x:

feed_dict = {x:coefficients} 

做一个整理:

session=tf.Session():
session.run(init)
print(session.run(w))
#changed to
with tf.Session() as session: 
    session.run(init)
    print(session.run(w))

Adam优化器等也可以简单实现

你可能感兴趣的:(深度学习)