吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)

文章目录

前言

本系列文章是吴恩达深度学习攻城狮系列课程的笔记,分为五部分。

这一部分讲了深度学习和神经网络的最基础的概念,这一章尤为重要,尤其是要理解神经网络的合理性,建立直觉。

我的笔记不同于一般的笔记,我的笔记更加凝练,除了结论以及公式,更多的是对知识的理解,结合课程可以加速理解,省去很多时间,但是请注意,笔记不能替代课程,应该结合使用。

传送门

结构化机器学习项目,我建议放在最后看。

首先学这一节对你后面的学习没有影响,我就是跳过去学的。而且他更多的讲的是策略,尤其是举了很多后面的例子,你听了不仅不太好懂,而且没啥意思,所以我建议放在最后看。

神经网络与深度学习(Neural Networks and Deep Learning)

改善深层神经网络:超参数调整,正则化,最优化(Hyperparameter Tuning)

卷积神经网络(Convolutional Neural Networks)

序列模型与循环神经网络(Sequence Models)

结构化机器学习项目(Structuring Machine Learning Projects)

神经网络与深度学习(Neural Networks and Deep Learning)

绪论

梯度下降的公式为:
w = w − α d w w=w-\alpha dw w =w −αd w

这让我们想到牛顿法:
x = x − f ( x ) f ′ ( x ) x=x-\dfrac{f(x)}{f^\prime(x)}x =x −f ′(x )f (x )​

这两个有什么区别呢?思想都是迭代,但是实际完全不一样,最简单的场景:

吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)
我们从x 0 x_0 x 0 ​开始跑,就会发现,最后gradient-descent会收敛到x g x_g x g ​但是牛顿法收敛到x n x_n x n ​

虽然方向都是导数负方向,但是步长是这两个方法的本质区别””

  1. gradient-descent的步长不由α \alpha α决定,而是由导数决定,导数越大,下降越快,什么时候不动了呢?就是f ′ ( x ) f^\prime(x)f ′(x )为0的时候,也就是谷底。
  2. 牛顿法的步长由f ( x ) f ′ ( x ) \dfrac{f(x)}{f^\prime(x)}f ′(x )f (x )​决定,如果假设导数仅仅决定方向,那么f ( x ) f(x)f (x )越大,下降越快。什么时候不动了呢?就是f ( x ) = 0 f(x)=0 f (x )=0,也就是零点。

; 梯度下降法与二分逻辑回归(Gradient Descend and Logistics Regression)

forward propagation

  1. 样本:X ( i ) X^{(i)}X (i )是一个n维向量,总共给定m个样本
  2. 样本矩阵:[ X ( 1 ) , ⋯ , X ( m ) ] n × m [X^{(1)},\cdots,X^{(m)}]_{n\times m}[X (1 ),⋯,X (m )]n ×m ​
  3. 参数:w w w 是一个n维向量$b b b是一个实数,我们的目标就是通过不断的迭代调整这两个参数
  4. 实际值和预测值:
    实际值为y y y,仅有0,1两种
    预测值是一个概率,写作a = y ^ = σ ( z ( i ) ) a=\hat{y}=\sigma(z^{(i)})a =y ^​=σ(z (i ))
    z ( i ) = w T X ( i ) + b z^{(i)}=w^TX^{(i)}+b z (i )=w T X (i )+b,z只是一个最初的预测,是在R范围上的,要进行转化
    σ ( x ) = 1 1 + e − x \sigma(x)=\dfrac{1}{1+e^{-x}}σ(x )=1 +e −x 1 ​,这个激活函数将R上的z变为0-1之间的数,可以理解为概率。
  5. 损失函数:L ( a , y ) = − ( y log ⁡ ( a ) + ( 1 − y ) log ⁡ ( 1 − a ) ) L(a,y)=-(y\log(a)+(1-y)\log(1-a))L (a ,y )=−(y lo g (a )+(1 −y )lo g (1 −a )),代表单个样本的差距
  6. 成本函数:J ( w , b ) = 1 m ∑ L ( a ( i ) , y ( i ) ) J(w,b)=\dfrac{1}{m}\sum L(a^{(i)},y^{(i)})J (w ,b )=m 1 ​∑L (a (i ),y (i )),代表样本总体的平均差距

