吴恩达深度学习 (week3,4)

news2024/12/25 8:56:00

文章目录

  • 一、神经网络概述
  • 二、神经网络的表示
  • 三、神经网络的输出
  • 四、多个例子的向量化
  • 五、向量化实现的解释
  • 六、深度学习激活函数
  • 七、激活函数导数
  • 八、神经网络的梯度下降法
  • 九、深度学习随机初始化
  • 十、上述学习总结
    • 1、第一题
    • 2、第二题
    • 3、第三题
    • 4、第四题
    • 5、第五题
    • 6、第六题
    • 7、第7题
  • 十一、深层神经网络常识
  • 十二、深度学习前向和反向传播
  • 十三、编程大作业实现
    • 1、环境准备与数据集
    • 2、Logistic回归的分类效果
    • 2、定义神经网络结构
    • 3、初始化模型的参数
    • 4、sigmoid与tanh前向传播
    • 5、计算成本函数J
    • 6、反向传播(难点)
    • 7、更新参数和模型整合
    • 8、预测与运行

一、神经网络概述

推荐视频神经网络的本质与结构 3Blue1Brown

  • 前情提要:神经网络公式

在这里插入图片描述

  • 可以把许多sigmoid单元堆叠起来形成一个神经网络

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

		在逻辑回归中,通过直接计算 z 得到结果 a 。而这个神经网络中,我们反复的计算 z  和 a ,计算 a  和 z ,最后得到了最终的输出`loss function`。
		
		在逻辑回归中,有一些从后向前的计算用来计算导数 `da、dz` 。同样,在神经网络中我们也有从后向前的计算,看起来就像这样,最后会计算 da^[2]^、   dz^[2]^、   计算出来之后,然后计算dw^[2]^、   db^[2]^等,按公式3.4、3.5箭头表示的那样,从右到左反向计算。

基于逻辑回归重复使用了两次该模型得到上述例子的神经网络。

逻辑回归中的导数 ( da ) 和 ( dz ) 是损失函数关于预测概率 (a) 和线性组合输入 (z) 的偏导数,它们在反向传播算法中用于更新模型参数 (w) 和 (b)。具体来说:

  1. 导数 ( da ) 是损失函数 ( L(a,y) ) 相对于预测概率 ( a ) 的偏导数。根据二元交叉熵损失函数,我们有:
  • ( da = dL/da = -y/a + (1-y)/(1-a) )
  1. 导数 ( dz ) 是损失函数 ( L(a,y) ) 相对于 ( z ) 的偏导数,并且是通过链式法则从 ( da ) 推导得到的:
    • ( dz = dL/dz = da * a(1-a) )
  2. 在具体的梯度下降步骤中,我们会使用以下公式来更新参数 ( w ) 和 ( b ):
    • ( dw = X^Tdz ) (其中 ( X ) 是输入特征矩阵,( dz ) 是一个向量或矩阵,根据上下文而定)
    • ( db = dz ) (因为 ( b ) 是一个标量)

这些导数对于理解如何通过梯度下降来优化逻辑回归模型至关重要。在每次迭代中,我们计算这些导数值并用它们来调整 ( w ) 和 ( b ),以期减小损失函数的值,从而提高模型的预测性能。

二、神经网络的表示

下面的x1 x2 x3表示一个样本的三个特征值
在这里插入图片描述

  • 有输入特征 x 1 、 x 2 、 x 3 ,它们被竖直地堆叠起来,这叫做神经网络的输入层(Input Layer)。
  • 它包含了神经网络的输入;然后这里有另外一层我们称之为隐藏层(Hidden Layer)。
  • 在本例中最后一层只由一个结点构成,而这个只有一个结点的层被称为输出层(Output Layer),它负责产生预测值。
  • 隐藏层的含义:在一个神经网络中,使用监督学习训练它的时候,训练集包含了输入 x 也包含了目标输出 y ,所以术语隐藏层的含义是在训练集中,这些中间结点的准确值我们是不知道到的,也就是说你看不见它们在训练集中应具有的值。你能看见输入的值,你也能看见输出的值,但是隐藏层中的东西,在训练集中你是无法看到的。所以这也解释了词语隐藏层,只是表示你无法在训练集中看到他们。

现在我们再引入几个符号,就像我们之前用向量 x 表示输入特征。这里有个可代替的记号 a[0] 可以用来表示输入特征。 a 表示激活的意思,它意味着网络中不同层的值会传递到它们后面的层中,输入层将 x传递给隐藏层,所以我们将输入层的激活值称为 a[0]

