100行Python代码理解深度学习关键概念:从头构建恶性肿瘤检测网络

摘要: 100行Python代码理解深度学习关键概念!

在构建乳腺癌预测神经网络过程当中,咱们主要分为3大部分:python

1.用Python从零开始建立一个神经网络,并使用梯度降低算法训练模型。算法

2.在该神经网络中使用威斯康星乳腺癌数据集,根据9种不一样的特征,预测肿瘤是良性仍是恶性的。编程

3.探索反向传播和梯度降低算法的工做原理。网络

在这个领域中,有不少大牛都经过视频和博文分享了本身掌握的专业知识,如fast.ai的Jeremy Howard、吴恩达、Andrej Karpathy、Yann Lecun等等。架构

他们一致认为,深度学习的关键之一就是,尽快亲自动手编写一个深度学习的模型。当前,深度学习领域中有不少强大的库可供咱们使用,如Tensorflow、 PyTorch、 Fast.ai、 Keras、 Mxnett、Nctk、DL4J 等。若是仅仅直接使用这些强大的库,咱们可能会错过不少关键的东西,所以,咱们须要进一步思考这些进程中最重要的那部分。机器学习

若是能本身亲自动手编码建立一个神经网络,咱们就不得不面对建立过程当中出现的一些问题和障碍,挖掘深度学习背后隐藏的那些使人惊叹的知识。函数

当前,深度学习领域中有各类各样的架构和开发:卷积神经网络、循环神经网络和生成对抗网络等等。在这些不一样种类的网络背后,都包含了两个相同的算法:反向传播算法和梯度降低算法。工具

探索神秘的函数

宇宙中的不少事物均可以用函数表示。本质上来讲,函数是一种数学结构,接受一个输入并产生一个输出,表示因果关系、输入输出关系。学习

当咱们审视周围的世界时,会接收到不少信息,咱们将这些信息转化为数据,就能够从这些数据中学到不少知识。在利用这些数据进行学习的时候,会有不少不一样的种类。一般来讲,深度学习中有三种最多见的类型:优化

1.监督学习:从一组有标签(已分类)的训练数据中学习函数,输入和输出是成对的数据集。

2.非监督学习:从没有任何标签或分类的数据中学习到函数。

3.强化学习:代理人会在特定环境中作出相应的动做,经过最大化代理人获得的奖励获得函数。

监督学习

本文中,咱们主要关注监督学习。如今,咱们有一个数据集,包含输入及对应的输出。下面,咱们想了解这些输入和输出是如何经过一个神秘的函数联系起来的。

当数据集达到必定的复杂度时,寻找这个函数的难度就至关大。所以,咱们就须要使用神经网络和深度学习,来探索这个神秘的函数。

本质上来讲,神经网络经过一系列的中间“权重”链接咱们的输入和指望输出数据。这些权重实际上就是一些数字。

当咱们使用正确的架构和参数,经过神经网络的结构和优化算法,咱们可将神经网络近似成一个通用函数近似器,将输入和输出数据联系起来。

建立一个神经网络

通常来讲,简单的神经网络包括两层(输入不计入层数):

1.输入:神经网络的输入包含了咱们的源数据。而且,神经元的数量与源数据的特征数量相匹配。下图中有4个输入,当咱们使用威斯康星乳腺癌数据集建立神经网络的时候,就会使用9个输入。

2.第一层:隐藏层,包含一些隐藏层神经元,这些神经元将会与周围层中的全部单元相链接。

3.第二层:有一个单元,为神经网络的输出。

在实际的神经网络构建过程当中,咱们可使用更多的层,好比10个或20个层的网络。为了简单起见,在这里,咱们使用2个层。千万不要小看这2个层,它可以实现不少功能。

神经网络如何进行学习

问题来了:在这个神经网络中,学习将在哪一个部分进行?

咱们来回顾一下,咱们在神经网络的输入层放置了一些数据,并向网络展现某个输入应该对应什么输出,也就是说,神经网络的输出(第2层)应该是什么结果。

在神经网络中,每一个神经元都有一个相关的权重以及一个误差。这些权重只是神经网络在开始学习时候初始化的一些随机数字。

