tensorflow 学习(一)

时间:2021-02-14 05:08:12

改系列只为记录我学习 udacity 中深度学习课程!!

1. 整个课程分为四个部分,如上图所示。

tensorflow 学习(一)

第一部分将研究逻辑分类器,随机优化以及实际数据训练。

第二部分我们将学习一个深度网络,和使用正则化技术去训练一个更大的模型

第三部分我们将深入研究图像和卷积模型

第四部分我们将学习文本和序列,我们将训练嵌入和递归模型

2. 课程将注重分类问题的研究

tensorflow 学习(一)

分类问题:典型的情况是你有很多样本,我们称为训练数据集,我们已经把他们归类了。

现在有一个全新的样本,你的目标是要指出这个样本属于哪一类?

3. 机器学习中不只是分类问题,但分类是整个机器学习的基石!

tensorflow 学习(一) tensorflow 学习(一)tensorflow 学习(一)

第二张图中,如果我们想做到行人检测,我们可以设计一个分类器将图中的小块分为行人/非行人两类,当分类器输入行人时,就要告诉我们行人的位置。

第三张图中,如果我们想做到网页搜索,我们可以使分类器接收成对的搜索请求,网页的输出则是相关/不相关两类。

4. 逻辑分类器是一种线性分类器

它接收输入X,比如图片的像素,对输入执行一个线性函数来生成预测,称为评分函数,该函数就是一个巨大的矩阵乘法。tensorflow 学习(一)

其中 W 是权重weights, b 是偏置项bias.

机器学习的目的就是为了找到一 W&b 使得我们的预测结果表现的非常好。

tensorflow 学习(一)

我们如果用上面的结果来执行分类呢?

我们将这些结果转化成概率,这将使得正确的分类概率接近于1,不正确的接近于0.

tensorflow 学习(一)

我们将结果转化为概率的方法是使用一个 Softmax 函数

我们将这些结果转化成概率,这将使得正确的分类概率接近于1,不正确的接近于0.

下面是在python中实现 softmax 函数的代码,值得注意的是当线性函数输出数量级较大时 softmax 函数 概率区别度越高,反之乐接近于平均分布。

#coding=utf-8
"""Softmax."""
# 假设线性函数输出为三个类别值,设计softmax函数给输出打分,获得分类概率
scores = [3.0, 1.0, 0.2]

import numpy as np

def softmax(x):
    """Compute softmax values for each sets of scores in x."""

    return np.exp(x) / np.sum(np.exp(x), axis=0)

print(softmax(scores))

# Plot softmax curves
import matplotlib.pyplot as plt
x = np.arange(-2.0, 6.0, 0.1)
scores = np.vstack([x, np.ones_like(x), 0.2 * np.ones_like(x)])

plt.plot(x, softmax(scores).T, linewidth=2)
plt.show()

5. One-Hot编码

tensorflow 学习(一)目的是使得正确的类别得分为1,不正确的为0

6. cross-entropy loss

tensorflow 学习(一)同时我们将使用交叉熵损失函数来量化预测得到的分类标签的得分与真实标签之间的一致性。

tensorflow 学习(一)即     tensorflow 学习(一)

tensorflow 学习(一) 我们的目的就是找到一对合适的 W 和 b 最小化损失函数。

该线性分类问题就转化成了一个数据最优化的问题,在最优化的过程中,通过更新评分函数的参数来最小化损失函数值。

最简单的方法就是梯度下降法,对损失函数的每一个变量求偏导,然后不断更新变量,直到达到局部最优。

tensorflow 学习(一)

7. 正则化输入和初始权重

输入数据过大或者过小都很严重影响我们的数值计算过程,所以我们要尽量将数据正则化为均值为0同方差的数据。

以图像为例,我们可以这么做:

tensorflow 学习(一)

这并没有改变你的图像信息,而且更利于数值优化。

在梯度下降过程众,你也会想要你的权重 W 和偏置 b 初始化在一个足够好的开始点。

比如,我们的参数可以从均值为0,标准差为sigma 的高斯分布中随机抽取。sigma的值决定了最优化过程中,在初始点你输出的数量级,通过softmax函数后,也将决定你初始化概率分布的峰值。

一个大的sigma将决定你的初始概率分布有一个较大的峰值,一个小的sigma则使得你的概率分布是不确定的。通常比较好的是开始于一个小的不确定的分布,所以选一个小的sigma。

总结来说,我们得到我们的训练数据后,先将这些数据标准化为均值为0方差一致的数据。然后我们把他乘以 权重 W 加上偏置项 b,权重初始化为随机权重。然后我们使用softmax函数得到概率,使用交叉熵损失计算整个训练数据上的平均损失。然后我们使用神奇的最优化包计算这个损失函数对权重和偏差的倒数,接着沿导数相反方向更新权重和偏差。重复这个过程,直到损失函数达到极小值(局部最优)。

8. 训练集,验证集和测试集