下一层即隐藏层也同样会产生一些激活值,那么我将其记作 a[1],所以具体地,这里的第一个单元或结点我们将其表示为 a1[1],第二个结点的值我们记为 a2[2]以此类推。所以这里的是一个四维的向量如果写成Python代码,那么它是一个规模为4x1的矩阵或一个大小为4的列向量,如下公式,它是四维的,因为在本例中,我们有四个结点或者单元,或者称为四个隐藏层单元;

在这里插入图片描述

  • 最后输出层将产生某个数值 a ,它只是一个单独的实数,所以 y
    的值将取为 a[2] 这与逻辑回归很相似,在逻辑回归中,我们有 y
    ​直接等于 a ,在逻辑回归中我们只有一个输出层,所以我们没有用带方括号的上标。
  • 但是在神经网络中,我们将使用这种带上标的形式来明确地指出这些值来自于哪一层,有趣的是在约定俗成的符号传统中,在这里你所看到的这个例子,只能叫做一个两层的神经网络。原因是当我们计算网络的层数时,输入层是不算入总层数内,所以隐藏层是第一层,输出层是第二层。第二个惯例是我们将输入层称为第零层,所以在技术上,这仍然是一个三层的神经网络,因为这里有输入层、隐藏层,还有输出层。但是在传统的符号使用中,如果你阅读研究论文或者在这门课中,你会看到人们将这个神经网络称为一个两层的神经网络,因为我们不将输入层看作一个标准的层。

最后,我们要看到的隐藏层以及最后的输出层是带有参数的,这里的隐藏层将拥有两个参数 W和 b ,我将给它们加上上标 [1] ( W [1], b [1])

表示这些参数是和第一层这个隐藏层有关系的。之后在这个例子中我们会看到 W 是一个4x3的矩阵,而 b 是一个4x1的向量,第一个数字4源自于我们有四个结点或隐藏层单元,然后数字3源自于这里有三个输入特征,我们之后会更加详细地讨论这些矩阵的维数,到那时你可能就更加清楚了。相似的输出层也有一些与之关联的参数W [2], b [2] 从维数上来看,它们的规模分别是1x4以及1x1。1x4是因为隐藏层有四个隐藏层单元而输出层只有一个单元,之后我们会对这些矩阵和向量的维度做出更加深入的解释,所以现在你已经知道一个两层的神经网络什么样的了,即它是一个只有一个隐藏层的神经网络。

在这里插入图片描述

三、神经网络的输出

神经网络计算,从逻辑回归开始,如下图所示。用圆圈表示神经网络的计算单元,逻辑回归的计算有两个步骤,首先你按步骤计算出 z ,然后在第二步中以sigmoid函数为激活函数计算 z (得出 a ),一个神经网络只是这样子做了好多次重复计算。

在这里插入图片描述

在这里插入图片描述
如果执行神经网络的程序,用for循环来做这些看起来真的很低效。所以接下来我们要做的就是把这四个等式向量化。向量化的过程是将神经网络中的一层神经元参数纵向堆积起来,例如隐藏层中的 w 纵向堆积起来变成一个 (4,3) 的矩阵,用符号 W[1]表示。另一个看待这个的方法是我们有四个逻辑回归单元,且每一个逻辑回归单元都有相对应的参数——向量 w,把这四个向量堆积在一起,你会得出这4×3的矩阵。 因此, 公式3.8:

在这里插入图片描述
在这里插入图片描述

四、多个例子的向量化

[n]表示第n层,(i)表示第i个样本,下标表示样本的第几个特征

a[i](m)→其中i是神经网络的第几层(层数),m是第几个样本。行列式,行数代表层数,列数代表样本序号。

隐藏单元就是指每一层神经网络中的那些圆圈圈。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
for循环是来遍历所有个训练样本。 定义矩阵 X 等于训练样本,将它们组合成矩阵的各列,形成一个 n 维或 n 乘以 m维矩阵。接下来计算见公式3.15:

以此类推,从小写的向量 x 到这个大写的矩阵 X ,只是通过组合 x 向量在矩阵的各列中。同理z[1](1), z[1](2) 等等都是 z [1](m) 的列向量,将所有 m 都组合在各列中,就的到矩阵 Z[1]

  • 同理a[1](1), a[1](2) ……a[1](m), 将其组合在矩阵各列中,如同从向量 x 到矩阵 X ,以及从向量 z 到矩阵 Z 一样,就能得到矩阵 A [1]

同样的,对于 Z[2]和A[2] ,也是这样得到。

这种符号其中一个作用就是,可以通过训练样本来进行索引。这就是水平索引对应于不同的训练样本的原因,这些训练样本是从左到右扫描训练集而得到的。

神经网络上通过在多样本情况下的向量化来使用这些等式。
在这里插入图片描述

横向是样本,竖向是隐藏层的节点

五、向量化实现的解释

