深度学习和神经网络-神经网络基础

1.二分类(Binary Classification)

逻辑回归(logistic regression)是一个用于二分类的算法.同样的,我们从一个问题说起,加入你有一张图片作为输入,比如这只猫,如果识别这张图片为猫,则输出标签1作为结果;如果识别不是猫,则输出标签0为结果,现在我们用y来表示输出的结果标签,如下图所示.

通常在计算机中,为了保存一张图片,需要保存三个矩阵,分别对应图片中的红、绿、蓝三种颜色通道,如果你的图片大小为64*64像素,那么你就有三个规模为64*64的矩阵,分别对于图片中红、绿、蓝三种像素的强度值.

 

 

 

 此时,为了把这些像素值放到一个特征向量中,我们需要把这些像素值提取出来,然后放如一个特征向量x.如果图片的大小为64*64像素,那么向量x的总维度将会是64*64*3,这是三给像素矩阵中像素的总量.在这个例子中结果为12,288.现在我们用 nx=12,288来表示输入特征向量x的维度.所以在二分类问题中,我们的目标就是学习得到一个分类器,他以图片的特征向量作为输入,然后预测输出结果y为1还是0,也就是预测图片是否有猫.

以下是符号定义:

x:表示一个nx维数据为输入数据,维度为(nx,1);

y:表示输出结果,取值为(0,1);;

(x(i),y(i)):表示第i组数据,可能是训练数据,也可能是测试数据;

X=[x(1),x(2),...,x(m)]:表示所有的训练数据集的输入值,放在一个nx*m的矩阵中,其中m表示样本数目;

Y=[y(1),y(2),...,y(m)]:表示所有训练数据集的输出值,维度为1*m.

python中的shape命令可以很好的用于显示矩阵的规模,即X.shape等于(nx,m),表示这是一个规模为nx乘以m的矩阵;Y.shape等于(1,m),表示这是一个规模为1乘以m的矩阵.

 

2.逻辑回归(Logistic Regression)

本节我们主要介绍逻辑回归的假设函数(Hypothesis Function).

对于二元分类问题来讲,给定一个输入特征向量X,他可能对应一张图片,现在你想识别这张图片看它是否是一只猫,你想要一个算法能够输出预测,你只能称之为y^,也就是你对实际值 y的估计.换句话说,如果X是表示一张图片(有或没有猫),其实y^就是告诉你这是一张猫的图片的概率有多大。X是表示一个nx维的向量,即相对于有nx个特征的特征向量。我们用w来表示逻辑回归的参数,这也还是一个nx为向量(因为实际上是特征权重,维度和特征向量相同),参数里面还有b,这是一个实数(表示偏差 )。所以给出输入x以及参数w和b之后,我么怎么样产生输出预测值y^,我们通常使用这个公式:

 

 

 这个时候我们会得到一个关于输入x的线性函数,但是对于二元分类问题来讲,你是想让y^的值处于0到1之间。而wTx+b的值是从正无穷到 负无穷的数,对于想要的到在0到1之间的概率是没有意义的,所以我们将得到的结果y^放入到sigmoid函数中,将线性函数转变成非线性函数。下面是sigmoid函数的图像和函数:

图像:

函数:

 

 

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

为什么需要代价函数:为了训练逻辑回归模型w和参数b,我们需要一个代价函数,通过训练代价函数来得到参数w和参数b,在这里我们在回顾一下逻辑回归的输出函数:

 

为了让模型通过学习调整参数,你需要给予一个m样本的训练集,这会让你在训练集上找到参数w和参数b,来得到你的输出。对训练集的预测值,我们将它写成y^,我们更加希望它接近训练集中的y值。

 

损失函数又叫做误差函数,是用来衡量算法的运行情况,Loss function:L(y,y^)。

我们通常用这个L称为的损失函数来衡量预测值和实际值有多接近。在逻辑回归中用到的损失函数是:

 

 为什么要使用这个函数作为逻辑损失函数呢?为了更好的理解这个损失函数怎么起作用,我们举两个例子:

 

 在深度学习这门课中有很多的函数效果和现在的这个类似,就是如果y等于1,我们就尽可能让y^变大,如果y等于0,我们就尽可能让y^变大。

同时,我们需要注意的是:损失函数是在单个训练样本中定义的,它衡量的是算法在单个训练样本中表现如何,为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数,算法的代价函数是对m个样本函数求和然后除以m(公式如下):

 

 损失函数只适用与像这个单个训练样本,而代价函数是参数的总代价,所以在训练逻辑回归模型时候,我们需要找到合适的w和b,来让代价函数J的总代价最低。

 

 

4.梯度下降法(Gradient Descent)

 梯度下降法用来在你的测试集上,通过最小代价 函数J(w,b)来训练参数w和b,如下图所示:

 

 

接下来我们对梯度下降法进行形象化说明:

在这个图中,曲面的高度就是J(w,b)在某一点的函数值,我们需要做的就是找到使得代价函数J(w,b)函数值的最小值,对应的参数w和b。