1. 用训练集中预测准确率来衡量分类器性能是错误的衡量方式,这是因为当你将分类器从未见过的测试集放入分类器众分类时,或许结果是不尽人意的。这是因为你的分类器已经“记住”了训练集,但它的泛化能力却可能很弱。这是个很正常的现象,我们的工作是将它泛化到新的数据上。

2. 用训练集训练分类器,然后用测试集衡量分类器性能。通过不断调整分类器模型,使得分类器在测试集上性能最优,这种方法也是错误的。在这个反复试错的过程中,其实分类器已经间接地看到了测试集了。

3. 那么我们该怎样衡量分类器的性能呢?一个简单的方法是将整个数据集分成训练集,验证集和测试集。训练集用于模型训练,验证集用来暂时衡量分类器性能,反复试错过后我们再使用测试集来最终衡量分类器性能。

4. 交叉验证方法!

9. 验证集和测试集大小

验证集过小:假设验证集只有6个,我们在调整模型过程中,验证集的准确率从66%(四个正确两个错误)提升到83%(五个正确一个错误)这显然是不可靠的。验证集越大,噪声越小,评价越可靠。

tensorflow 学习(一)假设验证集大小为3000,而我们只相信30个样本以上的改变是有效的。那么左边的提升中,只有第一种情况是可靠的提升。

10. 参数优化方法
对于一个数据集D,需要优化的目标函数是整个数据集中所有数据loss的平均值。

tensorflow 学习(一)

其中,fW(x(i))计算的是数据x(i)上的loss, 先将每个单独的样本x的loss求出来,然后求和,最后求均值。 r(W)是正则项(weight_decay),为了减弱过拟合现象。

如果采用这种Loss 函数,迭代一次需要计算整个数据集,在数据集非常大的这情况下,这种方法的效率很低,这个也是我们熟知的梯度下降采用的方法。

在实际中,通过将整个数据集分成几批(batches), 每一批就是一个mini-batch,其数量(batch_size)为N<<|D|,此时的loss 函数为:

tensorflow 学习(一)

有了loss函数后,就可以迭代的求解loss和梯度来优化这个问题。在神经网络中,用forward pass来求解loss,用backward pass来求解梯度。

SGD: 随机梯度下降(Stochastic gradient descent)是在梯度下降法(gradient descent)的基础上发展起来的,梯度下降法也叫最速下降法,具体原理在网易公开课《机器学习》中,吴恩达教授已经讲解得非常详细。SGD在通过负梯度tensorflow 学习(一)和上一次的权重更新值Vt的线性组合来更新W,迭代公式如下:

tensorflow 学习(一)
 
其中, tensorflow 学习(一) 是负梯度的学习率(base_lr),tensorflow 学习(一)是上一次梯度值的权重(momentum),用来加权之前梯度方向对现在梯度下降方向的影响。这两个参数需要通过tuning来得到最好的结果,一般是根据经验设定的。如果你不知道如何设定这些参数,可以参考相关的论文。

在深度学习中使用SGD,比较好的初始化参数的策略是把学习率设为0.01左右(base_lr: 0.01),在训练的过程中,如果loss开始出现稳定水平时,对学习率乘以一个常数因子(gamma),这样的过程重复多次。

对于momentum,一般取值在0.5--0.99之间。通常设为0.9,momentum可以让使用SGD的深度学习方法更加稳定以及快速。

关于更多的momentum,请参看Hinton的《A Practical Guide to Training Restricted Boltzmann Machines》。

它有一些 hyper-parameters

  • weight initialization
  • batch size
  • momentum
  • initial learning rate
  • learning rate decay

这里我引用caffe工具里优化实例:

type: SGD
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
lr_policy: "step"
gamma: 0.1  

weight_decay是损失函数里正则化损失项的超参数tensorflow 学习(一),目的是防止过拟合。

lr_policy设置为step,则学习率的变化规则为 base_lr * gamma ^ (floor(iter / stepsize))

即前1000次迭代,学习率为0.01; 第1001-2000次迭代,学习率为0.001; 第2001-3000次迭代,学习率为0.00001,第3001-3500次迭代,学习率为10-5

上面的设置只能作为一种指导,它们不能保证在任何情况下都能得到最佳的结果,有时候这种方法甚至不work。如果学习的时候出现diverge(比如,你一开始就发现非常大或者NaN或者inf的loss值或者输出),此时你需要降低base_lr的值(比如,0.001),然后重新训练,这样的过程重复几次直到你找到可以work的base_lr。

当我们训练出现问题时,我们首先想到的是降低学习率。

AdaGrad:自适应梯度(adaptive gradient)是基于梯度的优化方法(like SGD)

只需要两个超参数

  • initial learning rate
  • learning rate decay

具体的介绍文献:Duchi, E. Hazan, and Y. Singer. Adaptive Subgradient Methods for Online Learning and Stochastic OptimizationThe Journal of Machine Learning Research, 2011.

这种方法相比来说更稳定,但学习到的模型也一般。。。