在这里插入图片描述
吴恩达老师很细心的用不同的颜色表示不同的样本向量,及其对应的输出。所以从图中可以看出,当加入更多样本时,只需向矩阵 X中加入更多列。
在这里插入图片描述
所以从这里我们也可以了解到,之前我们对单个样本的计算要写成z[1](i)=W[1] x(i)+b[1] 这种形式,因为当有不同的训练样本时,将它们堆到矩阵 X 的各列中,那么它们的输出也就会相应的堆叠到矩阵 Z[1] 的各列中。现在我们就可以直接计算矩阵 Z[1] 加上 b[1] ,因为列向量 b[1] 和矩阵 Z[1] 的列向量有着相同的尺寸,而Python的广播机制对于这种矩阵与向量直接相加的处理方式是,将向量与矩阵的每一列相加。 所以这一节只是说明了为什么公式 Z [1]= W [1]X + b[1]是前向传播的第一步计算的正确向量化实现,但事实证明,类似的分析可以发现,前向传播的其它步也可以使用非常相似的逻辑,即如果将输入按列向量横向堆叠进矩阵,那么通过公式计算之后,也能得到成列堆叠的输出。

六、深度学习激活函数

在这里插入图片描述
结果表明,如果在隐藏层上使用函数 公式3.20: g (z[1]) = tanh ( z[1]) 效果总是优于sigmoid函数。因为函数值域在-1和+1的激活函数,其均值是更接近零均值的。在训练一个算法模型时,如果使用tanh函数代替sigmoid函数中心化数据,使得数据的平均值更接近0而不是0.5.

两者的优点是:

第一,在 z 的区间变动很大的情况下,激活函数的导数或者激活函数的斜率都会远大于0,在程序实现就是一个if-else语句,而sigmoid函数需要进行浮点四则运算,在实践中,使用ReLu激活函数神经网络通常会比使用sigmoid或者tanh激活函数学习的更快。

第二,sigmoidtanh函数的导数在正负饱和区的梯度都会接近于0,这会造成梯度弥散,而Relu和Leaky ReLu函数大于0部分都为常数,不会产生梯度弥散现象。(同时应该注意到的是,Relu进入负半区的时候,梯度为0,神经元此时不会训练,产生所谓的稀疏性,而Leaky ReLu不会有这问题)

z 在ReLu的梯度一半都是0,但是,有足够的隐藏层使得z值大于0,所以对大多数的训练数据来说学习过程仍然可以很快。

快速概括一下不同激活函数的过程和结论。

  • sigmoid激活函数:除了输出层是一个二分类问题基本不会用它。

  • tanh激活函数:tanh是非常优秀的,几乎适合所有场合。

  • ReLu激活函数:最常用的默认函数,,如果不确定用哪个激活函数,就使用ReLu或者Leaky ReLu。
    在这里插入图片描述

为什么需要非线性激活函数

  • 如果不设置激活函数,那么不论设置多少个隐藏层其实和设置一个隐藏层是一样的,也就是说没有激活函数,本质上都是单层的神经网络,只有有了激活函数才相当于真正扩展到了多层神经网络

七、激活函数导数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

八、神经网络的梯度下降法

n是对于每层的节点数,比如w[1]行位置上的n[1]就是第一层那n[1]个节点,而列位置上的n[0]就是输入特征向量x有n[0]个特征,也就是输入层第0层有n[0]个节点]

n0是输入层元素个数,n1是第一层隐藏单元个数

在这里插入图片描述
在这里插入图片描述
上述是反向传播的步骤,注:这些都是针对所有样本进行过向量化, Y 是 1 ∗ m 的矩阵;这里np.sum是python的numpy命令,axis=1表示水平相加求和,keepdims是防止python输出那些古怪的秩数 ( n , ) 加上这个确保矩阵db[2]这个向量输出的维度为 ( n , 1 )这样标准的形式。

目前为止,我们计算的都和Logistic回归十分相似,但当你开始计算反向传播时,你需要计算,是隐藏层函数的导数,输出在使用sigmoid函数进行二元分类。这里是进行逐个元素乘积,因为 W[2]T dz[2]W 和 (Z[1] )这两个都为(n[1],m)矩阵;

还有一种防止python输出奇怪的秩数,需要显式地调用reshape把np.sum输出结果写成矩阵形式。

九、深度学习随机初始化

  • 当训练神经网络时,权重随机初始化是很重要的。对于逻辑回归,把权重初始化为0当然也是可以的。但是对于一个神经网络,如果你把权重或者参数都初始化为0,那么梯度下降将不会起作用。

在这里插入图片描述
在这里插入图片描述

十、上述学习总结

1、第一题

在这里插入图片描述

