开始学习神经网络时,我花了两周的时间进行探索,选择合适的工具,对比不同的云服务以及检索在线课程。但回想起来,我还是希望我可以从第一天就能创建神经网络,这也是这篇文章的目的。
你不需要有任何预备知识。当然如果你对Python,命令行和Jupyter notebook有基础的了解会对你有所帮助。
深度学习是机器学习的一个分支,它被证明是一种可以在原始数据(如一幅图、或者一段声音)中找到固定模型的有效方法。 如果你想对猫和狗的图像进行分类。不需要具体的编程,它首先会找到图片中的边,然后从不同的边中构建模式。接下来,它会检测到鼻子,尾巴和爪子。通过这样的方式,神经网络最终可以实现对猫和狗进行分类。
但是,结构化的数据可以使用更好的机器学习算法。举个例子,如果你的excel表中记录了有序的客户数据,你希望可以预测他们的下一张订单,那么你可以使用传统的方法,使用一个更简单的机器学习算法。
核心逻辑
想象一个安装了很多随机调整齿轮的机器。这些齿轮堆叠在很多层上,而且会相互影响。最初,这个机器无法正常工作。然后随机地调整齿轮,直到调整到可以给出正确输出。
然后一个工程师会开始检查所有的齿轮,然后标记出来哪些齿轮会造成误差。他会从最后一层的齿轮开始,因为这里是所有误差累计的结果。一旦他找到了最后一层的误差,他就会开始查看前一层。通过这种方法他可以计算出每一个齿轮对于误差的贡献值。我们把这个过程称为反向传播。
然后这个工程师开始根据之前找到的误差对每一个齿轮进行调整,然后重新运行整个机器。运行机器,计算误差,调整齿轮,不断循环这个过程直到机器给出正确输出。
预测 – 计算误差 – 调整预测值 (训练周期)
神经网络的运行方式也是如此,有输入和输出,然后通过调整齿轮来寻找输入和输出之间的关系。给定一个输入,通过调整齿轮来预测输出,然后将预测值和真实值进行对比。
神经网络通过调整齿轮来追求最小误差(预测值与实际值之间的差异),它会不断调整齿轮,直到预测值与真实值之间的差异尽可能小。
最小化误差的一个最佳方法是梯度下降,即通过误差函数、或者说成本函数来进行误差的计算。
浅层神经网络
许多人认为人工神经网络是我们大脑新皮质的数字化复制品。 这是一个错误的观念。
我们并不知道大脑如何能够做出这样的声明。这只是神经网络发明人弗兰克·罗森布拉特(Frank Rosenblatt)的一个灵感源泉。
浅层神经网络 输入-权重-加和-判断 –> (预测值-实际值)*学习率
与神经网络模拟器玩一两个小时,你就可以获得对其的直观感受。
我们将从实现一个简单的神经网络开始,以了解TFlearn中的语法。从经典的101问题开始,也就是OR运算符。虽然神经网络更适合于其他类型的数据,但这是了解其工作原理的一个很好的问题。
所有的深度学习程序都遵循同样的核心逻辑:
- 首先加载库,然后加载数据并清洗。不管是照片,音频还是知觉数据,所有的输入都会被转化为数字。这些很长的数字列表就是我们神经网络的输入。
- 现在开始设计神经网络。选择你的神经网络层的类型和数量。
- 然后它会进入学习过程。
- 神经网络知晓输入和输出,然后自行寻找二者之间的关系。
- 最后会用训练好的模型中给到你一个预测值。
下面是这个神经网络的程序:
输出:
第一行 以“#”开头的行表示备注,一般用来解释代码
第二行 加载TFlearn库 通过这个语句我们可以使用谷歌Tensorflow的深度学习函数
第五行和第六行 将上述表中的数据存储在列表中
每个数字末尾的点会将整数映射到浮点数。它存储具有十进制值的数字,使计算更加精确。
第七行 初始化神经网络,并指定输入数据的维度或者说尺寸
所有的OR运算都是在一对数据中进行的,所以维度是2.
空值是默认值,表示批量的大小
第八行 输出层
激活函数将过程中的结果映射到输出层
在这个例子中,我们使用Sigmoid函数将其映射到(0,1)区间范围内
第十一行 应用回归
使用优化器选择合适的算法来最小化成本函数
学习率决定了神经网络的调整速度,而损失变量决定了如何计算误差。
第十二行 选择使用哪个神经网络
一般情况下也可以用来指定存储训练日志的位置
第十三行 训练你的神经网络和模型
选择你的输入数据(OR)以及实际的标签(Y_truth)
Epochs决定了你的神经网络运行数据的循环次数
如果你设置 snapshot=True,那么每次循环后都会进行模型验证
第十四到十八行 使用训练好的模型进行预测
在这个例子中,返回的是结果是1/True的概率
输出层:
第一个结果表示[0.]&[0.]组合为真的可能性为4%,以此类推。“Training step”显示了你训练了多少批。
在每一批中所有数据都将训练一次,类似于Epoch。如果数据相对内存较大,你需要停止分段训练。损失函数会计算每一次迭代的错误数量。
SGD指随机梯度下降法及最小化代价函数方法。
Iter指当前数据索引以及输入项的总和。
你可以在大多数TFlearn神经网络中找到上述逻辑和语法。学习这段代码最好的方法就是修改代码并产生一些错误。
损失曲线显示了每一次训练的错误量。
你可以通过Tensorboard来可视化每一次实验,并了解每一个参数是如何影响训练的。
这里有一些你可以运行的例子的建议。我推荐你花费几小时练习这些例子,以更好地适应运行环境以及TFlearn中的参数。
实验
- 增加训练与迭代次数
- 尝试添加或改变文档中提到的每一个函数的参数
例如g = tflearn.fullyconnected(g, 1, activation=’sigmoid’)改成tflearn.fullyconnected(g, 1, activation=’sigmoid’, bias=False)在输入项增加整数
- 改变输入层的形状
- 改变输出层的激活函数
- 使用不同的梯度下降方法
- 改变神经网络计算代价的方式
- 用X和Y来替代“AND”和“NOT”逻辑运算
- 例如将最后一项Y_truth从[1.]改为[0.]。为了使其有效,你需要在网络中增加一层。
- 使其学得更快
- 想办法使得每一步学习都超过0.1秒
新手入门
结合Python来使用Tensorflow在深度学习中是最常见的手段。
TFlearn是一个运行在Tensorflow之上的高层次框架。
另一个常见的框架是Keras。这是一个更加健壮的库,但是我发现TFlearn的语法更加简洁易懂。
它们都是运行在Tensorflow之上的高层次框架。
你可以使用你的电脑CPU来运行简单的神经网络。但是大多数实验需要运行数个小时甚至几周。这也是为什么大多数人通过现代GPU云服务来进行深度学习。
最简单的GPU云服务解决方案是FloydHub(https://www.floydhub.com/)。如果你掌握了基础的命令行技能,部署FloydHub将不会超过5分钟。
使用FloyHub文档来安装floyd-cli命令行工具。FloydHub还为遇到问题的客户提供内部客服支持。
让我们在FloyHub中使用TFlearn、Jupyter Notebook以及Tensorboard来运行你的第一个神经网络吧!
安装FloydHub并登陆,下载这份指南中所需的文件。
打开终端,输入以下命令:
进入文件夹并初始化FloydHub:
FloydHub会在你的浏览器打开web面板,提示你创建一个名为101的新项目。完成后回到终端,再次输入初始化命令。
现在你可以在FloydHub上运行你的神经网络任务了。
你可以通过“floyd run”命令进行不同的设置。在我们的案例中,我们希望:
- 在FloydHub中增加一个已上传的公共数据集
- data emilwallner/datasets/cifar-10/1:data 指定数据目录。你可以在FloydHub上查看该数据集(以及许多其他公共数据集)。
- gpu 使用GPU云计算
- tensorboard 激活Tensorboard
- mode jupyter Jupyter Notebook模式下运行任务
OK,开始运行我们的任务:
在浏览器中初始化Jupyter后,点击“start-here.ipnyb”文件。
start-here.ipnyb 包含了一个简单的神经网络,可以了解TFlearn语法。它学习了“OR”逻辑,随后解释了所有组合。
点击菜单栏的“Kernel ”下的 “Restart & Run All”。如果你能看到信息,说明它工作正常,你就可以去做其他事情了。
前往你的FloydHub项目,找到Tensorboard链接。
深度神经网络
深度神经网络指的是包含一层以上隐藏层的神经网络。目前有非常多的关于CNN(卷积神经网络)工作原理的详细教程。
因此,我们将关注适用于更多神经网络的高层次概念。
注:该图不是一个深度神经网络。它需要一层以上隐藏层。
你想训练神经网络来预测未经训练的数据。它需要能泛化的能力。这是一种介于学习与遗忘之间的平衡。
你想它能学习如何将信号从噪声中分离,但是同时遗忘只在训练数据中出现的信号。
如果神经网络未经充分学习,它会出现欠拟合现象。与之相反是过拟合现象。它指的是从训练数据学习过多。
Regularization (正则化)是一种通过遗忘训练中的特定信号来减少过拟合的方法。
为了进一步理解这些概念,我们在CIFAR-10数据集上开展实验。该数据集包含了10种类别6万张的图片,例如汽车、卡车和鸟。目标是预测一张新的图片属于哪种类别。
CIFAR中的示例图片
通常我们需要挖掘数据、清理数据以及过滤图片。但是为了简化过程,我们只关注神经网络。你可以在Jupyter notebook中运行安装的所有例子(https://github.com/emilwallner/Deep-Learning-101)。
输入层输出层将图片分为10类。隐藏层混合了卷积层、 pooling以及连接层。
选择层数
让我们来对比下只有一层的神经网络和有三层之间的区别。每一层包含卷积层,池层,和关联层。
你可以通过点击在菜单栏中的Kernel > Restart & Run All 来运行这些脚本。接着再瞥一眼Tensorboard中的训练记录。你会发现有很多层的多准确了15%。较少层的拟合度低 — 证明它学的还不够。
你可以运行你先前下载的文件夹中相同例子,同样包括接下来的试验。
让我们看一眼准确度和验证集的准确度。深度学习中最好的实践是将数据集一分为二,一部分用作训练这个神经网络,剩下的则用作验证它。通过这种方法可以告诉我们神经网络在预测新数据中表现如何,或是类推的能力。
就如你所见,训练数据的准确度高于验证数据集。这个神经网络包含了背景噪声和其他阻碍预测新图像的细节。
为解决过拟合问题,你可以惩罚复杂方程并在神经网络中增加噪声。普遍解决这个的正则化技术有丢弃层和惩戒复杂方程。
丢弃层
我们可以这样理解丢弃层:一些强大的神经元并不决定最终结果,而是由他们分配权力。
神经网络被迫使去学习一些独立的表现。当做最终的预测时,它则有一些不同的模型去学习。
下面是一个有丢弃层的神经网络的例子。
在这项对比中,两个神经网络是一样的除了其中一个有丢弃层,另一个没有。
在神经网络中的每一层中,神经元变得更依赖于彼此。某些神经元比其他的更有影响力。丢弃层随机的丢弃部分神经元。这样,每一个神经元需要为最终输出提供不同的贡献。
另一个流行的预防过拟合的方式是在每一层中运用L1 或L2 正则方程。
L1 & L2 正则方程
比方你想描述一匹马,如果这个描述太仔细,你则会排除掉太多不同形态的马。但是如果太笼统则可能包括进来很多别的动物。L1 和L2 正则化帮助我们的网络去做这种区分。
如果我们与之前试验类似的对比,我们会得到相似的结果。
有正则化方程的神经网络表现的比没有的要好。
正则化方程L2 惩戒方程太过复杂。它测量每一个方程对于最终输出的贡献量,接着惩罚系数大的方程。
批量大小
另一个重要参数是批量大小,在每一步训练中的数据量。下面是一组大批量数据与小批量数据的对比。
就如你所见,大批量所需的周期更少但在训练中更精确。对比之下,小批量更随机但需要消耗更多步来补偿。
大批量不需要很多学习步骤。但是,你需要更多存储空间和时间去计算每一步。
学习率
最后一个试验是对比大,中,小不同学习率的网络。
学习率因其影响力被视为最重要的一个参数。它规范了如何在每一步学习过程中调节预测中的变化。如果这个学习率太高或者太低都无法收敛,就如上图的大学习率一般。
设计神经网络没有特定的方式。很多是要通过试验来决定。看看别人如何增加层数和如何调节高阶参数的。
如果你有强大的计算能力,你可以设计一个程序和调节高阶参数。
当你完成了运行工作,你应当为你的GPU云降低运转速度比如通过取消FloydHub网页仪表盘来结束工作。
后续
在TFlearn的官方示例中(https://github.com/tflearn/tflearn/tree/master/examples/images),你能感受到一些表现优异的卷积神经网络。试着运用其中一些方式去提高CIFAR-10数据库的验证集准确率。目前最优的结果是96.53%(Graham,2014)。
学习Python的语法和熟悉它的命令语句是非常值得的一件事。这可以有效减少不必要的认知负荷从而全神贯注于深度学习概念上。从Codecademy的Python课开始,接着做一些命令语句练习。如果只做这一件事,你花不到三天就能掌握。
原文发布时间为:2017-11-8
本文作者:Emil Wallnér