神经网络根据输入数据和这些权重值进行计算,经过神经网络传播,直到输出产生最终的结果。

这些计算的结果就是一个将输入映射到输出的函数。

咱们须要的就是,这些神经网络可以计算出一个最佳权重值。由于网络经过计算,不一样的权重和不一样的层结合起来,会近似出不一样类型的函数。

如今,咱们来进一步探索正在探寻的函数。为了方便阅读,咱们须要解释下这些变量的名称:

1.X表示输入层,即提供给网络的数据集。

2.Y表示与输入x对应的目标输出,由输入通过网络进行一系列的计算获得的输出。

3.Yh(y hat)表示预测函数,即咱们像网络提供输入数据集x后,通过神经网络一系列的计算产生的输出。所以,Y是理想的输出,Yh是神经网络接收到输入数据后产生的实际输出。

4.W表示网络各层的权重。

咱们首先看第一层——隐藏层,它执行了一个运算W*X(即W和X的乘积)。

而后进行一个加权和:

1.这一层中的每一个单元都和前一层中的每一个单元相链接。

2.权重值存在于每一个链接中。

3.该层中每一个单元的值都是由前一个层中每一个单元的值*权重的总和,而该权重则是1中所获得的权重。

从某种程度上来讲,权重表示链接的强度,即:不一样层之间单元链接的强度。

如今,咱们要在这个架构中添加一个额外的量——误差:W*X+b。

这个误差可以给神经网络带来更多的灵活性,误差容许网络“移动”单位的线性计算,增强网络学习这些函数的能力。

b表明单位误差项。

咱们看到,W*X+b就是一个线性方程,经过乘积与和运算表示输入和输出的线性关系。

如今,咱们的神经网络只有2层,可是请记住,一个神经网络能够有不少层,好比20个甚至200个。所以,咱们用数字表述这些变量属于哪一层。这样一来,定义隐藏层(第1层)的线性方程则为:W1*X+b1,并为其输出命名为Z,表示某一层计算的输出。所以,咱们获得以下方程:

Z1=W1*X+b1

注意,这个计算应该针对每一个层的每一个单元进行。当咱们为神经网络编写代码的时候,咱们将使用向量化编程,也就是说,利用矩阵将某一层的全部计算放在一个单一的数学运算中。

上面所讲述的是只有一个层的神经网络。如今,咱们考虑一个有不少层的神经网络,每一个层执都执行一个相似上面的线性运算,当全部的线性运算链接在一块儿时,这个神经网络就可以计算复杂的函数了。

激活函数

然而,如今就有一个问题:线性函数——太简单了吧

这个世界是复杂的,所以,线性函数远远知足不了实际需求。通常来讲,复杂的函数每每都是非线性的。并且,若是神经网络的架构仅仅由线性函数计算,那么就很难计算非线性行为。这就是为何咱们要在神经网络的每一层末尾加上一个额外的量:激活函数。如今,咱们介绍4个最典型的例子。

为了方便咱们后续对激活函数进行深刻探索,首先须要介绍梯度这一律念。一个函数在某一点上的梯度也称为函数的导数,表示该函数在该点输出值的变化率。

咱们来思考这样一个问题:当特定输入发生变化时,函数的输出会发生怎样的变化?

当梯度(导数)很是小,即函数的输出变化很是平坦时,咱们称之为梯度消失。在后边的反向传播算法中,咱们能够经过梯度了解网络中每一个参数将会如何影响网络的输出,从而就可以决定如何调整网络的权值,也就是说了解这个参数的变化将会使网络的输出增长仍是减小?

梯度消失是咱们所面临的一个问题,由于若是某一点的梯度变化很小或趋于0,咱们就很难肯定该神经网络在该点的输出方向。

固然,咱们也会遇到相反的状况——梯度爆炸。当梯度值很是大时,神经网络可能就会变得很是不稳定。

不一样的激活函数有各自的优势,可是都会面临梯度消失和梯度爆炸这两大问题。

左上:Sigmoid激活函数;右上:Tanh激活函数;