正解:BDEF
错因:
A:第2层的第12个神经元的激活值
C: 就是D描述
G: 就是B描述

2、第二题

在这里插入图片描述
正解:D

3、第三题

A = np.random.randn(4,3)
B = np.sum(A, axis = 1, keepdims = True)

B.shape是多少?

A.(4,) B.(1, 3) C.(, 3) D.(4, 1)

正解:D

首先,A = np.random.randn(4,3)创建了一个形状为(4, 3)的数组,即有4行3列的矩阵。

然后,B = np.sum(A, axis = 1, keepdims = True)对矩阵A进行操作,其中np.sum函数用于计算数组元素的和。参数axis = 1指定了沿着水平轴(即每一行内部)进行求和,而keepdims = True的作用是在求和后保持原有的维度不变,即不降维。

因此,经过这样的操作后,B的形状将变为(4, 1),也就是说,它仍然是一个4行的矩阵,但列数减少为1,因为原本每一行的3个元素被求和成了一个元素。

4、第四题

逻辑回归的权重w应该随机初始化,而不是全部初始化为全部零,否则,逻辑回归将无法学习有用的决策边界,因为它将无法“打破对称

这种说法并不准确。逻辑回归模型的权重w可以初始化为全零,这并不影响模型的学习能力和最终性能。

5、第五题

已经为所有隐藏的单位建立了一个使用tanh激活的网络。使用np.random.randn(…, …)*1000将权重初始化为相对较大的值。会发生什么?

A.没关系。只要随机初始化权重,梯度下降不受权重大小的影响。

B.这将导致tanh的输入也非常大,从而导致梯度也变大。因此,你必须将设置得非常小,以防止发散;这将减慢学习速度。

C.这将导致tanh的输入也非常大,导致单元被“高度激活”。与权重从小值开始相比,加快了学习速度。

D.这将导致tanh的输入也非常大,从而导致梯度接近于零。因此,优化算法将变得缓慢。

正解:D

在这里插入图片描述

6、第六题

考虑以下1个隐层的神经网络:
在这里插入图片描述

正解:BCEH

W[i]后面对应的是(i层的神经元数目,i-1层的神经元数目)⭐️⭐️⭐️⭐️⭐️

7、第7题

在这里插入图片描述

同一层的z的维度和A的相同,m是样本数目。
正解:C

十一、深层神经网络常识

在这里插入图片描述

以下面的图为例,深度学习常见记号

在这里插入图片描述

在这里插入图片描述

  • 权重矩阵的行数对应于当前层的神经元数量,列数对应于上一层的神经元数量。

核对矩阵维数

在这里插入图片描述

关于为什么要缓存z[l],因为dz[l] =da[l] dot(g[l] ′ (z [l]))
而dw[l]=a[l-1]dz[l],db[l]=dz[l],da[l-1]=w[l]Tdz[l]都间接(因为用到了dz[l])用到了z[l]

十二、深度学习前向和反向传播

在这里插入图片描述
搭建深层神经网络块

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

da又叫做a‘,导数的意思,这里是偏导数(梯度)

参数 vs 超参数

比如算法中的learning rate α \alphaα (学习率)、iterations(梯度下降法循环的数量)、 L LL (隐藏层数目)、 n [ l ] n^{[l]}n
[l]
(隐藏层单元数目)、choice of activation function(激活函数的选择)都需要你来设置,这些数字实际上控制了最后的参数 W WW 和 b bb 的值,所以它们被称作超参数。

十三、编程大作业实现

序幕:我们要建立一个神经网络,它有一个隐藏层。这个模型和上一个逻辑回归实现的模型有很大的区别。

  • 构建具有单隐藏层的2类分类神经网络。
  • 使用具有非线性激活功能激活函数tanh
  • 计算交叉熵损失(损失函数)。
  • 实现向前和向后传播。

1、环境准备与数据集

软件包环境:

numpy:是用Python进行科学计算的基本软件包。
sklearn:为数据挖掘和数据分析提供的简单高效的工具。
matplotlib :是一个用于在Python中绘制图表的库。

import numpy as np
import matplotlib.pyplot as plt
from testCases import *
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset, load_extra_datasets

np.random.seed(1) #设置一个固定的随机种子,以保证接下来的步骤中我们的结果是一致的。

在这里插入图片描述
load_planar_dataset() 是一个用于加载平面数据集的函数。

  • 这个函数通常在机器学习和深度学习的教程或示例代码中出现,用于创建一个简单的二分类问题数据集。它返回两个矩阵,一个是特征矩阵X,另一个是对应的标签矩阵Y。
  • 在深度学习的背景下,load_planar_dataset() 可能会被用来演示如何使用神经网络来解决分类问题,特别是当数据不是线性可分的时候。例如,通过使用这个函数,可以生成一个类似于“鲜花形状”的数据集,其中包含两类不同的点,需要通过建立适当的模型来进行分类。