由于逻辑回归的代价函数的特性,我们必须要定义代价函数J(w,b)为凸函数。

初始化w和恶b,可以采用随机初始化的方法,找图像上的任意一点,因为函数是凸函数,所以无论在哪里初始化,应该达到同一点或大致相同的点。

朝最陡的下坡方向走一步,不断的迭代,直到走到全局最优解或接近全局最优解的地方,最终通过以上的方法我们可以找到全局的最优解,也就是代价函数J(w,b)这个凸函数的最小值点。

 

梯度下降法的细节化说明(仅有一个参数)

 

 

 假定代价函数J(w)只有一个参数w,即用 一维曲线代替多维曲线,迭代就是不断重复做下图的公式:

 

 :=表示更新参数,a表示学习率(Learing rate),用来控制步长(step),即向下走一步的长度就是函数J(w)对w求导,在代码中我们会使用dw表示这个结果,对于导数更加形象化的理解就是斜率。假设我们一如图点为初始化点,该点的斜率的符号是正的,即,所以接下来会向左走一步。整个梯度下降法的迭代过程就是不断地向左走,直至逼近最小值点。

 

 

 

假设我们一如下图点为初始化点,该点的斜率的符号是负的,即,所以接下来会向右走一步。整个梯度下降法的迭代过程就是不断地向右走,即朝着最小值点方向走。

 

当有两个参数也是同样地效果,公式如下:

 

 

5.逻辑回归中的梯度下降(Logistics Regression Gradient Descent)

 我们可以通过计算偏导数来实现逻辑回归的梯度下降算法。这个算法的关键点就是几个重要公式,用来实现逻辑回归梯度下降算法,下面我们举例说明。

假设样本只有两个特征x1和x2,为了计算z,我们需要输入参数w1、w2和b,除此之外还有特征值x1和x2,所以z的计算公式为:z=w1x1+w2x2+b 。

 

如图:在这个公式的外侧画上长方形,然后计算:,最后计算损失函数。所以为了使得逻辑回归中的最小代价函数L(a,y),我们需要做的仅仅是修改参数w和b的值。

 

 

因为我们想要计算出的代价函数L(a,y)的导数,首先我们需要反向计算出代价函数关于a的导数,在写代码的时候我们只需要用da来表示对代价函数求关于a的导数。最终我们求得:

 

 

 

 现在我们已经计算出了da,也就是最终输出结果的导数,此时我们可以在反向一步求出dz,也就是代价函数L关于z的导数:,现在进行最后一步反向推导,也就是计算w和b变化对代价函数L的影响,可以用:

          

这三个公式表示,更进一步化简可得:dw1=x1*dz,dw2=x2*dz,db=dz。

最后我们总结一下单个样本的梯度下降算法中参数更新一次的步骤:使用公式dz=(a-y)计算出dz,使用dw1=x1*dz计算dw1,dw2=x2*dz计算dw2,db=dz来计算db,然后更新w1=w1-adw1,w2=w2-dw2和b=b-db。

 

 

 

 

 

 

 那么对于m个训练样本我们应该怎么做呢?

首先,我们需要时刻记住损失函数J(w,b)的定义:,然后我们把上面的公式具体带入到算法当中,我们初始化J=0,dw1=0,dw2=0,db=0

 

 

代码流程:

J=0;dw1=0;dw2=0;db=0;

for i = 1 to m

    z(i) = wx(i)+b;

    a(i) = sigmoid(z(i));

    J += -[y(i)log(a(i))+(1-y(i)log(1-a(i));

    dz(i) = a(i)-y(i);

    dw1 += x1(i)dz(i);

    dw2 += x2(i)dz(i);

    db += dz(i);

J/= m;

dw1/= m;

dw2/= m;

db/= m;

w=w-alpha*dw

b=b-alpha*db

 以上是我们使用for循环来实现算法,实际上,在深度学习算法中使用for循环是一种比较低效的方法,因为通常数据集的大小会很大,,而此时如果使用循环的话必然会 有很大的代价,所以我们用向量化的方法来取代for循环,其实就是线性代数中的向量的内积,具体我们看下面的例子:

for代码:

for i in range(n_x)

  z+=w[i]*x[i]

z+=b

向量化代码:

z=np.dot(w,x)+b

 

最后让我们来表示用伪代码来完成向量化的logistic回归的梯度输出(Vectorizing Logistic Regression‘s  Gradient):

Z=wTX+b=np.dot(ww.T,X)+b

A=g(Z)

dZ=A-Y

dw=1/m * X * dZT

db=1/m *np.sum(dZ)

w=w- a*dw

b=b- a*db

 

tips:如果你想要生成一个1行五列的数组,使用a= np.random. randn(5,1)而不是a=np.random.randn(5),我们也可以很简单的应用a.shape来实现检测。

 

posted @ 2021-01-19 14:12  wt168  阅读(277)  评论(0编辑  收藏  举报