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

文章目录

  • 一、神经网络概述
  • 二、神经网络的表示
  • 三、神经网络的输出
  • 四、多个例子的向量化
  • 五、向量化实现的解释
  • 六、深度学习激活函数
  • 七、激活函数导数
  • 八、神经网络的梯度下降法
  • 九、深度学习随机初始化
  • 十、上述学习总结
    • 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_datasetsnp.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 #,隐藏层,硬编码为4n_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.01b1 = np.zeros(shape=(n_h, 1))W2 = np.random.randn(n_y,n_h) * 0.01b2 = 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"]#前向传播计算A2Z1 = np.dot(W1 , X) + b1A1 = np.tanh(Z1)Z2 = np.dot(W2 , A1) + b2A2 = 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) / mcost = 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 - YdW2 = (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 * dW1b1 = b1 - learning_rate * db1W2 = W2 - learning_rate * dW2b2 = b2 - learning_rate * db2parameters = {"W1": W1,"b1": b1,"W2": W2,"b2": b2}return parametersdef 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.rhkb.cn/news/307785.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

langchain LCEL,prompt模块,outputparse输出模块

目录 基本代码 prompt模块 prompt模版控制长度 outputparse格式化输出 并行使用调用链 LangChain表达式语言,或者LCEL,是一种声明式的方式,可以轻松地将链条组合在一起 langchian 可以使用 通义千问,我们用通义千问&#x…

STM32H7的MPU学习和应用示例

STM32H7的MPU学习记录 什么是MPU?MPU的三种内存类型内存映射MPU保护区域以及优先级 MPU的寄存器XN位AP位TEX、C、B、S位SRD 位SIZE 位CTRL 寄存器的各个位 示例总结 什么是MPU? MPU(Memory Protection Unit,内存保护单元&#xf…

Pytorch Windows EOFError: Ran out of input when num_workers>0

关于深度学习的一些学习框架,我使用过pytorch,caffe,caffe2,openchatkit,oneflow等,最近我将长达几十万字的报错手册重新进行了整理,制作出一个新的专栏,主要记录这几种常见的开发框架在安装和使用过程中常见的报错,以及我是如何解决掉的,以此来帮助更多的深度学习开…

GB/T 28181标准中的错误码,国标28181中可能出现的SIP协议相关的错误码及其含义

目录 一、GB/T 28181标准介绍 (一)概述 (二)关键内容和特点 1. 系统架构: 2. 设备接入: 3. 网络通信: 4. 业务功能: 5. 安全保护: 6. 平台管理: &a…

二维数组---刷题

一维数组不想更了,弄点二维数组! 1.新矩阵 思路 题目简单,6*636,可以得知有36个元素。数组就定义成a[7][7],难点在与如何找出对角线上的元素。可以画图分析: 通过观察不难发现,元素1&#xff…

spring boot admin搭建,监控springboot程序运行状况

新建一个spring boot web项目&#xff0c;添加以下依赖 <dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.0</version></dependency> <dependency&…

uni-app实现分页--(2)分页加载,首页下拉触底加载更多

业务逻辑如下&#xff1a; api函数升级 定义分页参数类型 组件调用api传参

[论文翻译]GLU Variants Improve Transformer

引言 今天带来一篇短小精悍的论文GLU Variants Improve Transformer笔记&#xff0c;作者提出了GLU1的一种变体。 GLU(Gated Linear Units,门控线性单元)由两个线性投影的逐元素乘积组成&#xff0c;其中一个首先经过sigmoid函数。GLU的变体是可能生效的&#xff0c;可以使用…

c语言多功能计算软件170

定制魏&#xff1a;QTWZPW&#xff0c;获取更多源码等 目录 题目 要求 主要代码片段 题目 设计一个计算器软件&#xff0c;具备如下功能提示界面。 要求 设计出界面&#xff0c;注意界面名称最后为自己的姓名&#xff1b;&#xff08;20分&#xff09;能够实现加、减、乘、…

Java 面试宝典:Redis 的线程模型是怎么样的?

大家好&#xff0c;我是大明哥&#xff0c;一个专注「死磕 Java」系列创作的硬核程序员。 本文已收录到我的技术网站&#xff1a;https://www.skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经 Redis 的线程模型其实是分两块的&#xff1a; Redis 6.0 …

(学习日记)2024.04.15:UCOSIII第四十三节:任务消息队列

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

文件上传【2】--靶场通关

1.前端禁用js绕过 上传文件&#xff0c;进行抓包&#xff0c;没有抓到&#xff0c;说明这里的验证是前端js验证跳出的弹窗 禁用js后&#xff0c;php文件上传成功。 2.文件上传.htaccess 上传png木马后连接不上 代码中存在.htaccess&#xff0c;判断此时应该就是需要用到.htac…

1111111111

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

21 标准错误

标准输出重定向关闭无数据 下面的代码&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main() {close(1);i…

超级详细的JDBC和数据库连接池讲解

文章目录 JDBC简介概念本质好处 JDBC快速入门JDBC中API详解DriverManager驱动管理类作用注册驱动获取连接 Connection数据库连接对象作用获取执行SQL的对象事务管理 Statement作用执行SQL语句 ResultSet原理使用步骤 PreparedStatementSQL注入获取对象操作步骤 原理好处 JDBC工…

力扣刷题 二叉树层序遍历相关题目II

NO.116 填充每个节点的下一个右侧节点指针 给定一个 完美二叉树 &#xff0c;其所有叶子节点都在同一层&#xff0c;每个父节点都有两个子节点。二叉树定义如下&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;…

redis的主从复制(docker方式快速入门和实战)

目录 一、主从复制简介 二、配置主从服务器 2.1使用配置文件的形式来主从复制 2.2使用纯代码的方式来进行主从复制&#xff1b; 2.3脱离主服务器 三、一些注意事项 一、主从复制简介 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器…

【论文阅读】MCTformer: 弱监督语义分割的多类令牌转换器

【论文阅读】MCTformer: 弱监督语义分割的多类令牌转换器 文章目录 【论文阅读】MCTformer: 弱监督语义分割的多类令牌转换器一、介绍二、联系工作三、方法四、实验结果 Multi-class Token Transformer for Weakly Supervised Semantic Segmentation 本文提出了一种新的基于变换…

尝试在手机上运行google 最新开源的gpt模型 gemma

Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型&#xff0c;使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重&#xff1a;2B和7B。每种尺寸都带有经过预训练&a…

【动手学深度学习】15_汉诺塔问题

注&#xff1a; 本系列仅为个人学习笔记&#xff0c;学习内容为《算法小讲堂》&#xff08;视频传送门&#xff09;&#xff0c;通俗易懂适合编程入门小白&#xff0c;需要具备python语言基础&#xff0c;本人小白&#xff0c;如内容有误感谢您的批评指正 汉诺塔&#xff08;To…