数据看起来像一朵红色(y = 0)和一些蓝色(y = 1)的数据点的花朵的图案。 我们的目标是建立一个模型来适应这些数据。现在,我们已经有了以下的东西:

    • X:一个numpy的矩阵,包含了这些数据点的数值
    • Y:一个numpy的向量,对应着的是X的标签【0 | 1】(红色:0 , 蓝色 :1

2、Logistic回归的分类效果

对照组

sklearn.linear_model.LogisticRegressionCV() 是一个用于逻辑回归分类的类,它结合了交叉验证和正则化。

该类使用L2正则化(岭回归)或L1正则化(套索回归),并使用交叉验证来选择最佳的正则化参数。它通过在训练集上进行多次拟合,每次使用不同的正则化参数,然后选择具有最高交叉验证得分的模型作为最终模型。

from sklearn.linear_model import LogisticRegressionCV

# 创建 LogisticRegressionCV 对象
lrcv = LogisticRegressionCV(Cs=[1, 10, 100], cv=5, penalty='l2', solver='lbfgs', max_iter=100)

# 拟合数据
lrcv.fit(X_train, y_train)

# 预测新数据
y_pred = lrcv.predict(X_test)

在这里插入图片描述

这段代码是用于绘制逻辑回归模型的决策边界,并计算模型的准确性。

  • 首先,plot_decision_boundary(lambda x: clf.predict(x), X, Y) 这行代码调用了一个名为 plot_decision_boundary 的函数,该函数接受一个预测函数、特征矩阵 X 和标签向量 Y 作为参数。这里的预测函数是一个匿名函数 lambda x: clf.predict(x),它使用逻辑回归分类器 clf 对输入数据进行预测。(进行画红蓝分解图像)

  • 然后,LR_predictions = clf.predict(X.T) 这行代码使用逻辑回归分类器 clf 对特征矩阵 X 的转置进行预测,得到预测结果 LR_predictions

  • 最后,print("逻辑回归的准确性: %d " % float((np.dot(Y, LR_predictions) + np.dot(1 - Y, 1 - LR_predictions)) / float(Y.size) * 100) + "% " + "(正确标记的数据点所占的百分比)") 这行代码计算了逻辑回归模型的准确性。准确性是通过计算正确标记的数据点所占的百分比来得到的。这里使用了 np.dot() 函数来计算两个向量的点积,然后将结果除以标签向量 Y 的大小(即样本数量),再乘以 100 得到百分比。最后,将准确性以字符串的形式打印出来。

准确性只有47%的原因是数据集不是线性可分的,所以逻辑回归表现不佳(对照组),现在正式开始构建神经网络。

2、定义神经网络结构

在这里插入图片描述

理论公式可以看我之前写的博客

https://blog.csdn.net/QuantumYou/article/details/137249807?spm=1001.2014.3001.5502

在这里插入图片描述

def layer_sizes(X , Y):
    """
    参数:
     X - 输入数据集,维度为(输入的数量,训练/测试的数量)
     Y - 标签,维度为(输出的数量,训练/测试数量)
    
    返回:
     n_x - 输入层的数量
     n_h - 隐藏层的数量
     n_y - 输出层的数量
    """
    n_x = X.shape[0] #输入层
    n_h = 4 #,隐藏层,硬编码为4
    n_y = Y.shape[0] #输出层
    
    return (n_x,n_h,n_y)


3、初始化模型的参数

实现函数initialize_parameters()。确保我们的参数大小合适,如果需要的话,请参考上面的神经网络图。

我们将会用随机值初始化权重矩阵。

  • np.random.randn(a,b)* 0.01来随机初始化一个维度为(a,b)的矩阵。
    将偏向量初始化为零。

  • np.zeros((a,b))用零初始化矩阵(a,b)。

def initialize_parameters( n_x , n_h ,n_y):
    """
    参数:
        n_x - 输入层节点的数量
        n_h - 隐藏层节点的数量
        n_y - 输出层节点的数量
    
    返回:
        parameters - 包含参数的字典:
            W1 - 权重矩阵,维度为(n_h,n_x)
            b1 - 偏向量,维度为(n_h,1)
            W2 - 权重矩阵,维度为(n_y,n_h)
            b2 - 偏向量,维度为(n_y,1)

    """
    np.random.seed(2) #指定一个随机种子,以便你的输出与我们的一样。
    W1 = np.random.randn(n_h,n_x) * 0.01
    b1 = np.zeros(shape=(n_h, 1))
    W2 = np.random.randn(n_y,n_h) * 0.01
    b2 = np.zeros(shape=(n_y, 1))
    
    #使用断言确保我的数据格式是正确的
    assert(W1.shape == ( n_h , n_x ))
    assert(b1.shape == ( n_h , 1 ))
    assert(W2.shape == ( n_y , n_h ))
    assert(b2.shape == ( n_y , 1 ))
    
    parameters = {"W1" : W1,
	              "b1" : b1,
	              "W2" : W2,
	              "b2" : b2 }
    
    return parameters


4、sigmoid与tanh前向传播

def forward_propagation( X , parameters ):
    """
    参数:
         X - 维度为(n_x,m)的输入数据。
         parameters - 初始化函数(initialize_parameters)的输出
    
    返回:
         A2 - 使用sigmoid()函数计算的第二次激活后的数值
         cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型变量
     """
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    #前向传播计算A2
    Z1 = np.dot(W1 , X) + b1
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2 , A1) + b2
    A2 = sigmoid(Z2)
    #使用断言确保我的数据格式是正确的
    assert(A2.shape == (1,X.shape[1]))
    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}
    
    return (A2, cache)