左下:Relu激活函数;右下:Leaky Relu激活函数

(1)Sigmoid激活函数——1/(1+e-x)

1.输出范围:[0,1]。

2.非线性,输出为两个极端变量0和1。适用于二分类问题。

3.曲线变化温和,所以,梯度(导数)比较容易控制。

4.该激活函数的主要缺点为:在极端状况下,函数的输出曲线变得很是平坦,也就是说,函数的导数(变化率)将变得很是小,在这种状况下,Sigmoid激活函数的计算效率和速度将会很是低,甚至会彻底没效率。

5.当Sigmoid激活函数出如今神经网络的最后一层时,将会特别有用,由于Sigmoid激活函数有助于将输出变为0或1(即二分类问题)。若是将Sigmoid激活函数放在神经网络的其余层,就会出现梯度消失问题。

(2)Tanh激活函数——(2/(1+e-2x))-1

1.输出范围:[-1,1]。

2.曲线和Sigmoid激活函数的曲线相似,是Sigmoid激活函数曲线的缩小版。

3.Tanh激活函数曲线较为陡峭,所以,该激活函数的导数(变化率)比较大。

4.Tanh激活函数的缺点与Sigmoid激活函数相似。

(3)Relu激活函数——max (0,x)

1.若是输入大于0,那么,输出值等于输入值;不然,输出为0。

2.Relu激活函数的范围是[0,+∞),这就意味着输出多是+∞,可能会存在梯度爆炸问题。

3.优势:使神经网络轻量化,由于一些神经元可能输出为0,防止全部的神经元被同时激活。

4.Relu激活函数存在一个问题,即输入为0的时候,输出所有为0,这将会致使梯度为0,会让咱们忽视某些神经元的一些有用的计算。

5.Relu激活函数计算简单,成本低廉。

6.当前,Relu激活函数是神经网络内层最常用的激活函数。

(4)Leaky Relu激活函数——ex / Sum(ex)

1.输出范围:[0,1]

2.Leaky Relu激活函数将输入进行标准化处理为一个几率分布。

3.一般用于多分类场景中的输出层。

在这里,咱们在输出层使用Sigmoid激活函数,在隐藏层使用Relu激活函数。

好了,如今咱们已经理解了激活函数,那么,就须要对其进行命名!

A:表示激活函数的输出。

所以,在神经网络的隐藏层中,将会进行以下计算:

A1=Relu(Z1)

Z1=W1*X+b1

在第二层的输出层中,将会进行以下计算:

A2=Sigmoid(Z2)

Z2=W2*A1+b2

请注意,第二层(输出层)的输入为第一层的输出,即A1。

第二层的输出就是网络的最终输出。将上面的计算概括一下,就获得2层神经网络所执行的所有计算:

Yh = A2 = Sigmoid(W2ReLU (W1X+ b1) + b2 )

所以,本质上来讲,神经网络是一连串的函数,有些是线性函数,有些是非线性函数,它们共同组成了一个复杂的函数,将咱们的输入数据和想要的输出数据链接了起来。

如今,咱们注意到,在这个方程的全部变量中,W和b是两个未知数,这就是神经网络须要学习的地方。也就是说,神经网络必须进行不断的学习,找到W和b的正确值,才能计算出正确的函数。

所以,咱们训练神经网络的目的也变得明了了,即寻找W1,b1,W2,b2的正确值。可是,在开始训练神经网络以前,咱们必须首先对这些值进行初始化,即用随机函数对其进行初始化处理。

初始化之后,咱们就能够对神经网络进行编码,咱们使用Python构建一个类,对这些主要的参数进行初始化处理。

咱们将如何进行实战编码呢?请继续阅读咱们的第二部分:用Python构建一个神经网络

一站式开发者服务,海量学习资源0元起!

阿里热门开源项目、机器学习干货、开发者课程/工具、小微项目、移动研发等海量资源;更有开发者福利Kindle、技术图书幸运抽奖,100%中--》https://www.aliyun.com/acts/product-section-2019/developer?utm_content=g_1000047140



本文做者:【方向】

阅读原文

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索