神经网络编程基础

1、二分类(Binary Classification)

  • 逻辑回归(logistic regression)是一个用于二分类(binary classification)的算法。所谓二分类是由输入到判断输出结果是或者不是。比如输入一个包含动物的图片,判断这张图片中的动物是否包含猫,有猫输出标签为 1,不是输出标签为 0,y表示输出的结果标签

    神经网络编程基础_第1张图片

  • 为了在计算机中保存一张图片,需要保存三个矩阵, 它们分别对应图片中的红、绿、蓝三种颜色通道,每一个颜色通道需要一个矩阵来保存对应图片中红、绿、蓝三种像素的强度值。下面是三个规模为 5 * 4 的矩阵分别表示对应图片中红、绿、蓝三种像素的强度值(注意在实际中图片的每一个颜色通道的矩阵大小应该为 64 * 64的规模)

    神经网络编程基础_第2张图片

  • 使用一个 5 * 4 * 3 的特征向量来保存上面三个颜色通道的像素强度值,大小为 60,使用 = 60 表示,来表示输入特征向量的维度
  • (符号定义):表示一个维数据,为输入数据,维度为(, 1),说白了就是一个列向量
  • :表示输出结果,取值为(0,1)
  • ( () , () ):表示第组数据,可能是训练数据,也可能是测试数据,此处默认为训练数据,也即一组输入对应一组输出
  • = [ (1) , (2) , . . . , () ]:表示所有的训练数据集的输入值,放在一个 × 的矩阵中,
  • 其中表示样本数目,也即所有列向量构成的一个大矩阵,每一列就是一张图片的特征向量(也即红、蓝、绿三种像素的强度值),总共有 m 个这样的图片
  • = [ (1) , (2) , . . . , () ]:对应表示所有训练数据集的输出值,维度为1 × m
  • 用一对(, )来表示一个单独的样本,代表维的特征向量, 表示标签(输出结果)只能为 0 或 1。 而训练集将由个训练样本组成,其中( (1) , (1) )表示第一个样本的输入和输 出,( (2) , (2) )表示第二个样本的输入和输出,直到最后一个样本( () , () ),然后所有的 这些一起表示整个训练集。有时候为了强调这是训练样本的个数,会写作,当涉及到 测试集的时候,我们会使用来表示测试集的样本数,所以这是测试集的样本数:

    神经网络编程基础_第3张图片

  • 最后为了能把训练集表示得更紧凑一点,我们会定义一个矩阵用大写的表示,它由输
    入向量 (1)、 (2)等组成,如下图放在矩阵的列中,所以现在我们把 (1)作为第一列放在矩阵
    中, (2)作为第二列, ()放到第列,然后我们就得到了训练集矩阵。所以这个矩阵有
    列,是训练集的样本数量,然后这个矩阵的高度记为,注意有时候可能因为其他某些原
    因,矩阵会由训练样本按照行堆叠起来而不是列,如下图所示: (1)的转置直到 ()的转
    置,但是在实现神经网络的时候,使用左边的这种形式,会让整个实现的过程变得更加简单:

    神经网络编程基础_第4张图片

  • 总之,是一个规模为乘以的矩阵,当用 Python 实现的时候,会使用 X.shape,这是一条 Python 命令,用于显示矩阵的规模,即 X.shape 等于(, ),是一个规模为乘以的矩阵,这就是如何将训练样本(输入向量的集合)表示为一个矩阵
  • 同样,为了能更加容易地实现一个神经网络,将标签放在列
    中将会使得后续计算非常方便,所以我们定义大写的等于 (1) , () , . . . , (),所以在这里 是一个规模为 1 乘以的矩阵,同样地使用 Python 将表示为 Y.shape 等于(1, ),表示这 是一个规模为 1 乘以的矩阵。

