疫情当前,国难当头,当灾难来临的时候才深刻的感觉到了自己的弱小,对国家,对亲人,是这么的无能为力,希望做点什么,可是却什么也做不了。不过庆幸的是我们还年轻,现在也不是自怜自哀的时候,作为一名学生现在可以做的就是尽快的成长起来,强大自己。在国家、亲人需要的时候说一声我可以做点什么。
知识的本身在于分享,分享的过程也是自己理解的一个加深。希望和大家一起学习,一起进步。本部分内容是一个系统内容,分为了三个章节:(这篇为第一章第一节)
基本上是遵循了从原理到实现再到应用的一个过程,第一章是从logistic入手介绍神经网络的基础知识,到卷积神经网络,再到循环神经网络。第二章为tensorflow的介绍,其实在第一章的部分会涉及一些,但是更多在第二章中,主要从tensorflow的计算模式,储存模式,到实现CNN、RNN然后再到自己搭建。第三章主要为应用,会用具体的实例来观察深度学习在金融领域的表现。这是目前的一个基本框架,如果有变动会在之后的文章中体现。
第一章神经网络基础知识,本章一共分为了5个节,从神经网络的介绍到序列模型,在原理部分只需要一点点简单的线性代数和高数的知识。所以Don‘t worry
本篇文章是第一章第一节,主要是通过logistics回归模型引入神经网络的基本概念,介绍了梯度下降,前向传播,反向传播等在之后的部分会经常用到的基础知识。
假设我们想要构建一个模型来表示房价和房子大小的关系,图中红色的点为实际的数据的数据点。现在构建一个回归模型来预测房子的价格,可以得到图中的蓝线。但是房价并不可能是负的,所以在接近x轴时出现拐点。房子的大小既是一个输入,价格为输出。
现在假设房子的价格不仅由房子的大小决定,而是由卧室的数量,邮政编码,周边的富裕的程度相关。我们可以画出如下的模型图,该图称为神经网络中的计算图,以后的模型基本都通过计算图表示,这个模型就可以简单的称一个神经网络,其中x为输入层,y为输出层,中间的部分为隐藏层。神经网络的工作既是学习中间的隐藏部分。
监督学习既是通过输入特征x来进行模型的学习即为监督学习,即有特征的学习,常见的监督学习有图像识别、语音识别、机器翻译、自动驾驶、时间序列等。无监督学习即不需要(x,y)这样的数据集,通常的应用有聚类、降维等。神经网络为一种监督学习,常见的应用如下:
Input(x) | Output(y) | Application | NN |
---|---|---|---|
Home features | Price | Real Estate | std NN |
Ad,user info | Click on ad?(0/1) | Online Advertising | std NN |
image | Object(1,……,1000) | Photo tagging | CNN |
Audio | Text transcript | Speech regognition | RNN |
Englist | Chinese | Maching translation | RNN |
Image,Reader info | Position of other cars | Autonomous driving | hybrid NN |
现在我们知道了神经网络是一种监督学习,是一个通过学习隐藏层从而输入数据就可以得到输出的模型,下面我们通过一个二分类问题来了解神经网络组成部分和它是怎么进行“学习”的。
二分类问题,顾名思义它的输出只有两个即0和1。我们的目的是输入一张图片,去判断这个图片中是否有猫(0没有,1有)。
首先来了解一下一个图片在计算机中是如何表示的,如果一张图片是64x64像素,则会有3个64x64的矩阵(红、绿、蓝),矩阵中的每一个元素为该颜色的强度。然后把每个矩阵中的元素都“拉平”、依次排开,则三个矩阵就转化为了一个12288(64x64x3)x1的特征向量X,X即为该图片的特征输入。
现在为了之后表述,做一个记号的规定
现在我们要得到就是有一个输入,可以得到输出。但是我们怎么知道输出是正确的?所以,需要通过训练集,把已知输出(肯定有猫)的数据进行输入,用预测值(有猫,或者是没猫)和真实值(有猫)进行比较,如果不一致则进行参数调整。如果一致则什么都不做。数据是多维的,这样的比较我们会进行很多次直到出错的概率非常小,代价函数既是预测准确度的一个体现。
l o g i s t i c m o d e l : y ^ = σ ( w T x + b ) w h e r e σ ( z ) = 1 1 + e − z g i v e n S e t : { ( x ( 1 ) , y ( 1 ) ) ( x ( 2 ) , y ( 2 ) ) . . . ( x ( m ) , y ( m ) ) } w a n t y ^ ( i ) ≈ y i 进 行 预 测 值 和 正 式 值 的 比 较 , 则 自 然 想 到 损 失 函 数 ( l o s s f u n c t i o n ) : L ( y ^ , y ) = 1 2 ( y ^ − y ) 2 但 是 该 损 失 函 数 是 非 凸 ( 找 不 到 最 好 的 点 ) 的 , 所 以 我 们 构 建 如 下 损 失 函 数 。 L ( y ^ , y ) = − ( y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ) 上 面 的 损 失 函 数 表 示 是 单 个 数 据 的 损 失 。 现 在 我 们 来 使 用 代 价 函 数 ( c o s t f u n c t i o n ) 表 示 总 训 练 集 的 误 差 : J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) = − 1 m ∑ i = 1 m [ ( y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ) ] logistic \,\, model: \\ {}\\ \hat{y} =\sigma(w^Tx + b) \\ {}\\ where \quad \sigma(z)=\frac{1}{1+e^{-z}} \\ {}\\ given \quad Set: \{(x^{(1)},y^{(1)})\, (x^{(2)},y^{(2)})\ ... (x^{(m)},y^{(m)})\} \\ {}\\ want \quad \hat{y}^{(i)} \approx y^{i} \\ {}\\ 进行预测值和正式值的比较,则自然想到损失函数(loss function): \\ {} \\ L(\hat{y},y)=\frac{1}{2}(\hat{y}-y)^2 \\ {} \\ 但是该损失函数是非凸(找不到最好的点)的,所以我们构建如下损失函数。\\ {}\\ L(\hat{y},y)=-(ylog\hat{y}+(1-y)log(1-\hat{y})) \\ {}\\ 上面的损失函数表示是单个数据的损失。\\ {} \\ 现在我们来使用代价函数(cost function)表示总训练集的误差:\\ {} \\ J(w,b) =\frac{1}{m}\sum_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)})=-\frac{1}{m}\sum_{i=1}^{m}[(ylog\hat{y}+(1-y)log(1-\hat{y}))] logisticmodel:y^=σ(wTx+b)whereσ(z)=1+e−z1givenSet:{(x(1),y(1))(x(2),y(2)) ...(x(m),y(m))}wanty^(i)≈yi进行预测值和正式值的比较,则自然想到损失函数(lossfunction):L(y^,y)=21(y^−y)2但是该损失函数是非凸(找不到最好的点)的,所以我们构建如下损失函数。L(y^,y)=−(ylogy^+(1−y)log(1−y^))上面的损失函数表示是单个数据的损失。现在我们来使用代价函数(costfunction)表示总训练集的误差:J(w,b)=m1i=1∑mL(y^(i),y(i))=−m1i=1∑m[(ylogy^+(1−y)log(1−y^))]
代价函数我们已经了解了,接下来我们需要去找代价函数最小的点,从而得到对应参数w,b,梯度下降法既是一种寻找最优点的方法。在凸问题当中由导数的定义可知,w和b的梯度的方向是最快达到最优点的方向。所以我们沿着梯度的方向进行迭代。由下图可知,图中的任意一点到最小点的最快的方向既是导数的方向。多维向量的导数既是梯度。
y ^ = σ ( w T x + b ) σ ( z ) = 1 1 + e − z J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) = − 1 m ∑ i = 1 m [ ( y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ) ] \hat{y} =\sigma(w^Tx + b) \quad \sigma(z)=\frac{1}{1+e^{-z}} \\ {}\\ J(w,b) =\frac{1}{m}\sum_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)}) =-\frac{1}{m}\sum_{i=1}^{m}[(ylog\hat{y}+(1-y)log(1-\hat{y}))] \\ {} \\ y^=σ(wTx+b)σ(z)=1+e−z1J(w,b)=m1i=1∑mL(y^(i),y(i))=−m1i=1∑m[(ylogy^+(1−y)log(1−y^))]
所以w和b的更新方程为:
w : = w − α d J ( w , b ) d w b : = b − α d J ( w , b ) d b α 称 为 学 习 率 w:=w-\alpha \frac{dJ(w,b)}{dw} \\ {} \\ b:=b-\alpha \frac{dJ(w,b)}{db} \\ {}\\ \alpha 称为学习率 w:=w−αdwdJ(w,b)b:=b−αdbdJ(w,b)α称为学习率
接下来我们来看怎么在模型中有步骤的完成上述过程。
计算图为神经网络的计算模型,计算图可以很好的表示神经网络模型,在神经网络中必不可少,在接下的计算过程中,我们会一直用到计算图。神经网络的计算过程主要分为前向传播和反向传播。
按 照 上 面 的 模 型 : α J α V = 3 α J α a = α J α V α V α a 因 为 我 们 一 直 都 是 J 对 其 他 参 数 进 行 求 导 。 所 以 我 们 可 以 把 α J α a 记 作 α a 或 者 d a , 区 别 在 于 a 是 否 是 一 维 的 。 一 维 用 d 表 示 , 多 维 用 α 表 示 。 按照上面的模型:\\ {}\\ \frac{\alpha J}{\alpha V}=3 \\ {} \\ \frac{\alpha J}{\alpha a}=\frac{\alpha J}{\alpha V}\frac{\alpha V}{\alpha a} \\ {} \\ 因为我们一直都是J对其他参数进行求导。\\ 所以我们可以把\frac{\alpha J}{\alpha a}记作\alpha a或者da,区别在于a是否是一维的。一维用d表示,多维用\alpha 表示。 按照上面的模型:αVαJ=3αaαJ=αVαJαaαV因为我们一直都是J对其他参数进行求导。所以我们可以把αaαJ记作αa或者da,区别在于a是否是一维的。一维用d表示,多维用α表示。
现在把通过logistics回归模型,进一步理解梯度下降法。
通 过 2.2.1 中 的 模 型 可 知 : z = w T x + b y ^ = a = σ ( z ) L ( a , y ) = − ( y l o g ( a ) + ( 1 − y ) l o g ( 1 − a ) ) 通过2.2.1中的模型可知:\\ {} \\ z = w^Tx +b\\ {}\\ \hat{y} = a =\sigma(z) \\ {} \\ L(a,y)=-(ylog(a)+(1-y)log(1-a)) \\ {} \\ 通过2.2.1中的模型可知:z=wTx+by^=a=σ(z)L(a,y)=−(ylog(a)+(1−y)log(1−a))
logistics模型的计算图可以表示为:
其中反向传播过程为:
d a = d L ( a , y ) d a = − y a + 1 − y 1 − a d z = d L ( a , y ) d z = d L d a d a d z = ( y a + 1 − y 1 − a ) × a ( 1 − a ) = a − y 所 以 相 同 的 原 理 α L α w 1 = d w 1 = x 1 d z d w 2 = x 2 d z d b = d z da = \frac{dL(a,y)}{da}=-\frac{y}{a}+\frac{1-y}{1-a} \\ {}\\ dz = \frac{dL(a,y)}{dz} = \frac{dL}{da}\frac{da}{dz}=(\frac{y}{a}+\frac{1-y}{1-a}) \times a(1-a) = a-y\\ {}\\ 所以相同的原理 \\ {}\\ \frac{\alpha L}{\alpha w_1}=dw_1=x_1dz \\ {}\\ dw_2 = x_2dz \\ {}\\ db = dz \\ da=dadL(a,y)=−ay+1−a1−ydz=dzdL(a,y)=dadLdzda=(ay+1−a1−y)×a(1−a)=a−y所以相同的原理αw1αL=dw1=x1dzdw2=x2dzdb=dz
所以根据梯度下降法:参数的更新方程为:
w 1 : = w 1 − α d w 1 w 2 : = w 2 − α d w 2 b : = b − α d b w_1:=w_1 - \alpha dw_1 \\ {}\\ w_2:=w_2 - \alpha dw_2 \\ {}\\ b:=b-\alpha db \\ w1:=w1−αdw1w2:=w2−αdw2b:=b−αdb
上述描述为单一训练数据,现在我们讨论在对其m个数据的代价函数(cost function)
为 了 表 示 方 便 我 们 以 后 用 a 表 示 y ^ 和 每 一 神 经 网 络 层 的 输 出 ; 则 代 价 函 数 为 : J ( w , b ) = 1 m ∑ i = 1 m L ( a , y ( i ) ) a ( i ) = y ^ ( i ) = σ ( z ( i ) ) = σ ( w T x ( i ) + b ) α α w 1 J ( w , b ) = 1 m ∑ i = 1 m α α w 1 L ( a ( i ) , y ( i ) ) 为了表示方便我们以后用 a 表示\hat{y} 和每一神经网络层的输出;则代价函数为:\\ {} \\ J(w,b) =\frac{1}{m}\sum_{i=1}^{m}L(a,y^{(i)}) \\ {}\\ a^{(i)} = \hat{y}^{(i)} = \sigma(z^{(i)})=\sigma(w^Tx^{(i)}+b) \\ {}\\ \frac{\alpha}{\alpha w_1}J(w,b) = \frac{1}{m} \sum_{i=1}^{m} \frac{\alpha}{\alpha w_1} L(a^{(i)},y^{(i)}) 为了表示方便我们以后用a表示y^和每一神经网络层的输出;则代价函数为:J(w,b)=m1i=1∑mL(a,y(i))a(i)=y^(i)=σ(z(i))=σ(wTx(i)+b)αw1αJ(w,b)=m1i=1∑mαw1αL(a(i),y(i))
现在我们通过算法实现上述过程:
初 始 化 参 数 : J = 0 ; d w 1 = 0 ; d w 2 = 0 ; d b = 0 m 为 训 练 数 据 集 的 维 度 : f o r i = 1 t o m : z i = w T x ( i ) + b a ( i ) = σ ( z ( i ) ) J + = − [ y ( i ) l o g a ( i ) + ( 1 − y ( i ) ) l o g ( 1 − a ( i ) ) ] d w 1 + = x 1 ( i ) d z ( i ) d w 2 + = x 2 ( i ) d z ( i ) d b + = d z ( i ) J / = m d w 2 / = m d b / = m w 1 : = w 1 − α d w 1 w 2 : = w 2 − α d w 2 b : = b − α d b 初始化参数:J = 0;dw_1 = 0;dw_2=0;db=0 \\ {}\\ m为训练数据集的维度:\\ {}\\ \begin{aligned} for\quad & i =1\quad to\quad m:\\ & z^{{i}} = w^Tx^{(i)}+b \\ & a^{(i)} = \sigma (z^{(i)}) \\ & J+= -[y^{(i)}loga^{(i)}+(1-y^{(i)})log(1-a^{(i)})] \\ & dw_1 += x_1^{(i)}dz^{(i)} \\ & dw_2 += x_2^{(i)}dz^{(i)} \\ & db += dz^{(i)} \\ J /= m\\ dw_2 /=m\\ db /= m \\ \end{aligned} \\ w_1:=w_1 - \alpha dw_1 \\ {}\\ w_2:=w_2 - \alpha dw_2 \\ {}\\ b:=b-\alpha db \\ 初始化参数:J=0;dw1=0;dw2=0;db=0m为训练数据集的维度:forJ/=mdw2/=mdb/=mi=1tom:zi=wTx(i)+ba(i)=σ(z(i))J+=−[y(i)loga(i)+(1−y(i))log(1−a(i))]dw1+=x1(i)dz(i)dw2+=x2(i)dz(i)db+=dz(i)w1:=w1−αdw1w2:=w2−αdw2b:=b−αdb
虽然上述方法看似非常理所应当,但是在上述算法中存在着两个循环一个是,循环m为变量,另一个循环是循环更新参数。在python中循环是最低效的计算方法,所以现在我们尽量少用循环来完成。即向量化
在python当中应该本着原则:能少用就少用for循环。for循环为效率非常低的运行方法。
现在我们通过对算法的向量化尽少的使用for循环。
import numpy as np
u = np.exp(v)
u = np.log(v)
u = np.obs(v)
u = np.maxmun(v,0)
v**2
1/v
所以上述的logis回归梯度下降法可以进行改写,即不使用一个显性的循环。
z ( 1 ) = w T x ( 1 ) + b a ( 1 ) = σ ( z ( 1 ) ) z^{(1)}=w^Tx{(1)}+b \\ {}\\ a^{(1)}=\sigma(z^{(1)})\\ {}\\ z(1)=wTx(1)+ba(1)=σ(z(1))
如果由m为训练集,在之前logist回归中上述的计算过程我们会计算m次。
现在我们定义:
X = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ x ( 1 ) x ( 2 ) . . . x ( m − 1 ) x ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } Z = [ z ( 1 ) , z ( 2 ) . . . z ( m ) ] A = [ a ( 1 ) , a ( 2 ) . . . a ( m ) ] X= \left\{ \begin{matrix} | & | & | & | & | \\ | & | & | & | & | \\ x^{(1)} & x^{(2)} & ... & x^{(m-1)} & x^{(m)} \\ | & | & | & | & | \\ | & | & | & | & | \\ \end{matrix}\right\} \\ {}\\ Z = [z^{(1)},z^{(2)}...z^{(m)}] \\ {}\\ A = [a^{(1)},a^{(2)}...a^{(m)}] \\ {}\\ X=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣x(1)∣∣∣∣x(2)∣∣∣∣...∣∣∣∣x(m−1)∣∣∣∣x(m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫Z=[z(1),z(2)...z(m)]A=[a(1),a(2)...a(m)]
所以logistic回归中的计算过程,在python中只需要两行:
Z = n p . d o t ( W T , X ) + b A = σ ( Z ) Z= np.dot(W^T,X)+b \\ {}\\ A = \sigma(Z) Z=np.dot(WT,X)+bA=σ(Z)
在上述过程可以看出b是一个实数,但是WT,X都是矩阵,但是依然可以进行计算。在python
中有一个神奇的地方就是python会自动把b看作是一个1xm维的向量,这种计算过程我们称之为python的广播。
类似上述过程接下来进行logistic回归的反向传播过程的向量化。
d Z = [ d z ( 1 ) , d z ( 2 ) . . . d z ( m ) ] A = [ a ( 1 ) . . . a ( m ) ] Y = [ y ( 1 ) . . . y ( m ) ] d b = 1 m ∑ i = 1 m d z ( i ) = 1 m n p . s u m ( d Z ) d w = 1 m X d Z dZ=[dz^{(1)},dz^{(2)}...dz^{(m)}] \\ {} \\ A = [a^{(1)}...a^{(m)}] \\ {}\\ Y = [y^{(1)}...y^{(m)}] \\ {} \\ db=\frac{1}{m}\sum_{i=1}^{m}dz^{(i)} =\frac{1}{m}np.sum(dZ) \\ {}\\ dw = \frac{1}{m} X dZ \\ dZ=[dz(1),dz(2)...dz(m)]A=[a(1)...a(m)]Y=[y(1)...y(m)]db=m1i=1∑mdz(i)=m1np.sum(dZ)dw=m1XdZ
所以综上,logistic回归中的学习过程可以更改为:
Z = W T X + b = n p . d o t ( w . T , X ) A = σ ( Z ) d Z = A − Y d W = 1 m X d Z T d b = 1 m n p . s u m ( d Z ) W : = W − α d W b : = b − α d b Z = W^TX+b=np.dot(w.T,X) \\ {} \\ A = \sigma(Z) \\ {} \\ dZ = A-Y \\ {} \\ dW = \frac{1}{m}XdZ^T \\ {}\\ db = \frac{1}{m}np.sum(dZ) \\ {} \\ W:=W-\alpha dW \\ {}\\ b:=b- \alpha db Z=WTX+b=np.dot(w.T,X)A=σ(Z)dZ=A−YdW=m1XdZTdb=m1np.sum(dZ)W:=W−αdWb:=b−αdb
通过例子1我们来具体体会一下python的广播。
eg.1 现在想计算每种食物的碳水化合物(Carb)占每种食物中所有热量的比值。
Apples | Beef | Eggs | Potatoes | |
---|---|---|---|---|
Carb | 56.0 | 0.0 | 4.4 | 68.0 |
Protein | 1.2 | 104.0 | 52.0 | 8.0 |
Fat | 1.8 | 135.0 | 99.0 | 0.9 |
import numpy as np
A = np.array([56.0, 0.0 ,4.4,68.0],
[1.2, 104.0, 52.0, 68.0],
[1.6, 135.0, 99.0, 0.9])
cal = A.sum(axis = 0)
percentage = 100 * A/cal.reshape(1,4)
在python中,一个mxn的矩阵A乘以B,如果B是1xm的,则B会复制n次;如果B是nx1的那么B会复制m次。更多的用法参见python中的numpy文档。
2.7.1 番外篇(numpy)
numpy 中常见的bug,如果一个矩阵定义为(5,)这样的形式,通常会由一些稀奇古怪的bug,所以再定义矩阵的时候我们应该定义为(5,1)而不是(5,)
a = np.random.randn(5) # don't use this
a = np.random.randn(5,1) # this is beter
a = np.random.randn(1,5)
assert(a.shape == (5,1)) # sure your victer are the dimension that you need it to be
人工神经网络一般通过计算图来进行结构的表示,分为输入层,隐藏层和输出层,我们把只有一个隐藏层的神经网络称为双层神经网络,一个隐藏层,一个输出层。一般情况下我们把输入层记为第0层,不计入总层数。每一层中由神经元(节点)构成,每个节点中通过激活函数来控制
在本神经网络中,我们依然采用logistic回归的例子,在一个两层神经网络中每一个节点共经过了两次计算,第一次为线性计算,第二次为sigma函数变换。
在上述双层神经网络中每一个节点的内容如上,那么我们整个神经网络可以表示为:
则具体的公式如下:
z 1 [ 1 ] = w 1 [ 1 ] T + b 1 [ 1 ] , a 1 [ 1 ] = σ ( z 1 [ 1 ] ) z 2 [ 1 ] = w 2 [ 1 ] T + b 2 [ 1 ] , a 2 [ 1 ] = σ ( z 2 [ 1 ] ) z 3 [ 1 ] = w 3 [ 1 ] T + b 3 [ 1 ] , a 3 [ 1 ] = σ ( z 3 [ 1 ] ) z 4 [ 1 ] = w 4 [ 1 ] T + b 4 [ 1 ] , a 4 [ 1 ] = σ ( z 4 [ 1 ] ) 令 z [ 1 ] = { z 1 [ 1 ] z 2 [ 1 ] z 3 [ 1 ] z 4 [ 1 ] } , w [ 1 ] = { w 1 [ 1 ] T w 2 [ 1 ] T w 3 [ 1 ] T w 4 [ 1 ] T } , x = { x 1 x 2 x 3 } , b [ 1 ] = { b 1 [ 1 ] b 2 [ 1 ] b 3 [ 1 ] b 4 [ 1 ] } z_1^{[1]}=w_1^{[1]T}+b_1^{[1]},a_1^{[1]}=\sigma(z_1^{[1]}) \\ {}\\ z_2^{[1]}=w_2^{[1]T}+b_2^{[1]},a_2^{[1]}=\sigma(z_2^{[1]}) \\ {} \\ z_3^{[1]}=w_3^{[1]T}+b_3^{[1]},a_3^{[1]}=\sigma(z_3^{[1]}) \\ {} \\ z_4^{[1]}=w_4^{[1]T}+b_4^{[1]},a_4^{[1]}=\sigma(z_4^{[1]}) \\ {} \\ 令 z^{[1]}= \left\{ \begin{matrix} z_1^{[1]} \\ z_2^{[1]} \\ z_3^{[1]} \\ z_4^{[1]} \\ \end{matrix}\right\} ,w^{[1]}=\left\{ \begin{matrix} w_1^{[1]T} \\ w_2^{[1]T} \\ w_3^{[1]T} \\ w_4^{[1]T} \\ \end{matrix}\right\} ,x=\left\{ \begin{matrix} x_1 \\ x_2 \\ x_3 \\ \end{matrix}\right\} ,b^{[1]}= \left\{ \begin{matrix} b_1^{[1]} \\ b_2^{[1]} \\ b_3^{[1]} \\ b_4^{[1]} \\ \end{matrix}\right\} z1[1]=w1[1]T+b1[1],a1[1]=σ(z1[1])z2[1]=w2[1]T+b2[1],a2[1]=σ(z2[1])z3[1]=w3[1]T+b3[1],a3[1]=σ(z3[1])z4[1]=w4[1]T+b4[1],a4[1]=σ(z4[1])令z[1]=⎩⎪⎪⎪⎨⎪⎪⎪⎧z1[1]z2[1]z3[1]z4[1]⎭⎪⎪⎪⎬⎪⎪⎪⎫,w[1]=⎩⎪⎪⎪⎨⎪⎪⎪⎧w1[1]Tw2[1]Tw3[1]Tw4[1]T⎭⎪⎪⎪⎬⎪⎪⎪⎫,x=⎩⎨⎧x1x2x3⎭⎬⎫,b[1]=⎩⎪⎪⎪⎨⎪⎪⎪⎧b1[1]b2[1]b3[1]b4[1]⎭⎪⎪⎪⎬⎪⎪⎪⎫
所以上述过程可以改写为,两层神经网络可以表示为:
z [ 1 ] = z [ 1 ] x + b [ 1 ] a [ 1 ] = σ ( z [ 1 ] ) z [ 2 ] = w [ 2 ] a [ 1 ] + b [ 2 ] a [ 2 ] = σ ( z [ 2 ] ) z^{[1]} = z^{[1]}x + b^{[1]} \\ {}\\ a^{[1]} = \sigma(z^{[1]}) \\ {} \\ z^{[2]} = w^{[2]}a^{[1]} + b^{[2]} \\ {} \\ a^{[2]} = \sigma(z^{[2]}) \\ {} \\ z[1]=z[1]x+b[1]a[1]=σ(z[1])z[2]=w[2]a[1]+b[2]a[2]=σ(z[2])
令 X = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ x ( 1 ) x ( 2 ) . . . x ( m − 1 ) x ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } Z [ 1 ] = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ z [ 1 ] ( 1 ) z [ 1 ] ( 2 ) . . . z [ 1 ] ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } A [ 1 ] = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ a [ 1 ] ( 1 ) a [ 1 ] ( 2 ) . . . a [ 1 ] ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } Z [ 2 ] = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ z [ 2 ] ( 1 ) z [ 2 ] ( 2 ) . . . z [ 2 ] ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } A [ 2 ] = { ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ a [ 2 ] ( 1 ) a [ 2 ] ( 2 ) . . . a [ 2 ] ( m ) ∣ ∣ ∣ ∣ ∣ ∣ ∣ ∣ } 所 以 m 维 训 练 集 神 经 网 咯 的 计 算 过 程 可 以 表 示 为 : Z [ 1 ] = W [ 1 ] X + b [ 1 ] A [ 1 ] = σ ( Z [ 1 ] ) Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] A [ 2 ] = σ ( z [ 2 ] ) 令 X= \left\{ \begin{matrix} | & | & | & | & | \\ | & | & | & | & | \\ x^{(1)} & x^{(2)} & ... & x^{(m-1)} & x^{(m)} \\ | & | & | & | & | \\ | & | & | & | & | \\ \end{matrix}\right\}\\ {}\\ Z^{[1]}= \left\{ \begin{matrix} | & | & | & | \\ | & | & | & | \\ z^{[1](1)} & z^{[1](2)} & ... & z^{[1](m)} \\ | & | & | & | \\ | & | & | & | \\ \end{matrix}\right\} \\ {}\\ A^{[1]}= \left\{ \begin{matrix} | & | & | & | \\ | & | & | & | \\ a^{[1](1)} & a^{[1](2)} & ... & a^{[1](m)} \\ | & | & | & | \\ | & | & | & | \\ \end{matrix}\right\} \\ {} \\ Z^{[2]}= \left\{ \begin{matrix} | & | & | & | \\ | & | & | & | \\ z^{[2](1)} & z^{[2](2)} & ... & z^{[2](m)} \\ | & | & | & | \\ | & | & | & | \\ \end{matrix}\right\} \\ {}\\ A^{[2]}= \left\{ \begin{matrix} | & | & | & | \\ | & | & | & | \\ a^{[2](1)} & a^{[2](2)} & ... & a^{[2](m)} \\ | & | & | & | \\ | & | & | & | \\ \end{matrix}\right\} \\ {} \\ 所以m维训练集神经网咯的计算过程可以表示为: \\ {} \\ Z^{[1]} = W^{[1]}X + b^{[1]} \\ {} \\ A^{[1]} = \sigma(Z^{[1]})\\ {} \\ Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]}\\ {}\\ A^{[2]} = \sigma(z^{[2]}) {}\\ 令X=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣x(1)∣∣∣∣x(2)∣∣∣∣...∣∣∣∣x(m−1)∣∣∣∣x(m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫Z[1]=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣z[1](1)∣∣∣∣z[1](2)∣∣∣∣...∣∣∣∣z[1](m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫A[1]=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣a[1](1)∣∣∣∣a[1](2)∣∣∣∣...∣∣∣∣a[1](m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫Z[2]=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣z[2](1)∣∣∣∣z[2](2)∣∣∣∣...∣∣∣∣z[2](m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫A[2]=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∣∣a[2](1)∣∣∣∣a[2](2)∣∣∣∣...∣∣∣∣a[2](m)∣∣⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫所以m维训练集神经网咯的计算过程可以表示为:Z[1]=W[1]X+b[1]A[1]=σ(Z[1])Z[2]=W[2]A[1]+b[2]A[2]=σ(z[2])
在上述过程中,我们所用到的激活函数都一直都是sigma函数,现在我们介绍几种其他常用的激活函数。
神经网络的梯度下降和logis回归中梯度下降类似
参 数 : W [ 1 ] , b [ 1 ] , W [ 2 ] , b [ 2 ] 梯 度 下 降 : p r e d t i o n ( y ^ ( i ) , i = 1... m ) d W [ 1 ] = d J d W [ 1 ] d b [ 1 ] = d J d b [ 1 ] . . . W [ 1 ] : = W [ 1 ] − α d W [ 1 ] b [ 1 ] : = b [ 1 ] − α d b [ 1 ] W [ 2 ] : = W [ 2 ] − α d W [ 2 ] b [ 2 ] : = b [ 2 ] − α d b [ 2 ] . . . 前 向 传 播 : Z [ 1 ] = W [ 1 ] X + b [ 1 ] A [ 1 ] = g [ 1 ] ( Z [ 1 ] ) Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] A [ 2 ] = g [ 2 ] ( Z [ 2 ] ) = σ ( Z [ 2 ] ) 后 向 传 播 : d z [ 2 ] = A [ 2 ] − Y d W [ 2 ] = 1 m d z 2 A [ 1 ] T d b [ 2 ] = 1 m n p . s u m ( d z [ 2 ] , a x i s = 1 , k e e p d i m s = T R U E ) d z [ 1 ] = W [ 2 ] T d z [ 2 ] ∗ g [ 1 ] X [ T ] d W [ 1 ] = 1 m d z [ 1 ] X [ T ] d b [ 1 ] = 1 m n p . s u m ( d z [ 1 ] , a x i s = 1 , k e e p d i m s = T r u e ) 参数:W^{[1]}, b^{[1]},W^{[2]},b^{[2]} \\ {}\\ 梯度下降:\\ {} \\ predtion (\hat{y}^{(i)},i=1...m) \\ {}\\ dW^{[1]}=\frac{dJ}{dW^{[1]}} \\ {}\\ db^{[1]}=\frac{dJ}{db^{[1]}} \\ {}\\ ... {}\\ W^{[1]}:=W^{[1]}-\alpha d W^{[1]} \\ {}\\ b^{[1]}:=b^{[1]}-\alpha d b^{[1]} \\ {}\\ W^{[2]}:=W^{[2]}-\alpha d W^{[2]} \\ {}\\ b^{[2]}:=b^{[2]}-\alpha d b^{[2]} \\ {}\\ ... 前向传播: \\ {}\\ Z^{[1]}=W^{[1]}X+b^{[1]} \\ {}\\ A^{[1]}=g^{[1]}(Z^{[1]}) \\ {}\\ Z^{[2]}=W^{[2]}A^{[1]}+b^{[2]} \\ {}\\ A^{[2]}=g^{[2]}(Z^{[2]})=\sigma(Z^{[2]}) \\ {}\\ 后向传播:\\ {}\\ dz^{[2]}=A^{[2]}-Y \\ {} \\ dW^{[2]}=\frac{1}{m}dz^{2}A^{[1]T} \\ {} \\ db^{[2]}=\frac{1}{m}np.sum(dz^{[2]},axis=1,keepdims=TRUE) \\ {}\\ dz^{[1]} = W^{[2]T}dz^{[2]} * g^{[1]}X^{[T]} \\ {}\\ dW^{[1]} = \frac{1}{m}dz^{[1]}X^{[T]}\\ {}\\ db^{[1]}=\frac{1}{m}np.sum(dz^{[1]},axis=1,keepdims=True) 参数:W[1],b[1],W[2],b[2]梯度下降:predtion(y^(i),i=1...m)dW[1]=dW[1]dJdb[1]=db[1]dJ...W[1]:=W[1]−αdW[1]b[1]:=b[1]−αdb[1]W[2]:=W[2]−αdW[2]b[2]:=b[2]−αdb[2]...前向传播:Z[1]=W[1]X+b[1]A[1]=g[1](Z[1])Z[2]=W[2]A[1]+b[2]A[2]=g[2](Z[2])=σ(Z[2])后向传播:dz[2]=A[2]−YdW[2]=m1dz2A[1]Tdb[2]=m1np.sum(dz[2],axis=1,keepdims=TRUE)dz[1]=W[2]Tdz[2]∗g[1]X[T]dW[1]=m1dz[1]X[T]db[1]=m1np.sum(dz[1],axis=1,keepdims=True)
如果初始变量都选择0,那么梯度下降法便会失效,所以一般情况下选择,初始变量都为随机数。
现在我们来证明一下为什么初始变量为0,则梯度下降法会失效。
由 于 初 始 化 为 0 则 : W [ 1 ] = [ 0 0 0 0 ] b [ 1 ] = [ 0 0 ] 因 为 : a = σ ( w T x + b ) 所 以 无 论 输 入 特 征 是 什 么 , 都 有 : a 1 [ 1 ] = a 2 [ 1 ] 在 第 二 层 中 : w [ 2 ] = [ 0 0 ] 所 以 : y ^ = a 1 [ 2 ] = σ ( w [ 2 ] T A + b ) w h e r e A = { a 1 [ 1 ] a 2 [ 1 ] } 在 反 向 传 播 中 : d z [ l ] = A [ l ] − A [ l + 1 ] 所 以 : d z 1 [ 1 ] = d z 2 [ 1 ] d w = { u v u v } 更 新 方 程 : w [ 1 ] = w [ 1 ] − α d w 由于初始化为0则:\\ W^{[1]}= \left[ \begin{matrix} 0 & 0 \\ 0 & 0 \\ \end{matrix} \right] \, b^{[1]}= \left[ \begin{matrix} 0 \\ 0 \end{matrix} \right] \\ {}\\ 因为: a=\sigma(w^Tx+b)\\ {}\\ 所以无论输入特征是什么,都有:\\ {}\\ a^{[1]}_1=a^{[1]}_2\\ {}\\ 在第二层中:w^{[2]}= \left[ \begin{matrix} 0 \\ 0 \end{matrix} \right]\\ {}\\ 所以 : \hat{y}=a^{[2]}_1=\sigma(w^{[2]T}A+b) where \quad A=\left\{ \begin{matrix} a^{[1]}_1 \\ a^{[1]}_2 \end{matrix} \right\}\\ {}\\ 在反向传播中: dz^{[l]}=A^{[l]}-A^{[l+1]} \\ {}\\ 所以:dz_1^{[1]}=dz_2^{[1]} \\ {} \\ dw= \left\{ \begin{matrix} u & v \\ u & v \end{matrix} \right\}\\ {}\\ 更新方程:\\ {}\\ w^{[1]}=w^{[1]}-\alpha dw\\ 由于初始化为0则:W[1]=[0000]b[1]=[00]因为:a=σ(wTx+b)所以无论输入特征是什么,都有:a1[1]=a2[1]在第二层中:w[2]=[00]所以:y^=a1[2]=σ(w[2]TA+b)whereA={a1[1]a2[1]}在反向传播中:dz[l]=A[l]−A[l+1]所以:dz1[1]=dz2[1]dw={uuvv}更新方程:w[1]=w[1]−αdw
所以最后无论更新多少层W的每一行都是相同的数据,即每一个单元对数据都以相同的方式处理。则更新方程不再有效,无法进行梯度下降法。
logistic可以理解为一个2层的神经网络,通过logistics回归大致的了解了神经网络的一个概况,现在我们通过一个四层神经网络,来介绍一下深层神经网络具体是怎么搭建和进行学习的.
对应上图中神经网络,先来规定一些记号。
L = 4 # l a y e r s n [ l ] # u n i t s i n l a y e r d a [ 1 ] # a c t i v t i o n s i n l a y e r d w [ l ] # w e i g h t s f o r z [ l ] b [ l ] # b a i s f o r z [ l ] n [ 1 ] = 5 , n [ 2 ] = 5 , n [ 3 ] = 3 , n [ 4 ] = 1 , n [ 0 ] = n x = 3 L = 4 \quad \#layers \\ {}\\ n^{[l]} \quad \# units \,\, in \,\, layerd \\ {}\\ a^{[1]} \quad \#activtions \,\, in \,\, layerd \\ {} \\ w^{[l]} \quad \# weights \,\, for \,\, z^{[l]} \\ {} \\ b^{[l]} \quad \#bais\,\,for\,\,z^{[l]} \\ {} \\ n^{[1]}=5 \,\, , n^{[2]}=5 \,\, , n^{[3]}=3 \,\, , n^{[4]}=1 \,\, , n^{[0]}=n_{x}=3 L=4#layersn[l]#unitsinlayerda[1]#activtionsinlayerdw[l]#weightsforz[l]b[l]#baisforz[l]n[1]=5,n[2]=5,n[3]=3,n[4]=1,n[0]=nx=3
第L层的前向传播:
i n p u t : a [ l − 1 ] ; o u t p u t : a [ l ] ; c a c h e : z [ 1 ] ; z [ l ] = w [ l ] a [ l − 1 ] + b [ l ] a [ l ] = g [ l ] ( z [ l ] ) v e c t o r i z e d : Z [ l ] = W [ l ] ⋅ A [ l − 1 ] + b [ l ] A [ l ] = g [ l ] ( Z [ l ] ) input: a^{[l-1]};\quad output : a^{[l]};\quad \\ {}\\ cache:z^{[1]}; \\ {} \\ z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]} \\ {} \\ a^{[l]}=g^{[l]}(z^{[l]}) \\ {} \\ vectorized: \\ {}\\ Z^{[l]}=W^{[l]}·A^{[l-1]}+b^{[l]} \\ {}\\ A^{[l]}=g^{[l]}(Z^{[l]}) \\ input:a[l−1];output:a[l];cache:z[1];z[l]=w[l]a[l−1]+b[l]a[l]=g[l](z[l])vectorized:Z[l]=W[l]⋅A[l−1]+b[l]A[l]=g[l](Z[l])
第L层的反向传播:
i n p u t : d a [ l ] o u t p u t : d a [ l − 1 ] , d w [ l ] , d b [ l ] d z [ l ] = d a [ l ] ⋅ g [ l ] ( z [ l ] ) d w [ l ] = d z [ l ] ⋅ a [ l − 1 ] d b [ l ] = d z [ l ] d a [ l − 1 ] = w [ l ] d z [ l ] v e c t o r i z e d : d Z [ l ] = d A [ l ] ∗ g [ l ] ( Z [ l ] ) d W [ l ] = 1 m d Z [ l ] A [ l − 1 ] T d b [ l ] = 1 m n p . s u m ( d Z [ l ] , a x i s = 1 , k e e p d i m s = T r u e ) d A [ l − 1 ] = W [ l ] T d Z [ l ] input:da^{[l]} \\ {} \\ output:da^{[l-1]},dw^{[l]},db^{[l]} \\ {} \\ dz^{[l]}=da^{[l]}·g^{[l]}(z^{[l]}) \\ {} \\ dw^{[l]}=dz^{[l]}·a^{[l-1]} \\ {} \\ db^{[l]}=dz^{[l]} \\ {} \\ da^{[l-1]}=w^{[l]}dz^{[l]} \\ {} \\ vectorized: \\ {} \\ dZ^{[l]}=dA^{[l]}*g^{[l]}(Z^{[l]}) \\ {} \\ dW^{[l]}=\frac{1}{m}dZ^{[l]}A^{[l-1]T} \\ {}\\ db^{[l]}=\frac{1}{m}np.sum(dZ^{[l]},axis=1,keepdims=True) \\ {}\\ dA^{[l-1]} = W^{[l]T}dZ^{[l]} \\ input:da[l]output:da[l−1],dw[l],db[l]dz[l]=da[l]⋅g[l](z[l])dw[l]=dz[l]⋅a[l−1]db[l]=dz[l]da[l−1]=w[l]dz[l]vectorized:dZ[l]=dA[l]∗g[l](Z[l])dW[l]=m1dZ[l]A[l−1]Tdb[l]=m1np.sum(dZ[l],axis=1,keepdims=True)dA[l−1]=W[l]TdZ[l]
在搭建的神层神经网络之前,我们首先了解一下为什么是“深层”,神经网络不一定得非常的大,但是应该有深度。通过异或门来深刻的理解为什么“深”的神经网络要比“大”(单层网络中的节点多)的神经网络好。
现在想要学习如下的模型:
这 是 一 个 异 或 函 数 y = x 1 X O R x 2 X O R x 3 X O R ⋅ ⋅ ⋅ X O R x n ( X O R 为 异 或 门 ) 这是一个异或函数 y = x_1 XOR x_2 XOR x_3 XOR··· XOR x_n (XOR为异或门) 这是一个异或函数y=x1XORx2XORx3XOR⋅⋅⋅XORxn(XOR为异或门)
如果是深层网络则可以表示为:
利用深层神经网络,通过这样的结构我们每层需要计算n/2次计算,共需要logn次计算即可。
如果利用单层神经网络,其结构为:
通过上述单隐藏层可以了解到一个有n个输入的单层神经网络一共需要2^n次计算,相比于深度神经网络,按照指数倍增加了计算次数。通过这个例子我们可以清楚的了解到神经网络的“深”要远远好于其“大”。
搭建深度神经网络的主要结构依据前向传播和后向传播的思想。输入特征矩阵X,通过前向传播依次到输出y,然后通过反向传播计算代价函数对中间变量a的导数,从而推出参数,即权重W和偏执b的导数,然后进行更新参数,最后再进行下一次计算,周而复试,不断缩小代价函数(cost function),最终达到我们所需要的精度。
上图为一轮神经网络的训练过程,然后通过下述更新方程对参数进行更新从而开始新的一轮的训练。
W [ l ] = W [ l ] − α d W [ l ] b [ 1 ] = b [ 1 ] − α d w [ l ] W^{[l]}=W^{[l]}-\alpha dW^{[l]} \\ {}\\ b^{[1]}=b^{[1]}-\alpha dw{[l]} W[l]=W[l]−αdW[l]b[1]=b[1]−αdw[l]
在神经网络中参数通常指权重W和偏执b,但是除了这些我们还存在,神经网络迭代次数,学习率,隐藏单元数,隐藏层数,激活函数的选取等,我们把这些决定参数的参数称之为超参数。
p a r a m e t e r : W , b H y p e r p a r a m e t e r : # i t e r a t i o n # h i d d e r l a y e r L # a c t i v t i o n f u n c t i o n # m o m e n t # m i n i b a t c h s i z e parameter: W,b \\ {}\\ Hyperparameter: \\ {} \\ \# iteration \\ {}\\ \# hidder \,\,layer L \\ {}\\ \# activtion \,\, function \\ {}\\ \#moment \\ {}\\ \# minibatch \,\, size parameter:W,bHyperparameter:#iteration#hidderlayerL#activtionfunction#moment#minibatchsize
参数是可以通过网络自己进行迭代学习,但是超参数往往需要我们自己主观的选择,存在着一定的偶然,一种常用的调参的思想既是通过代价函数,在调参的同时观察代价函数是否下降,如果代价函数是下降的方向,说明我们调参的方向是正确的。