backward propagation(with Chain Rule)

使用计算图+链式法则求导,省略部分步骤,直接到关键步

  1. d z ( i ) = a ( i ) − y ( i ) dz^{(i)}=a^{(i)}-y^{(i)}d z (i )=a (i )−y (i ),对每一个x ( i ) x^{(i)}x (i ),都有一个d z ( i ) dz^{(i)}d z (i )
  2. d w i = 1 m ∑ x i ( i ) d z ( i ) dw_i=\dfrac{1}{m}\sum x_i^{(i)}dz^{(i)}d w i ​=m 1 ​∑x i (i )​d z (i ),对每一个w w w,都是由m个X ( i ) X^{(i)}X (i )生成,其中w w w的每一个元,都是有m个X ( i ) X^{(i)}X (i )的对应元生成
  3. d b = d z db=dz d b =d z ,db由所有d z ( i ) dz^{(i)}d z (i )生成

vectorization

避免使用显式的for loop,而是改用numpy的向量和矩阵运算函数,其中内置了大量的加速算法,以及调用多线程,充分利用CPU以及GPU的计算资源,可以将性能提高百倍以上。

总体流程为fp:w , b , X − > Z , σ − > A w,b,X->Z,\sigma->A w ,b ,X −>Z ,σ−>A,bp:A , Y − > d Z , X − > d w , d b A,Y->dZ,X->dw,db A ,Y −>d Z ,X −>d w ,d b,将 w 和 b 将w和b 将w 和b迭代然后不断循环,直至足够准确。

  1. 将 m 个 X 样本写成一个矩阵为 X ,然后分块 将m个X样本写成一个矩阵为X,然后分块将m 个X 样本写成一个矩阵为X ,然后分块[ X ( 1 ) , ⋯ , X ( m ) ] [X^{(1)},\cdots,X^{(m)}][X (1 ),⋯,X (m )]
  2. 将 m 个 y 样本写成一个矩阵为 将m个y样本写成一个矩阵为将m 个y 样本写成一个矩阵为Y = [ y ( 1 ) , ⋯ , y ( m ) ] Y=[y^{(1)},\cdots, y^{(m)}]Y =[y (1 ),⋯,y (m )]
  3. 将 z ( i ) 写成矩阵,为 将z^{(i)}写成矩阵,为将z (i )写成矩阵,为Z = [ z ( 1 ) , ⋯ , z ( m ) ] Z=[z^{(1)},\cdots, z^{(m)}]Z =[z (1 ),⋯,z (m )]
  4. 则有 则有则有Z = w T X + B = w T [ X ( 1 ) , ⋯ , X ( m ) ] Z=w^TX+B=w^T[X^{(1)},\cdots, X^{(m)}]Z =w T X +B =w T [X (1 ),⋯,X (m )]
    = [ w T X ( 1 ) , ⋯ , w T X ( m ) ] =[w^TX^{(1)},\cdots,w^TX^{(m)}]=[w T X (1 ),⋯,w T X (m )],
    这就是一个简单的分块矩阵然后 w T 左乘 这就是一个简单的分块矩阵然后w^T左乘这就是一个简单的分块矩阵然后w T 左乘就是相当于对分块矩阵行进行作用 就是相当于对分块矩阵行进行作用就是相当于对分块矩阵行进行作用
  5. 对 Z 矩阵进行 σ 作用,转换成 A 矩阵 对Z矩阵进行\sigma作用,转换成A矩阵对Z 矩阵进行σ作用,转换成A 矩阵
  6. d Z = A − Y ,很明显,两个行向量直接相减即可得出 d Z dZ=A-Y,很明显,两个行向量直接相减即可得出dZ d Z =A −Y ,很明显,两个行向量直接相减即可得出d Z
  7. d w = 1 m X d Z T dw=\dfrac{1}{m}XdZ^T d w =m 1 ​X d Z T,这一步看着有点迷惑,但是确实有效,从效果上,可以理解为用每一个z ( i ) 作用到一列 X ( i ) z^{(i)}作用到一列X^{(i)}z (i )作用到一列X (i )上,然后通过矩阵积的性质实现累加,最后外面挂个求均值得出结果
  8. d b = 对 d Z 向量求均值 db=对dZ向量求均值d b =对d Z 向量求均值

