课程 3:深度神经网络
线性模型的局限性
这是一般情况,如果你有N个输入值 K个输出值,则可以使用(N+1)K个参数,但实际上你可能需要使用多得多的参数。而且该算式是线性的,这意味着你使用该模型,能够表示的算式关系是有限的。例如,如果两个输入值的算式关系是相加,则你的模型可以通过矩阵相乘来很好的表示这一关系。但是,如果两个输入值的算式关系是相乘,则无法使用线性模型有效地表示这一关系。
但是,线性运算本身还是很有用的,大的矩阵相乘正是图形处理器的设计宗旨,图形处理器相对来说成本低廉而且速度非常快。从数学角度来讲,线性运算非常稳定,我们可以通过数学公式来演示,输入值得小小变化绝对不会使输出值出现非常大的波动。
其中的导数也很理想,线性函数的导数是常量。
我们希望将参数保持在大的线性函数里面,但是又希望整个模型是非线性的。我们不能仅仅通过线性函数将输入值不断地相乘,因为这就等同于一个大的线性函数。
ReLUs 网络
修正线性单元(the rectified linear units),简称ReLU,其导数也十分简单。
逻辑分类器只需要稍加修改,就能变成非线性函数,直接在公式中间插入一个ReLU,而不是将单个矩阵因子当做分类器。两个矩阵,一个将输入值传递到ReLU中,一个将ReLU与分类器相连。通过在中间插入ReLU函数现在已经变成非线性函数,这里的H对应的是分类器中ReLU的个数,我们可以根据需要将H调的非常大,这就构建了第一个神经网络。
深度神经网络
通过增大中间隐藏层的尺寸,你可以让它变的更大,更复杂。但总体上说,仅仅增大H数,并非高效的手段。你需要让他变的非常非常大,当然这也会使它很难被训练,而这正是深度学习核心思想发挥作用的地方。
原因(1)参数的“效率”。
通过让网络变深的方式,你可以通过增加较少的参数以使模型表现大为改善。
原因(2)层次化的结构。
我们以一个图形分类器模型为例,若我们画出它每层所学到的内容,你会发现模型最底层会是一些非常简单的东西,例如线、边等。再往右看,则会有更复杂的东西出现,例如几何形状等。再往深处看,你则会看到一些更具体的内容,例如脸、物件等。该模型因此而显得十分强大,因为模型能够学习到数据中的抽象内容,而这正是你所期望的。而最终,模型也会因此而更快地完成学习过程。
防止过拟合
(1)通过过观察模型在验证集的表现,并在模型开始过拟合的时候,停止训练。这种方法叫做“早停”,并且它是防止你模型,对于训练集过度优化的最好方法。
(2)另一种方法是使用正则化。
正则化是在网络上施加额外的限制,以此来间接地减少自由变量的参数数量,但同时却不增大优化的难度。
例如,L2正则化。它的核心思想是在罚函数中加入一个额外的一项,以削减大权重的影响。它的常用做法是在罚函数中加上权重矩阵的L2范数,乘以一个小常数得到的值。不过结果就是不可避免的引入了一个超参数要去调试。L2正则化最好的地方,莫过于它非常非常的简单,因为你仅在你的罚函数上加上了一个数值,而你神经网络的架构并未因此改变,并且你能很快地徒手算出它的导数。
再如,Dropout。对于正则化而言,另一个重要的技巧叫做dropout丢弃法。dropout的机理是这样的,假设这一层与这一层升级网络相连。在训练你神经网络的过程中对每个样列,任选所有激活值中的一半,并把他们设为0。在这个完全随机的过程中,你将选取流过神经网络的一半的数据,并直接忽略它,然后对下一组数据也进行如下随机的过程。
参考文献
[1] https://classroom.udacity.com/courses/ud730
任务 2: SGD
官网示例:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/udacity/2_fullyconnected.ipynb
博客示例:http://www.hankcs.com/ml/udacity-sgd.html
按照官网,可以通过各项任务,还是比较容易的。在博客示例中,由于对方用的tensorflow不是1.0,他把官网的
tf.global_variables_initializer().run()
改成
tf.initialize_all_variables().run()
如果用tensorflow 1.0,就不用改动官网的代码。
另外,博客示例的各处
tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))
要改成
tf.nn.softmax_cross_entropy_with_logits(labels=tf_train_labels, logits=logits))
否则出现以下错误:
ValueError: Only call `softmax_cross_entropy_with_logits` with named arguments (labels=...,logits=...,...)
另外,官方代码的
save = pickle.load(f)
要改成
save = pickle.load(f,encoding='iso-8859-1')
否则出现以下类似的错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xbf in position 3: ordinal not in range(128)
这种错误在用cmd里面python启动.py会发生,但是用Anaconda启动.py时不会。
参考文献
[1] https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/udacity/2_fullyconnected.ipynb
[2] http://www.hankcs.com/ml/udacity-sgd.html
任务 3: 正则化
官网示例:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/udacity/3_regularization.ipynb
博客示例:http://www.hankcs.com/ml/task-3-regularization.html
对官网或博客的代码改动与任务2类似。
参考文献
[1] https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/udacity/3_regularization.ipynb
[2] http://www.hankcs.com/ml/task-3-regularization.html