5、计算成本函数J

def compute_cost(A2,Y,parameters):
    """
    计算方程(6)中给出的交叉熵成本,
    
    参数:
         A2 - 使用sigmoid()函数计算的第二次激活后的数值
         Y - "True"标签向量,维度为(1,数量)
         parameters - 一个包含W1,B1,W2和B2的字典类型的变量
    
    返回:
         成本 - 交叉熵成本给出方程(13)
    """
    
    m = Y.shape[1]
    W1 = parameters["W1"]
    W2 = parameters["W2"]
    
    #计算成本
    logprobs = logprobs = np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2))
    cost = - np.sum(logprobs) / m
    cost = float(np.squeeze(cost))
    
    assert(isinstance(cost,float))
    
    return cost


6、反向传播(难点)

在这里插入图片描述

def backward_propagation(parameters,cache,X,Y):
    """
    使用上述说明搭建反向传播函数。
    
    参数:
     parameters - 包含我们的参数的一个字典类型的变量。
     cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型的变量。
     X - 输入数据,维度为(2,数量)
     Y - “True”标签,维度为(1,数量)
    
    返回:
     grads - 包含W和b的导数一个字典类型的变量。
    """
    m = X.shape[1]
    
    W1 = parameters["W1"]
    W2 = parameters["W2"]
    
    A1 = cache["A1"]
    A2 = cache["A2"]
    
    dZ2= A2 - Y
    dW2 = (1 / m) * np.dot(dZ2, A1.T)
    db2 = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)
    dZ1 = np.multiply(np.dot(W2.T, dZ2), 1 - np.power(A1, 2))
    dW1 = (1 / m) * np.dot(dZ1, X.T)
    db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
    grads = {"dW1": dW1,
             "db1": db1,
             "dW2": dW2,
             "db2": db2 }
    
    return grads


7、更新参数和模型整合

良好学习速率(收敛)梯度下降算法

在这里插入图片描述

不良学习速率(发散)梯度下降算法

在这里插入图片描述
图片来源Adam Harley⭐️

def update_parameters(parameters,grads,learning_rate=1.2):
    """
    使用上面给出的梯度下降更新规则更新参数
    
    参数:
     parameters - 包含参数的字典类型的变量。
     grads - 包含导数值的字典类型的变量。
     learning_rate - 学习速率
    
    返回:
     parameters - 包含更新参数的字典类型的变量。
    """
    W1,W2 = parameters["W1"],parameters["W2"]
    b1,b2 = parameters["b1"],parameters["b2"]
    
    dW1,dW2 = grads["dW1"],grads["dW2"]
    db1,db2 = grads["db1"],grads["db2"]
    
    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2
    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    
    return parameters


def nn_model(X,Y,n_h,num_iterations,print_cost=False):
    """
    参数:
        X - 数据集,维度为(2,示例数)
        Y - 标签,维度为(1,示例数)
        n_h - 隐藏层的数量
        num_iterations - 梯度下降循环中的迭代次数
        print_cost - 如果为True,则每1000次迭代打印一次成本数值
    
    返回:
        parameters - 模型学习的参数,它们可以用来进行预测。
     """
     
    np.random.seed(3) #指定随机种子
    n_x = layer_sizes(X, Y)[0]
    n_y = layer_sizes(X, Y)[2]
    
    parameters = initialize_parameters(n_x,n_h,n_y)
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    
    for i in range(num_iterations):
        A2 , cache = forward_propagation(X,parameters)
        cost = compute_cost(A2,Y,parameters)
        grads = backward_propagation(parameters,cache,X,Y)
        parameters = update_parameters(parameters,grads,learning_rate = 0.5)
        
        if print_cost:
            if i%1000 == 0:
                print("第 ",i," 次循环,成本为:"+str(cost))
    return parameters