损失函数和成本函数推导(Loss Function | Cost Function)

损失函数 L ( a , y ) = − [ y log ⁡ ( a ) + ( 1 − y ) log ⁡ ( 1 − a ) ] L(a,y)=-[y\log(a)+(1-y)\log(1-a)]L (a ,y )=−[y lo g (a )+(1 −y )lo g (1 −a )]
成本函数

  1. 损失函数

定义a = P ( y = 1 ∣ X ) a=P(y=1|X)a =P (y =1∣X ),即给定样本下得出y=1的概率。那么,反过来。P ( y = 0 ∣ X ) = 1 − a P(y=0|X)=1-a P (y =0∣X )=1 −a,即,给定X得出y=0的概率为1-a

对于单个样本,即X X X,他的真实结果不是0,就是1,也就是说,是两点分布。那么我们可以写出P ( y ∣ X ) = a y ( 1 − a ) 1 − y P(y|X)=a^y(1-a)^{1-y}P (y ∣X )=a y (1 −a )1 −y,这是个很经典的两点分布写法,分别取y=1和0,可以得出我们最开始的两种情况。

然后左右两边同取log(实际上是ln),得log ⁡ ( P ) = y a + ( 1 − y ) ( 1 − a ) \log(P)=ya+(1-y)(1-a)lo g (P )=y a +(1 −y )(1 −a ),因为我们用梯度下降,是要最小化,所以为了最大化概率P,我们要在损失函数前加负号,这样,当我们把损失函数最小化,那么里面的非负部分就是最大化的了,即P最大。

  1. 成本函数

成本函数使用极大似然估计推导。

首先,假设m个样本都是独立同分布的,这个应该在找样本的时候就确保好,然后我们就可以用最大似然估计了。

P ( X ∣ θ ) = ∏ P ( y i ∣ X i ) P(X|\theta)=\prod P(y^i|X^i)P (X ∣θ)=∏P (y i ∣X i ),然后用最大似然估计的套路,左右取ln,得出log ⁡ P ( X ∣ θ ) = − ∑ L ( a i , y i ) \log P(X|\theta)=-\sum L(a^i,y^i)lo g P (X ∣θ)=−∑L (a i ,y i ),为了使P最大,需要令∑ L ( a i , y i ) \sum L(a^i,y^i)∑L (a i ,y i )最小,出于某种原因,我们给他前面加了一个常数来进行一个缩放,最后就是J ( w , b ) = 1 m ∑ L ( a i , y i ) J(w,b)=\dfrac{1}{m}\sum L(a^i,y^i)J (w ,b )=m 1 ​∑L (a i ,y i )

其实这个也可以直观理解。

让所有样本的平均损失最小,不就整体最优了嘛。

多层神经网络入门

