【翻译】Sklearn 与 TensorFlow 机器学习实用指南 —— 第10章 人工神经网络介绍(下)

浏览: 1693

作者:ApacheCN【翻译】   Python机器学习爱好者

Python爱好者社区专栏作者

GitHub:https://github.com/apachecn/hands_on_Ml_with_Sklearn_and_TF



使用神经网络

现在神经网络被训练了,你可以用它进行预测。 为此,您可以重复使用相同的建模阶段,但是更改执行阶段,如下所示:

with tf.Session() as sess:
   saver.restore(sess, "./my_model_final.ckpt") # or better, use save_path
   X_new_scaled = mnist.test.images[:20]
   Z = logits.eval(feed_dict={X: X_new_scaled})
   y_pred = np.argmax(Z, axis=1)

首先,代码从磁盘加载模型参数。 然后加载一些您想要分类的新图像。 记住应用与训练数据相同的特征缩放(在这种情况下,将其从 0 缩放到 1)。 然后代码评估对数点节点。 如果您想知道所有估计的类概率,则需要将softmax()函数应用于对数,但如果您只想预测一个类,则可以简单地选择具有最高 logit 值的类(使用argmax()函数做的伎俩)。

微调神经网络超参数

神经网络的灵活性也是其主要缺点之一:有很多超参数要进行调整。 不仅可以使用任何可想象的网络拓扑(如何神经元互连),而且即使在简单的 MLP 中,您可以更改层数,每层神经元数,每层使用的激活函数类型,权重初始化逻辑等等。 你怎么知道什么组合的超参数是最适合你的任务?

当然,您可以使用具有交叉验证的网格搜索来查找正确的超参数,就像您在前几章中所做的那样,但是由于要调整许多超参数,并且由于在大型数据集上训练神经网络需要很多时间, 您只能在合理的时间内探索超参数空间的一小部分。 正如我们在第2章中讨论的那样,使用随机搜索要好得多。另一个选择是使用诸如 Oscar 之类的工具,它可以实现更复杂的算法,以帮助您快速找到一组好的超参数.

它有助于了解每个超级参数的值是合理的,因此您可以限制搜索空间。 我们从隐藏层数开始。

隐藏层数量

对于许多问题,您只需从单个隐藏层开始,您将获得合理的结果。 实际上已经表明,只有一个隐藏层的 MLP 可以建模甚至最复杂的功能,只要它具有足够的神经元。 长期以来,这些事实说服了研究人员,没有必要调查任何更深层次的神经网络。 但是他们忽略了这样一个事实:深层网络具有比浅层网络更高的参数效率:他们可以使用比浅网格更少的神经元来建模复杂的函数,使得训练更快。

要了解为什么,假设您被要求使用一些绘图软件绘制一个森林,但是您被禁止使用复制/粘贴。 你必须单独绘制每棵树,每枝分枝,每叶叶。 如果你可以画一个叶,复制/粘贴它来绘制一个分支,然后复制/粘贴该分支来创建一个树,最后复制/粘贴这个树来制作一个林,你将很快完成。 现实世界的数据通常以这样一种分层的方式进行结构化,DNN 自动利用这一事实:较低的隐藏层模拟低级结构(例如,各种形状和方向的线段),中间隐藏层将这些低级结构组合到 模型中级结构(例如,正方形,圆形)和最高隐藏层和输出层将这些中间结构组合在一起,以模拟高级结构(如面)。

这种分层架构不仅可以帮助 DNN 更快地融合到一个很好的解决方案,而且还可以提高其将其推广到新数据集的能力。 例如,如果您已经训练了模型以识别图片中的脸部,并且您现在想要训练一个新的神经网络来识别发型,那么您可以通过重新使用第一个网络的较低层次来启动训练。 而不是随机初始化新神经网络的前几层的权重和偏置,您可以将其初始化为第一个网络的较低层的权重和偏置的值。这样,网络将不必从大多数图片中低结构中从头学习;它只需要学习更高层次的结构(例如发型)。

总而言之,对于许多问题,您可以从一个或两个隐藏层开始,它可以正常工作(例如,您可以使用只有一个隐藏层和几百个神经元,在 MNIST 数据集上容易达到 97% 以上的准确度使用两个具有相同总神经元数量的隐藏层,在大致相同的训练时间量中精确度为 98%)。对于更复杂的问题,您可以逐渐增加隐藏层的数量,直到您开始覆盖训练集。非常复杂的任务,例如大型图像分类或语音识别,通常需要具有数十个层(或甚至数百个但不完全相连的网络)的网络,正如我们将在第 13 章中看到的那样),并且需要大量的训练数据。但是,您将很少从头开始训练这样的网络:重用预先训练的最先进的网络执行类似任务的部分更为常见。训练将会更快,需要更少的数据(我们将在第 11 章中进行讨论)

每层隐藏层的神经元数量

显然,输入和输出层中神经元的数量由您的任务需要的输入和输出类型决定。例如,MNIST 任务需要28×28 = 784个输入神经元和 10 个输出神经元。对于隐藏的层次来说,通常的做法是将其设置为形成一个漏斗,每个层面上的神经元越来越少,原因在于许多低级别功能可以合并成更少的高级功能。例如,MNIST 的典型神经网络可能具有两个隐藏层,第一个具有 300 个神经元,第二个具有 100 个。但是,这种做法现在并不常见,您可以为所有隐藏层使用相同的大小 - 例如,所有隐藏的层与 150 个神经元:这样只用调整一次超参数而不是每层都需要调整(因为如果每层一样,比如 150,之后调就每层都调成 160)。就像层数一样,您可以尝试逐渐增加神经元的数量,直到网络开始过度拟合。一般来说,通过增加每层的神经元数量,可以增加层数,从而获得更多的消耗。不幸的是,正如你所看到的,找到完美的神经元数量仍然是黑色的艺术.