8、预测与运行

def predict(parameters,X):
    """
    使用学习的参数,为X中的每个示例预测一个类
    
    参数:
		parameters - 包含参数的字典类型的变量。
	    X - 输入数据(n_x,m)
    
    返回
		predictions - 我们模型预测的向量(红色:0 /蓝色:1)
     
     """
    A2 , cache = forward_propagation(X,parameters)
    predictions = np.round(A2)
    
    return predictions


# 运行
parameters = nn_model(X, Y, n_h = 4, num_iterations=10000, print_cost=True)

#绘制边界
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
plt.title("Decision Boundary for hidden layer size " + str(4))

predictions = predict(parameters, X)
print ('准确率: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')



  • predict函数,它接收两个参数:parametersXparameters是一个包含模型参数的字典,X是输入数据。

函数的主要目的是使用学习的参数为输入数据X中的每个示例预测一个类。首先,它调用forward_propagation函数,将Xparameters作为输入参数,返回A2cache。然后,通过对A2进行四舍五入操作(np.round(A2)),得到预测结果predictions。最后,函数返回预测结果predictions

在这里插入图片描述

注解:训练一个神经网络模型并绘制决策边界的。首先,通过调用nn_model函数来训练模型,传入输入数据X、标签Y、隐藏层大小n_h、迭代次数num_iterations和是否打印损失值print_cost等参数。然后,使用plot_decision_boundary函数绘制决策边界,传入预测函数(通过lambda x: predict(parameters, x.T)定义)、输入数据X和标签Y。接着,设置图表标题为"Decision Boundary for hidden layer size "加上隐藏层大小。最后,使用predict函数对输入数据X进行预测,并计算准确率,将结果打印出来。

  • 边界在机器学习中通常用于区分不同类别的数据。在这个例子中,决策边界是一条线或曲线,它将输入空间划分为两个区域:一个区域包含属于类别1的样本,另一个区域包含属于类别2的样本。通过绘制决策边界,我们可以直观地看到模型如何根据输入特征将数据点分类到不同的类别中。这对于理解模型的性能和进行模型评估非常有用。
    在这里插入图片描述

用于绘制不同隐藏层节点数量下的决策边界,并输出对应的准确率。首先设置画布大小为16x32,然后定义一个包含不同隐藏层节点数量的列表。接着使用循环遍历这个列表,每次循环中绘制一个子图,标题为当前隐藏层节点数量,调用nn_model函数训练模型,传入输入数据X、标签Y、当前隐藏层节点数量和迭代次数5000。然后调用plot_decision_boundary函数绘制决策边界,传入预测函数、输入数据X和标签Y。接着调用predict函数对输入数据X进行预测,计算准确率并输出。

  • 隐藏层节点数量是指神经网络中隐藏层的神经元数量。在这段代码中,隐藏层节点数量分别为1、2、3、4、5、20和50。

⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

完结!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1592185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[lesson22]对象的销毁

对象的销毁 对象的销毁 生活中的对象都是被初始化后才上市的 生活中的对象被销毁前会做一些清理工作 一般而言,需要销毁的对象都应该做清理 解决方案 为每个类都提供一个public的free函数对象不在需要时立即调用free函数进行清理 存在的问题 free只是一个普通…

创建一个qt登录界面,密码账号正确转到窗口2,否则弹出对话框提示账号密码错误,窗口2有四个按键,三个按键可以朗读按键文本,第四个退出。

作业要求: 主函数: int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();Form1 f;//连接窗口1的信号函数和窗口2打开的lambda函数Widget::connect(&w,&Widget::login,[&](){f.show();});return a.exec(); }窗…

【心路历程】初次参加蓝桥杯实况

送给大家一句话: 寂静的光辉平铺的一刻,地上的每一个坎坷都被映照得灿烂。 – 史铁生 《我与地坛》 初次参加蓝桥杯有感 一点小小的震撼难评的做题过程A题 艺术与篮球问题描述解题 B 题 五子棋问题描述解题 C题 训练士兵问题描述解题 D题 团建解题 E题 …

电脑显卡怎么看,win10电脑显卡怎么看参数

win10电脑显卡怎么看参数呢?有些小伙伴在买电脑的时候,由于看不懂一些硬件配置,因此只能听别人的推荐来做选择,这样很被动,可能会买到不适合自己的电脑。例如说,你有游戏的需求,那么显卡配置要好&#xff…

Unity给地图物体添加对撞机

在项目/Assets下创建Prefabs文件夹 选择素材拖入层级下,注意此时地图素材有可能看不到,此时选择Tilemap在检查器中修改图层顺序调至最低。 添加对撞机 选择素材,在检查器中点击添加组件Box Collider 2D,将素材拖入Prefabs文件下…