一些符号的规定

  1. 神经网络分层,用[] 作为上标来表明层数,输入层为0层,所以通常观念中,输入层不算做神经网络层中的一层。L为总层数。
  2. n x = n [ 0 ] n_x=n^{[0]}n x ​=n [0 ],为输入特征数,, n [ i ] ,n^{[i]},n [i ]为每层的神经元个数,理论上这两个其实是一类东西,因为每一层经过神经元作用后,输到下一层的特征数就会变成n
  3. 每一层的每一个节点都是神经元,每一个节点分为两部分,第一部分是使用w 作用 w作用w 作用,第二部分是激活函数作用。一个神经元就相当于我们前面的logistic 回归,一层就是若干个logistic回归堆叠而成。
  4. W m × n [ i ] = W n [ i ] × n [ i − 1 ] [ i ] 代表第 i 层的神经网络参数,是 w 的推广 W^{[i]}{m\times n}=W^{[i]}{n^{[i]}\times n^{[i-1]}}代表第i层的神经网络参数,是w的推广W m ×n [i ]​=W n [i ]×n [i −1 ][i ]​代表第i 层的神经网络参数,是w 的推广,可以看做是当前层所有节点的 w T 垂直 堆叠而成 可以看做是当前层所有节点的w^T \textbf{垂直} 堆叠而成可以看做是当前层所有节点的w T 垂直堆叠而成,所以 W [ i ] = [ [ w 1 [ i ] T ] , [ w 2 [ i ] T ] , ⋯ , [ w m [ i ] T ] ] 所以W^{[i]}=[[w^{[i]T}_1],[w^{[i]T}_2],\cdots,[w^{[i]T}_m]]所以W [i ]=[[w 1 [i ]T ​],[w 2 [i ]T ​],⋯,[w m [i ]T ​]]总共堆m行,m是本层神经元个数= n [ i ] =n^{[i]}=n [i ],每一行都是n维向量,n是上一层传过来特征的数量= n [ i − 1 ] =n^{[i-1]}=n [i −1 ]。
    所以可以看出来,水平遍历可以将单个神经元接收的所有特征遍历,垂直遍历可以将单个特征导向的所有神经元遍历。
  5. B [ i ] 代表第 i 层的神经网络参数,是 b 的推广, B^{[i]}代表第i层的神经网络参数,是b的推广,B [i ]代表第i 层的神经网络参数,是b 的推广,可以看做是当前层所有节点的 b 堆叠而成,同样是 垂直 堆叠 可以看做是当前层所有节点的b堆叠而成,同样是\textbf{垂直}堆叠可以看做是当前层所有节点的b 堆叠而成,同样是垂直堆叠
  6. Z [ i ] 是 z T 的水平堆叠 Z^{[i]}是z^T的水平堆叠Z [i ]是z T 的水平堆叠
  7. A [ i ] 是 a T 的水平堆叠,是 Z [ i ] 被 g 作用后的矩阵 A^{[i]}是a^T的水平堆叠,是Z^{[i]}被g作用后的矩阵A [i ]是a T 的水平堆叠,是Z [i ]被g 作用后的矩阵,A n x × m [ 0 ] = X A^{[0]}{n_x\times m}=X A n x ​×m [0 ]​=X,A [ L ] = Y ^ 1 × m A^{[L]}=\hat{Y}{1\times m}A [L ]=Y ^1 ×m ​
  8. g [ i ] g^{[i]}g [i ]代表当前层的激活函数

神经网络的向量化fp

设X=A{[0]},\hat{Y}=A{[L]},则逐层计算,这个for loop现在没有办法避免:

for i = 1 to L:

Z [ i ] = W [ i ] A [ i − 1 ] + B [ i ] Z^{[i]}=W^{[i]}A^{[i-1]}+B^{[i]}Z [i ]=W [i ]A [i −1 ]+B [i ]
A [ i ] = g ( Z [ i ] ) A^{[i]}=g(Z^{[i]})A [i ]=g (Z [i ])

这个式子可以分块理解,还原他们堆叠之前的状态,然后这个分块列向量乘以分块行向量再加B向量(广播后实际为矩阵),出来一个矩阵,这个矩阵每行对应于单节点的logistic regression,然后垂直堆叠起来一层的结果。

我们换个角度理解这个产生的矩阵,经过sigmoid函数作用后生成的A矩阵,如果从列来看,实际上每一列都相当于一个样本X ( i ) X^{(i)}X (i )经过一层神经网络后产生的新样本,只不过该样本的维数(长度)变成了当前层神经元的个数,但是很明显,样本数量没有变化。

也就是说:

节点数n [ i ] n^{[i]}n [i ]=参数矩阵W [ i ] W^{[i]}W [i ]的高度=样本矩阵A [ i ] A^{[i]}A [i ]的高度.