2、逻辑回归(Logistic Regression)

  • 假设有一个预测函数 ^ = + b,^ 表示 等于 1 的一种可能性或者是机会,前提条件是给定了输入特征X,w上是特征权重,维度与特征向量相同,是一个实数(表示偏差),得到是一个关于输入的线性函数

    神经网络编程基础_第5张图片

  • 但是对于二元分类问题来讲这不是一个非常好的算法,因为你想让^表示实际值等于 1的机率的话,^ 应该在 0 到 1 之间。这是一个需要解决的问题,因为 + 可能比 1 要大得多,或者甚至为一个负值。对于你想要的在 0 和 1 之间的概率来说它是没有意义的,因此在逻辑回归中,我们的输出应该是^等于由上面得到的线性函数式子作为自变量的 sigmoid函数,将线性函数转换为非线性函数。
  • 下图是 sigmoid 函数的图像,如果我把水平轴作为 轴,那么关于 sigmoid 函数是这
    样的,它是平滑地从 0 走向 1 ,让我在这里标记纵轴,这是 0 ,曲线与纵轴相交的截距是 0.5 , 这就是关于 sigmoid 函数的图像。我们通常都使用 来表示 + 的值

    神经网络编程基础_第6张图片

  • 因此当实现逻辑回归时,就是去让机器学习参数 以及 这样才使得 ^ 成为对 = 1 这一情况的概率的一个很好的估计(y=1,则z趋向无穷) 比如在某些例子里,定义一个额外的特征称之为 0 ,并且使它等于 1 ,那么现在 就是一 1 维的变量,然后你定义 ^ = ( ) sigmoid 函数。在这个备选的符号惯例里,你 有一个参数向量 0 , 1 , 2 , . . . , ,这样 0 就充当了 ,这是一个实数,而剩下的 1 直到 充当了 ,结果就是当你实现你的神经网络时,有一个比较简单的方法是保持 分开

神经网络编程基础_第7张图片

  • (神经元的计算过程)线性计算:将输入信号与对应的权重进行加权求和,然后加上一个偏置项,得到一个加权和。数学公式为:z = Wx + b,其中,W是权重矩阵,x是输入信号向量,b是偏置向量。
  • 非线性变换:将线性计算得到的结果通过激活函数进行非线性变换,得到最终的输出值。激活函数可以是sigmoid、ReLU、tanh等函数,它们可以将线性计算得到的结果映射到一个非线性的空间中,使得神经元节点可以捕捉到更复杂的数据模式和特征。 因此,整个神经元节点的计算过程是先进行线性计算,再经过激活函数进行非线性变换,最终得到输出值。
  • 因此,整个神经元节点的计算过程是先进行线性计算,再经过激活函数进行非线性变换,最终得到输出值。