【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)

🔥个人主页:Forcible Bug Maker 🔥专栏:C 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性及用法 析构函数 概念 析构函数的特性及用法 结语 前言 本篇主要内容:类的6个默认成员函数中的构造函…

超越传统Lambda函数:深入解析Out-of-line Lambdas的奇妙之处

超越传统函数:深入解析线外 Lambda函数 的奇妙之处 一、背景二、lambda 的捕获三、可能出现的警告四、lambda的广义捕获五、为每种情况进行重载六、总结 一、背景 Out-of-line Lambdas翻译过来就是“线外Lambda函数”或“离线Lambda函数”。Lambda 是使代码更具表现…

vue canvas绘制信令图,动态显示标题、宽度、高度

需求: 1、 根据后端返回的数据,动态绘制出信令图 2、根据 dataStatus 返回值: 0 和 1, 判断 文字内容的颜色,0:#000,1:red 3.、根据 lineType 返回值: 0 和 1, 判断 箭…

人员抽烟AI检测算法原理介绍及实际场景应用

抽烟检测AI算法是一种基于计算机视觉和深度学习技术的先进工具,旨在准确识别并监测个体是否抽烟。该算法通过训练大量图像数据,使模型能够识别出抽烟行为的关键特征,如烟雾、手部动作和口部形态等。 在原理上,抽烟检测AI算法主要…

AI预测体彩排3第2弹【2024年4月13日预测--第1套算法开始计算第2次测试】

各位小伙伴,今天实在抱歉,周末回了趟老家,回来比较晚了,数据今天上午跑完后就回老家了,晚上8点多才回来,赶紧把预测结果发出来吧,虽然有点晚了,但是咱们前面说过了,目前的…

ZL-099动物行为学视频分析系统

简单介绍: 动物行为学视频分析系统是一套通过视频摄像机和计算机,采用图像处理技术,自动跟踪和记录动物活动的通用型运动轨迹记录分析系统,可以应用在神经药理,学习记忆药理,药理和新药神经系统一般药理毒理…

element UI 设置type=“textarea“ 禁止输入框缩放

背景 在 Element UI 中,当您使用 el-input 组件并设置 type"textarea" 时,默认情况下,用户可以通过拖动输入框的右下角来调整其大小。如果您想禁止这种缩放行为,需要使用 CSS 来覆盖默认的浏览器行为。 注意上图&#x…

CH254X 8051芯片手册介绍

1 8051CPU 8051是一种8位元的单芯片微控制器,属于MCS-51单芯片的一种,由英特尔(Intel)公司于1981年制造。Intel公司将MCS51的核心技术授权给了很多其它公司,所以有很多公司在做以8051为核心的单片机,如Atmel、飞利浦、深联华等公…

【Tars-go】腾讯微服务框架学习使用03-- TarsUp协议

3 TarsUP协议 统一通信协议 TarsTup | TarsDocs (tarscloud.github.io) TarsDocs/base at master TarsCloud/TarsDocs (github.com) : 有关于tars的所有介绍 每一个rpc调用双方都约定一套数据序列化协议,gprc用的是protobuff,tarsgo是统一…

《黑马点评》Redis高并发项目实战笔记(上)P1~P45

P1 Redis企业实战课程介绍 P2 短信登录 导入黑马点评项目 首先在数据库连接下新建一个数据库hmdp,然后右键hmdp下的表,选择运行SQL文件,然后指定运行文件hmdp.sql即可(建议MySQL的版本在5.7及以上): 下面这…

Vivado抓信号——提高效率的工具化生成XDC(Python脚本)

操作目录 一、要抓取信号的txt列表二、操作流程 通常情况下,Vivado上板抓取信号的方法主要有两类: (1)通过在信号前添加(mark_debug“true”),综合完之后点击Set Up Debug,将需要抓取的信号添加进去&#x…

电脑端微信截图文字识别功能效率更高了

近期发现微信中的截图文字识别比QQ中的截图文字识别效率高更高,效果更好。 使用方法: 安装电脑端微信客户端:https://weixin.qq.com/(如果没有下载,可以安装一下) 默认截图组合快捷键是:ALTA (使用下来感觉不是很顺手…

网桥的原理

网桥的原理 1.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。 交换机就是这样一个设备,它有若干个网口…

基于SpringBoot+Vue的毕业设计管理系统(源码+文档+部署+讲解)

一.系统概述 二十一世纪我们的社会进入了信息时代,信息管理系统的建立,大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多,而在线管理系统刚好能满足这些需求,在线管理系统突破了传统管理方式的局限性。于是本文针…