以上随着神经网络的层而变化。

但是:

A [ i ] 矩阵的宽度 ≡ 初始样本数 A^{[i]}矩阵的宽度\equiv 初始样本数A [i ]矩阵的宽度≡初始样本数

以上 随层而变化。

我们从更高层的角度去理解W和Z,B的形状:

B和W是按照神经元垂直堆叠的,所以这两个的高度 ≡ 当前层神经元个数 高度\equiv 当前层神经元个数高度≡当前层神经元个数

然后因为激活函数不改变形状,所以实际上结果A ∼ Z ∼ W W W ⋯ X A\sim Z\sim WWW\cdots X A ∼Z ∼WWW ⋯X,因为最右矩阵是X,所以A,Z矩阵的宽度恒定为m

至于W的宽度,这个根据上一层的n定。

最后,不管你有多少层,最终还是输出了一个A m × 1 A_{m\times 1}A m ×1 ​,因此,Lost和Cost的计算方法完全相同。

神经网络的向量化bp

d Z n [ i ] × m [ i ] = { A [ i ] − Y , i = L d A [ i ] ∗ g [ i ] ′ ( Z [ i ] ) , i ≠ L , ∗ 为 e l e m e n t − w i s e 逐元素相乘 dZ^{[i]}_{n^{[i]}\times m}= \begin{cases} A^{[i]}-Y, & i=L \ dA^{[i]}g^{[i]\prime}(Z^{[i]}), & i\neq L,为element-wise逐元素相乘 \end{cases}d Z n [i ]×m [i ]​={A [i ]−Y ,d A [i ]∗g [i ]′(Z [i ]),​i =L i =L ,∗为e l e m e n t −w i se 逐元素相乘​
其中,dA的计算是反向递归的,要给一个递归初始值

d A [ i − 1 ] = { [ − y ( 1 ) a ( 1 ) + 1 − y ( 1 ) 1 − a ( 1 ) , ⋯ , − y ( m ) a ( m ) + 1 − y ( m ) 1 − a ( m ) ] 1 × m , i = L W [ i ] T d Z [ i ] , i ≠ L dA^{[i-1]}= \begin{cases} [-\dfrac{y^{(1)}}{a^{(1)}}+\dfrac{1-y^{(1)}}{1-a^{(1)}},\cdots,-\dfrac{y^{(m)}}{a^{(m)}}+\dfrac{1-y^{(m)}}{1-a^{(m)}}]_{1\times m},& i=L \ W^{[i]T}dZ^{[i]},& i\neq L \ \end{cases}d A [i −1 ]=⎩⎨⎧​[−a (1 )y (1 )​+1 −a (1 )1 −y (1 )​,⋯,−a (m )y (m )​+1 −a (m )1 −y (m )​]1 ×m ​,W [i ]T d Z [i ],​i =L i =L ​

第一个式子可以迁移,第二个式子直观理解只能通过维数来理解他的合理性。

  1. d W n [ i ] × n [ i − 1 ] [ i ] = 1 m d Z [ i ] A [ i − 1 ] T dW^{[i]}_{n^{[i]}\times n^{[i-1]}}=\dfrac{1}{m} dZ^{[i]}A^{[i-1]T}d W n [i ]×n [i −1 ][i ]​=m 1 ​d Z [i ]A [i −1 ]T
    这个可以迁移理解,在Logistic Regression里,d w = 1 m X d Z T dw=\dfrac{1}{m}XdZ^T d w =m 1 ​X d Z T,而我们这里的W矩阵是若干个w T w^T w T纵向堆叠而成,所以我们要做一个转置。
  2. d B n [ i ] × 1 [ i ] = 1 m n p . s u m ( d Z [ i ] , a x i s = 1 , k e e p d i m s = T r u e ) . r e s h a p e ( n [ i ] , 1 ) dB^{[i]}_{n^{[i]}\times 1}=\dfrac{1}{m} np.sum(dZ^{[i]},axis=1,keepdims=True).reshape(n^{[i]},1)d B n [i ]×1 [i ]​=m 1 ​n p .s u m (d Z [i ],a x i s =1 ,k ee p d im s =T r u e ).res ha p e (n [i ],1 )
    这个如此理解,对每一个节点,我们都要对所有样本进行均值,所以进行横向求均值,形成若干个b堆叠而成的向量,最后一层的B就是一个实数。

写到这里,我不由得感叹矩阵的强大,真tm哪个小天才能想出这种玩意,能让公式随着维数的增加而保持形式稳定,太离谱了!

神经网络函数块

其实可以看出来,除了最后一层有点特殊以外,每一层的处理方式都是相同的,那可不可以编写一个函数去一次性处理一层的任务呢?

可以,以下是流程图:

吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)

; fp块

Input: A [ i − 1 ] A^{[i-1]}A [i −1 ]

Process:

Z [ i ] = n p . d o t ( W [ i ] , A [ i − 1 ] ) + B [ i ] Z^{[i]}=np.dot(W^{[i]},A^{[i-1]})+B^{[i]}Z [i ]=n p .d o t (W [i ],A [i −1 ])+B [i ]

A [ i ] = g [ i ] ( Z [ i ] ) A^{[i]}=g^{[i]}(Z^{[i]})A [i ]=g i

Cache: Z [ i ] Z^{[i]}Z [i ]

Output: A [ i ] A^{[i]}A [i ]

bp块

Input: d A [ i ] dA^{[i]}d A [i ]

Process:

d Z [ i ] = d A [ i ] ∗ g [ i ] ′ ( Z [ i ] ) dZ^{[i]}=dA^{[i]}*g^{[i]\prime }(Z^{[i]})d Z [i ]=d A [i ]∗g [i ]′(Z [i ])

d W [ i ] = 1 m n p . d o t ( d Z [ i ] , A [ i − 1 ] T ) dW^{[i]}=\dfrac{1}{m}np.dot(dZ^{[i]},A^{[i-1]T})d W [i ]=m 1 ​n p .d o t (d Z [i ],A [i −1 ]T )

d B [ i ] = 1 m n p . s u m ( d Z [ i ] , a x i s = 1 , k e e p d i m s = T r u e ) dB^{[i]}=\dfrac{1}{m}np.sum(dZ^{[i]},axis=1,keepdims=True)d B [i ]=m 1 ​n p .s u m (d Z [i ],a x i s =1 ,k ee p d im s =T r u e )

d A [ i − 1 ] = n p . d o t ( W [ i ] T , d Z [ i ] ) dA^{[i-1]}=np.dot(W^{[i]T},dZ^{[i]})d A [i −1 ]=n p .d o t (W [i ]T ,d Z [i ])

Output: d A [ i − 1 ] , d W [ i ] , d B [ i ] dA^{[i-1]} , dW^{[i]} , dB^{[i]}d A [i −1 ],d W [i ],d B [i ]

一轮迭代的处理流程

  1. 赋值A [ 0 ] = X A^{[0]}=X A [0 ]=X
  2. 不断调用fp函数,生成A和Z
  3. 赋值d A [ L ] = [ − y ( 1 ) a ( 1 ) + 1 − y ( 1 ) 1 − a ( 1 ) , ⋯ , − y ( m ) a ( m ) + 1 − y ( m ) 1 − a ( m ) ] 1 × m dA^{[L]}=[-\dfrac{y^{(1)}}{a^{(1)}}+\dfrac{1-y^{(1)}}{1-a^{(1)}},\cdots,-\dfrac{y^{(m)}}{a^{(m)}}+\dfrac{1-y^{(m)}}{1-a^{(m)}}]_{1\times m}d A [L ]=[−a (1 )y (1 )​+1 −a (1 )1 −y (1 )​,⋯,−a (m )y (m )​+1 −a (m )1 −y (m )​]1 ×m ​
  4. 反向调用bp函数,生成dA,dW,dB,更新W,B矩阵

激活函数

可选项

  1. sigmoid/tanh
    tanh ⁡ ( x ) = e x − e − x e x + e − x \tanh(x) =\dfrac{e^x-e^{-x}}{e^x+e^{-x}}tanh (x )=e x +e −x e x −e −x ​,隐藏层常用,因为有期望为0的特征,往往表现比sigmoid函数好,而sigmoid常用于输出层的激活。同时,tanh也有缺陷,就是在|z|很大的时候,梯度几乎为0,会拖慢迭代速度。
  2. ReLU/Leaky ReLU (Rectified Linear Unit)
    a = m a x ( 0 , z ) a=max(0,z)a =ma x (0 ,z ),线性修正单元出现了,这个是隐藏层激活函数的默认选项。 因为其梯度的稳定性,用其实现的神经网络迭代速度很快。
    a = m a x ( 0.01 z , z ) , a=max(0.01z,z),a =ma x (0.01 z ,z ),Leaky ReLU的出现是用来修正ReLU在负数情况下梯度为0的情况的。但是实际上因为神经元多以及初始样本的输入,出现z小于0的情况很少
  3. 为什么要使用非线性激活函数
    如果全都是线性的,那么最后的计算结果也不过是一种线性组合,化简后就会发现,无论多少层网络,最终效果就和一层网络相同。
    如果要用,就是输出层或者是用于特殊用途的隐藏层。

导数计算(prime)

  1. sigmoid
    g ′ ( z ) = a ( 1 − a ) g^\prime (z)=a(1-a)g ′(z )=a (1 −a )
  2. tanh
    g ′ ( z ) = 1 − a 2 g^\prime (z)=1-a^2 g ′(z )=1 −a 2
    直观理解,如果|z|足够大,( t a n h ( z ) ) 2 (tanh(z))^2 (t anh (z ))2趋近1,也就是导数趋近0
  3. ReLU
    g ′ ( z ) = { 0 , z ≤ 0 1 , z > 0 g^\prime (z)= \begin{cases} 0 ,& z \leq 0 \ 1 ,& z > 0 \end{cases}g ′(z )={0 ,1 ,​z ≤0 z >0 ​
  4. Leaky ReLU
    g ′ ( z ) = { 0.01 , z ≤ 0 1 , z > 0 g^\prime(z)= \begin{cases} 0.01, & z \leq 0 \ 1, & z>0 \end{cases}g ′(z )={0.01 ,1 ,​z ≤0 z >0 ​

随机初始化

  1. W = n p . r a n d o m . r a n d n ( ( n [ i ] , n [ i − 1 ] ) ) ∗ 0.01 W=np.random.randn((n^{[i]},n^{[i-1]}))*0.01 W =n p .r an d o m .r an d n ((n [i ],n [i −1 ]))∗0.01

首先,W不能对称,即W的行不能相同。如果有相同,那这两个神经元就造成了浪费,如果完全对称,那么每层神经元就相当于一个神经元

然后,乘一个系数调整使得权重足够小,防止Z矩阵元素过大导致sigmoid或者tanh函数饱和,从而拖慢学习速度。

  1. B = n p . z e r o ( ( n [ i ] , 1 ) ) B=np.zero((n^{[i]},1))B =n p .zero ((n [i ],1 ))

B其实随便,因为W已经随机了

深层网络的合理性

首先,从图像识别来看,神经网络就相当于从细微的特征入手,然后逐层组装,最后合成一个目标特征。

然后,深层神经网络可以在计算复杂问题的时候有效降低神经元规模,用深度换取空间复杂度。这个起源于电路理论。

emm,我其实也不太理解,看了几个小文章,大概理解了:逐层抽象提取分类,可以让简单的特征被下一层复用,有一种类似于通过动态规划来降低递归的重复计算的作用。暂时这么理解吧。

Original: https://blog.csdn.net/weixin_50295745/article/details/126333483
Author: 亦梦亦醒乐逍遥
Title: 吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/617320/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球