3、逻辑回归的代价函数(Logistic Regression Cost Function

  • (为什么需要代价函数)为了训练逻辑回归模型的参数参数和参数我们,需要一个代价函数(成本函数),通过训练代价函数来得到参数和参数。逻辑回归的输出函数:

神经网络编程基础_第8张图片

  •  为了让模型通过学习调整参数,需要给予一个样本的训练集,这会在在训练集上找到参数和参数,,来得到输出。 对训练集的预测值,将它写成^,但是更希望它会接近于训练集中的值,为了对上 面的公式更详细的介绍,需要说明上面的定义是对一个训练样本来说的,这种形式也使 用于每个训练样本,使用这些带有圆括号的上标来区分索引和样本,训练样本所对应 的预测值是 () ,是用训练样本的 () + 然后通过 sigmoid 函数来得到,也可以把定义为 () = () + ,我们将使用这个符号()注解,上标()来指明数据表示或者或者或者其 他数据的第个训练样本,这就是上标()的含义。
  • 损失函数又叫做误差函数,用来衡量算法的运行情况Loss function:(^ , )。
    通过这个 称为的损失函数,来衡量预测输出值和实际值有多接近。一般我们用预
    测值和实际值的平方差或者它们平方差的一半,但是通常在逻辑回归中我们不这么做,因为
    当我们在学习逻辑回归参数的时候,会发现我们的优化目标不是凸优化,只能找到多个局部
    最优值,梯度下降法很可能找不到全局最优值,虽然平方差是一个不错的损失函数,但是我
    们在逻辑回归模型中会定义另外一个损失函数。
  • 逻辑回归中用到的损失函数是:(^ , ) = −log(^) − (1 − )log(1 − ^)。选择原因如下:
    = 1 时损失函数 = −log(^) ,如果想要损失函数 尽可能得小(靠近0),因为 sigmoid 函数取值 [0,1] ,那么^就要尽可能大(^取值为1时), 所以^ 会无限接近于 1
    = 0 时损失函数 = −log(1 − ^) ,如果想要损失函数 尽可能得小(靠近0),那么^ 就要尽可能小(y ^取值为0时),因为 sigmoid 函数取值[0,1],所以^会无限接近于 0。
    在这门课中有很多的函数效果和现在这个类似,就是如果等于 1,我们就尽可能让^
    大,如果等于 0,我们就尽可能让 ^ 变小。
  • 损失函数是在单个训练样本中定义的,它衡量的是算法在单个训练样本中表现如何,为了衡量算法在全部训练样本上的表现如何,需要定义一个算法的代价函数(成本函数),算法的代价函数是对个样本的损失函数求和然后除以:

  • 损失函数只适用于像这样的单个训练样本,用于衡量单一训练样本的效果。而代价函数是用于衡量参数 w 和 参数b的效果在全部训练集上总代价,所以在训练逻辑回归模型时候,我们需要找到合适的,来让代价函数 的总代价降到最低

4、梯度下降法(Gradient Descent

神经网络编程基础_第9张图片

  • 在深度学习中,梯度下降法是优化算法之一,用于最小化损失函数。在神经网络中,损失函数通常用来衡量模型预测结果与真实标签之间的误差。
  • 梯度下降法的基本思想是,通过不断迭代调整模型参数,使损失函数的值逐渐减小,最终达到最小化损失函数的目的。具体来说,对于给定的损失函数,我们需要计算其关于模型参数(例如神经网络中的权重)的梯度(即导数),然后按照梯度的方向进行参数的更新,使损失函数的值逐渐减小。这个过程可以进行多次迭代,直到损失函数的值达到一个较小的阈值或者达到一定的迭代次数为止。
  • (例子)在下面的图中,横轴表示空间参数和,在实践中,可以是更高的维度,但是为了更好地绘图,我们定义和,都是单一实数,代价函数(成本函数)(, )是在水平轴和上的曲面,因此曲面的高度就是(, )在某一点的函数值。我们所做的就是找到使得代价函数(成本函数)(, )函数值是最小值,对应的参数和。代价函数(成本函数)(, )是一个凸函数(convex function),像一个大碗一样,因为非凸图像有很多不同的局部最小值。由于逻辑回归的代价函数(成本函数)(, )特性,必须定义代价函数(成本函数)(, )为凸函数, 初始化和。可以用如图那个小红点来初始化参数和,也可以采用随机初始化的方法,对于逻辑回归几乎所有的初始化方法都有效,因为函数是凸函数,无论在哪里初始化,应该达到同一点或大致相同的点。

    神经网络编程基础_第10张图片

  • (例子步骤)(1)、朝着最陡的下坡方向走一步,不断地迭代(2)、朝最陡的下坡方向走一步,如图,走到了如图中第二个小红点处(3)、可能停在这里也有可能继续朝最陡的下坡方向再走一步,如图,经过两次迭代走到第三个小红点处(4)、直到走到全局最优解或者接近全局最优解的地方。通过以上的三个步骤我们可以找到全局最优解,也就是代价函数(成本函数)(, )这 个凸函数的最小值点

    神经网络编程基础_第11张图片

  • (例子细化说明,只要一个参数,图像的右半部分)假定代价函数(成本函数)() 只有一个参数,即用一维曲线代替多维曲线,这样可以更好画出图像。从右半部分进行梯度下降,寻找最优的损失函数,进行不断迭代的公式为 ≔ − *()/。其中: =表示更新参数, 表示学习率(learning rate),用来控制步长(step),即向下走一步的长度()/就是函数()对 求导(derivative),在代码中经常使用表示这个结果。假设以如图点为初始点,该点处的斜率的符号是正的,即 () / > 0,所以接下来会向左走一步。

    神经网络编程基础_第12张图片

  • (例子细化说明,只要一个参数,图像的左半部分)整个梯度下降法的迭代过程就是不断地向右走,即朝着最小值点方向走。因为在左半部分始终有() / < 0,所以经过 ≔ − *()/不断循环迭代计算,参数w会越来越大

神经网络编程基础_第13张图片

  • (例子细化说明,两个参数)也就是偏导数,比如逻辑回归的代价函数(成本函数)(, )是含有两个参数的。 ≔ − *(,)/    ≔ − *(,)/。 表示求偏导符号,可以读作 round,(,)/就是函数(, ) 对 求偏导,在代码中我们会使用 表示这个结果,(,)/就是函数(, )对 求偏导,在代码中我们会使用 表示这个结果, 小写字母用在求导数(derivative),即函数只有一个参数, 偏导数符号 用在求偏导(partialderivative),即函数含有两个以上的参数
  • 梯度下降法有多种变体,例如批量梯度下降(Batch Gradient Descent)、随机梯度下降(Stochastic Gradient Descent)和小批量梯度下降(Mini-Batch Gradient Descent)等。这些变体的主要区别在于每次更新参数时使用的数据量不同。批量梯度下降使用全部训练数据计算梯度,因此每次更新参数的代价较高;随机梯度下降只使用一个样本计算梯度,因此更新速度较快,但可能会出现参数的震荡;小批量梯度下降折中使用部分训练数据计算梯度,既能保证更新速度,又能避免参数震荡。

5、使用计算图求导数

  • 一个神经网络的计算,都是按照前向或反向传播过程组织的。首先我们计算出 一个新的网络的输出 (前向过程,蓝色部分过程) ,紧接着进行一个反向传输操作 (红色部分过程) 。后者我们用来计算出对应的梯度或导数

    神经网络编程基础_第14张图片

  •  / = / * / = 3 * 1 = 3
  • (符号定义)在实际的神经网络编程中使用 = 3,是代码里的变量名,其真正的定义是
    /。 = 3 是代 码里的变量名,其实代表 / 的值
  • 同理由偏导数可知 / = / * / = 3
  • / = / * / * / = 3 * 1 * c,而 c = 2,所以 / = 6
  • / = / * / * / = 3 * 1 * b,而 b = 3,所以 / = 9
  • (为什么在神经网络中强调计算偏导数?)
    • 在神经网络编程中,计算导数是非常重要的,因为它可以帮助我们对神经网络进行优化和训练。具体来说,计算导数可以帮助我们确定如何调整神经网络中的权重和偏差,以便使其能够更好地拟合训练数据。
    • 在训练神经网络时,通常使用反向传播算法来计算每个神经元的导数。反向传播算法通过将误差从输出层反向传播到输入层,并利用链式法则计算每个神经元的导数。然后,根据这些导数来更新神经网络中的权重和偏差,以最小化网络的损失函数。
    • 因此,计算导数在神经网络编程中是非常重要的,它可以帮助我们训练出更加准确和有效的神经网络,以便用于各种不同的应用场景,如图像分类、语音识别、自然语言处理等。

6、逻辑回归中的梯度下降Logistic Regression Gradient

Descent

神经网络编程基础_第15张图片

神经网络编程基础_第16张图片

  •  需要反向计算出代价函数(, )关于的导数,由损失函数(, )对求偏导数得 (,)/ = −/ + (1 − )/(1 − ),在实际的编程实现过程中(,)/可以简写为,表示(, )对求偏导数
  • 再反向一步,在编写 Python 代码时,只需要用 来表示代价函数 关于 的导数 / ,也可以写成(,) / ,这两种写法都是正确的。 / = − 。

    神经网络编程基础_第17张图片

  • 现在进行最后一步反向求偏导,也就是计算变化对代价函数的影响。1 表示 /1 = / * /1,其中 /1 = 1,所以 /1 = / * /1 = 1 ⋅ ,同理 2 表示 /2 = 2 ⋅ , =
  • 因此,关于单个样本的梯度下降算法,你所需要做的就是如下的事情: 使用公式 = ( − ) 计算 , 使用 1 = 1 计算 1 2 = 2 计算 2 = 来计算 然后: 更新1 = 1 − 1, 更新2 = 2 − 2, 更新 = − 。这就是关于单个样本实例的梯度下降算法中参数更新一次的步骤。

7、m个样本的梯度下降

你可能感兴趣的:(深度学习,神经网络,深度学习)