一个更简单的方法是选择一个具有比实际需要的更多层次和神经元的模型,然后使用早期停止来防止它过度拟合(以及其他正则化技术,特别是 drop out,我们将在第 11 章中看到)。 这被称为“拉伸裤”的方法:而不是浪费时间寻找完美匹配您的大小的裤子,只需使用大型伸缩裤,缩小到合适的尺寸。

激活函数

在大多数情况下,您可以在隐藏层中使用 ReLU 激活函数(或其中一个变体,我们将在第 11 章中看到)。 与其他激活函数相比,计算速度要快一些,而梯度下降在局部最高点上并不会被卡住,因为它不会对大的输入值饱和(与逻辑函数或双曲正切函数相反, 他们容易在 1 饱和)

对于输出层,softmax 激活函数通常是分类任务的良好选择(当这些类是互斥的时)。 对于回归任务,您完全可以不使用激活函数。

这就是人造神经网络的这个介绍。 在接下来的章节中,我们将讨论训练非常深的网络的技术,并分发多个服务器和 GPU 的训练。 然后我们将探讨一些其他流行的神经网络架构:卷积神经网络,循环神经网络和自动编码器。

完整代码

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
from sklearn.metrics import accuracy_score
import numpy as np

if __name__ == '__main__':
   n_inputs = 28 * 28
   n_hidden1 = 300
   n_hidden2 = 100
   n_outputs = 10

   mnist = input_data.read_data_sets("/tmp/data/")

   X_train = mnist.train.images
   X_test = mnist.test.images
   y_train = mnist.train.labels.astype("int")
   y_test = mnist.test.labels.astype("int")

   X = tf.placeholder(tf.float32, shape= (None, n_inputs), name='X')
   y = tf.placeholder(tf.int64, shape=(None), name = 'y')

   with tf.name_scope('dnn'):
       hidden1 = tf.layers.dense(X, n_hidden1, activation=tf.nn.relu
                                 ,name= 'hidden1')

       hidden2 = tf.layers.dense(hidden1, n_hidden2, name='hidden2',
                                 activation= tf.nn.relu)

       logits = tf.layers.dense(hidden2, n_outputs, name='outputs')

   with tf.name_scope('loss'):
       xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels = y,
                                                                 logits = logits)
       loss = tf.reduce_mean(xentropy, name='loss')#所有值求平均

   learning_rate = 0.01

   with tf.name_scope('train'):
       optimizer = tf.train.GradientDescentOptimizer(learning_rate)
       training_op = optimizer.minimize(loss)

   with tf.name_scope('eval'):
       correct = tf.nn.in_top_k(logits ,y ,1)#是否与真值一致 返回布尔值
       accuracy = tf.reduce_mean(tf.cast(correct, tf.float32)) #tf.cast将数据转化为0,1序列

   init = tf.global_variables_initializer()

   n_epochs = 20
   batch_size = 50
   with tf.Session() as sess:
       init.run()
       for epoch in range(n_epochs):
           for iteration in range(mnist.train.num_examples // batch_size):
               X_batch, y_batch = mnist.train.next_batch(batch_size)
               sess.run(training_op,feed_dict={X:X_batch,
                                               y: y_batch})
           acc_train = accuracy.eval(feed_dict={X:X_batch,
                                               y: y_batch})
           acc_test = accuracy.eval(feed_dict={X: mnist.test.images,
                                               y: mnist.test.labels})
           print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test)

练习

  1. 使用原始的人工神经元(如图 10-3 中的一个)来计算神经网络,计算A ⊕ B表示 XOR 运算)。提示:A ⊕ B = (A ∧ ¬ B) ∨ (¬ A ∧ B)

  2. 为什么通常使用逻辑斯蒂回归分类器而不是经典感知器(即使用感知器训练算法训练单层的线性阈值单元)?你如何调整感知器使之等同于逻辑回归分类器?

  3. 为什么激活函数是训练第一个 MLP 的关键因素?

  4. 说出三种流行的激活函数。你能画出它们吗?

  5. 假设有一个 MLP 有一个 10 个神经元组成的输入层,接着是一个 50 个神经元的隐藏层,最后一个 3 个神经元输出层。所有人工神经元使用 Relu 激活函数。

    • 输入矩阵X的形状是什么?

    • 隐藏层的权重向量的形状以及它的偏置向量的形状如何?

    • 输出层的权重向量和它的偏置向量的形状是什么?

    • 网络的输出矩阵Y是什么形状?

    • 写出计算网络输出矩阵的方程

  6. 如果你想把电子邮件分类成垃圾邮件或正常邮件,你需要在输出层中有多少个神经元?在输出层中应该使用什么样的激活函数?如果你想解决 MNIST 问题,你需要多少神经元在输出层,使用什么激活函数?如第 2 章,一样让你的网络预测房屋价格。

  7. 什么是反向传播,它是如何工作的?反向传播与反向自动微分有什么区别?

  8. 你能列出所有可以在 MLP 中调整的超参数吗?如果 MLP 与训练数据相匹配,你如何调整这些超参数来解决这个问题?

  9. 在 MNIST 数据集上训练一个深层 MLP 并查看是否可以超过 98% 的精度。就像在第 9 章的最后一次练习中,尝试添加所有的铃声和哨子(即,保存检查点,在中断的情况下恢复最后一个检查点,添加摘要,使用 TensorBoard 绘制学习曲线,等等)。

练习的答案请参照附录 A



Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复课程即可获取

小编的Python入门免费视频课程!!!

【最新免费微课】小编的Python快速上手matplotlib可视化库!!!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告制作免费学习视频。

玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。





image.png

推荐 0
本文由 Python爱好者社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册