Neural Network and Deep Learning 第二周笔记

Neural Network and Deep Learning

week 2

1. Logistic Regression as a Neural Network

1.1 Binary Classification

图像在计算机的存储

三个矩阵,分别存储RGB值,可以转化为一个向量:

X = [ R . . . , G . . . , B . . . ]

(一共有 n x 个)

一些常用的符号

  • (x,y):一个样本,x n x 维(即维度为( n x ,1))的特征向量。 x R n x m y是此样本的标签, y { 0 , 1 }

  • 样本集(X,Y)

    X = [ x 1 1 x 2 1 x m 1 x 1 2 x 2 2 x m 2 x 1 n x x 2 n x x m n x ]

Y = [ y 1 , y 2 , . . . , y m ]

x.shape=(nx,m)
y.shapr=(1,m)

训练集 { ( x 1 , y 1 ) , ( x 2 , y 2 ) . . . ( x m , y m ) }
- m:训练集数目

1.2 Logistic Regression

对于二元分类问题来讲,给定一个输入特征向量 X ,它可能对应一张图片,想识别这张图片识别看它是否是一只猫或者不是一只猫的图片,我们想要一个算法能够输出预测,我们称之为 y ^ ,也就是对实际值 y 的估计。

更正式地来说,你想让 y ^ 表示 y 等于 1 的一种可能性或者是机会,前提条件是给定了输入特征 X X 是一个
n x 维的向量(相当于有 n x 个特征的特征向量)

我们用 w 来表示逻辑回归的参数,这也是一个 n x 维向量(因为 w 实际上是特征权重,维度与特征向量相同),参数里面还有 b ,这是一个实数(表示偏差)。所以给出输入 x 以及参数 w b 之后,我们怎样产生输出预测值 y ^
即:
- Give X

  • want: y ^ = P ( y = 1 , x )

  • 其中: x R n x , y ^ { 0 , 1 }

  • 参数: w R n x , b R

output:

y ^ = σ ( w T + b )

这时候我们得到的是一个关于输入 x 的线性函数,这是你在做线性回归时所用到的,但是这对于二元分类问题来讲不是一个非常好的算法,因为我们想让 y ^ 表示实际值 y 等于1的机率的话, y ^ 应该在0到1之间。

这是一个需要解决的问题,因为 w T + b 可能比 1 要大得多,或者甚至为一个负值。对于想要的在 0 和 1 之间的概率来说它是没有意义的,因此在逻辑回归中,我们的输出应该是 y ^ 等于由上面得到的线性函数式子作为自变量的 sigmoid函数中,将线性函数转换为非线性函数。

sigmoid函数

σ ( z ) = 1 1 + e z

实现逻辑回归时,目标是根据训练集学习参数w,b,这样会使 y ^ 更好的估计 y = 1 的概率

1.3 Logistic Regression Cost Function

为什么需要代价函数(cost function)

对于给到的训练集 { ( x 1 , y 1 ) , ( x 2 , y 2 ) . . . ( x m , y m ) } ,我们希望训练w,b后得到的输出值(预测值) y ^ 和实际值相差较小。

为了优化参数w,b,定义了代价函数(cost function),通过训练代价函数来得到参数w,b

先看看逻辑回归的输出函数:
y ^ ( i ) = σ ( w T x ( i ) + b ) , where σ ( z ) = 1 1 + e ( z )

Gicen { ( x ( 1 ) , y ( 1 ) ) , . . . , ( x ( m ) , y ( m ) ) } , want y ^ ( i ) y ( i )

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

损失函数(Loss function)

损失函数又叫做误差函数,用来衡量算法的运行情况,Loss function: L ( y ^ , y ) .
我们通过这个 L 称为的损失函数,来衡量预测输出值和实际值有多接近。一般我们用预测值和实际值的平方差或者它们平方差的一半。

L ( y ^ , y ) = 1 2 ( y ^ y ) 2

但是通常在逻辑回归中我们不这么做,因为当我们在学习逻辑回归参数的时候,会发现我们的优化目标不是凸优化,只能找到多个局部最优值,梯度下降法很可能找不到全局最优值。

我们在逻辑回归中用到的损失函数是:

L ( y ^ , y ) = ( y log y ^ + ( 1 y ) log ( 1 y ^ ) )

为什么要用这个函数作为逻辑损失函数?

当我们使用平方误差作为损失函数的时候,会想要让这个误差尽可能地小,对于这个逻辑回归损失函数,我们也想让它尽可能地小。

  • y = 1 时损失函数 L = log ( y ^ ) ,如果想要损失函数 L 尽可能得小,那么 y ^ 就要尽可能大,因为sigmoid函数取值[0,1],所以 y ^ 会无限接近于 1。
  • y = 0 时损失函数 L = log ( 1 y ^ ) ,如果想要损失函数 L 尽可能得小,那么 y ^ 就要尽可能小,因为 sigmoid 函数取值[0,1],所以 y ^ 会无限接近于 0。

代价函数(Cost function)

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

J ( w , b ) = 1 m i = 1 m L ( y ^ ( i ) , y ( i ) )

= 1 m i = 1 m ( y ( i ) log y ^ ( i ) ( 1 y ( i ) log ( 1 y ^ ) log ( 1 y ^ ( i ) ) ) )

损失函数只适用于像这样的单个训练样本,而代价函数是参数的总代价。

所以在训练逻辑回归模型时候,我们需要找到合适的 w b ,来让代价函数 J 的总代价降到最低。

根据我们对逻辑回归算法的推导及对单个样本的损失函数的推导和针对算法所选用参数的总代价函数的推导,结果表明逻辑回归可以看做是一个非常小的神经网络。

1.4 Gradient Descent

梯度下降法可以做什么?

在测试集上,通过最小化代价函数(成本函数) J ( w , b ) 来训练的参数 w b

步骤

  1. 初始化 w b , 通常设为0,但也可以采用随机初始化的方法,对于逻辑回归几乎所有的初始化方法都有效,因为函数是凸函数,无论在哪里初始化,应该达到同一点或大致相同的点。
  2. 朝最陡的下坡方向走一步,不断地迭代。
  3. 直到走到全局最优解或者接近全局最优解的地方。

通过以上的三个步骤我们可以找到全局最优解,也就是代价函数(成本函数) J ( w , b ) 这个凸函数的最小值点。

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

假定代价函数(成本函数) J ( w ) 只有一个参数 w ,即用一维曲线代替多维曲线,这样可以更好画出图像。

迭代的算法伪代码如下:


repeat{
A;
}

其中:

A : ( w == w α J ( w ) w )

α 表示学习率(learning rate),用来控制步长(step),即向下走一步的长度 J ( w ) w
就是函数 J ( w ) w 求导(derivative)。

整个梯度下降法的迭代过程就是不断地向左走,直至逼近最小值点。

1.5 Derivatives

1.6 More Derivatives Examples

1.7 Computation Graph

可以说,一个神经网络的计算,都是按照前向或反向传播过程组织的。首先我们计算出一个新的网络的输出(前向过程),紧接着进行一个反向传输操作。后者我们用来计算出对应的梯度或导数。计算图解释了为什么我们用这种方式组织这些计算过程。

从图中我们可以看出,通过一个从左向右的过程,你可以计算出 J 的值。为了计算导数,从右到左(红色箭头,和蓝色箭头的过程相反)的过程是用于计算
导数最自然的方式。

1.8 Derivatives with a Computation Graph

现在我们利用流程图计算出函数 J 的导数.

J u = J v v b

J b = J u u b

J a = J u u a

在反向传播算法中的术语,我们看到,如果你想计算最后输出变量的导数,使用你最关心的变量对 v 的导数,那么我们就做完了一步反向传播,在这个流程图中是一个反向步。

1.9 Logistic Regression Gradient Descent

本节我们讨论怎样通过计算偏导数来实现逻辑回归的梯度下降算法。它的关键点是几个重要公式,其作用是用来实现逻辑回归中梯度下降算法。

但是在本节中,我们将使用计算图对梯度下降算法进行计算。虽然使用计算图来计算逻辑回归的梯度下降算法有点大材小用了。但是,我认为以这个例子作为开始来讲解,可以使你更好的理解背后的思想。从而在讨论神经网络时,你可以更深刻而全面地理解神经网络。

假设样本只有两个特征 x 1 x 2 ,为了计算 z ,我们需要输入参数 w 1 w 2 b 。因此 z 的计算公式为: z = w 1 x 1 + w 2 x 2 + b .

回想一下逻辑回归的公式定义如下:

y ^ = a = σ ( z ) ,其中 z = w T + b , σ ( z ) = 1 1 + e ( z )

损失函数: L ( y ^ ( i ) , y ( i ) ) = y ( i ) log y ^ ( i ) ( 1 y ( i ) ) log ( 1 y ^ ( i ) )

代价函数: J ( w , b ) = 1 m i = 1 m L ( y ^ ( i ) , y ( i ) )

假设现在只考虑单个样本的情况,单个样本的代价函数定义如下:

L ( a , y ) = ( y log ( a ) + ( 1 y ) log ( 1 a ) )

其中 a 是逻辑回归的输出, y 是样本的标签值。现在画出表示这个计算的计算图。
先复习下梯度下降法, w b 的修正量可以表达如下:

w := w α J ( w , b ) w , b := b α J ( w , b ) b

现在来讨论通过反向计算出导数。 因为我们想要计算出的代价函数 L ( a , y ) 的导数,首先我们需要反向计算出代价函数 L ( a , y ) 关于 a 的导数。

d a = L ( a , y ) a = y / a + ( 1 y ) / ( 1 a )

d z = L z = L ( a , y ) z = ( L a ) ( a z ) = a y

d w 1 = L ( a , y ) w 1 = L w 1 = x 1 d z

d w 2 = L ( a , y ) w 2 = L w 2 = x 2 d z

d b = d z

更新策略:

w 1 = w 1 α   d w 1

w 2 = w 2 α   d w 2

b = b α   d b

1.10 Gradient Descent on m Examples

之前我们已经学会如何计算导数,以及应用梯度下降在逻辑回归的一个训练样本上。现在我们想要把它应用在 m 个训练样本上。

回顾一下在 m 个样本上的logistic gegression:

J ( w , b ) = 1 m i = 1 m L ( a ( i ) , y )

a ( i ) = y ( i ) = σ ( z ( i ) ) = σ ( w T x ( i ) + b )

w 1 J ( w , b ) = 1 m i = 1 m w i L ( a ( i ) y ( i ) )

伪代码

上面只应用了一步梯度下降。因此你需要重复以上内容很多次,以应用多次梯度下降。

但这种计算中有两个缺点,也就是说应用此方法在逻辑回归上你需要编写两个for循环。

第一个 for 循环是一个小循环遍历 m 个训练样本,

第二个 for 循环是一个遍历所有特征的 for循环。这个例子中我们只有 2 个特征,所以 n 等于 2 并且 n x 等于 2。 但如果你有更多特征,需要一个 for 循环遍历所有 n 个特征。

但是在代码中显式地使用 for 循环使算法很低效,同时在深度学习领域会有越来越大的数据集。所以能够应用没有显式的for循环算法是重要的,并且会适用于更大的数据集。

这里有一些叫做向量化技术,它可以使代码摆脱显式的 for 循环。

2. Python and Vectorization

2.1 Vectorization

What is vectorization

在logestic regression中需要去计算 z = w T + b w = [ w 1 , w 2 , . . . , w n ] T x = [ x 1 , x 2 , . . . , x n ] T 都是列向量。

如果有很多的特征那么就会有一个非常大的向量,所以 w R n x , x R n x ,所以如果你想使用非向量化方法去计算 w T x ,你需要用如下方式(python)

z=0 
for i in range(n_x) 
   z+=w[i]*x[i] 
   z+=b 

这是一个非向量化的实现,你会发现这真的很慢,作为一个对比,向量化实现直接计算 w T x ,,代码如下:

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

这是向量化计算 w T x ,的方法,它非常快

2.2 More Vectorization Examples

当我们在写神经网络程序时应该避免写循环(loop)语句。虽然有时写循环(loop)是不可避免的,但是我们可以使用比如 numpy 的内置函数或者其他办法去计算。当你这样使用后,程序效率总是快于循环(loop)。

另外一个例子。如想计算向量 u = A v

现在,利用向量化对logstic regression中的提到下降进行改进:

2.3 Vectorizing Logistic Regression

回顾逻辑回归的前向传播步骤

m 个训练样本。

然后对第一个样本进行预测,需要这样计算:计算 z ,即 z ( 1 ) = w T x ( 1 ) + b 。然后计算激活函数 a ( 1 ) = σ ( z ( 1 ) ) ,计算第一个样本的预测值 y

对第二个样本进行预测,需要计算 z ( 2 ) = w T x ( 2 ) + b a ( 2 ) = σ ( z ( 2 ) )

对第三个样本进行预测,需要计算 z ( 3 ) = w T x ( 3 ) + b a ( 3 ) = σ ( z ( 3 ) )

依次类推。

用到的公式:

z ( 1 ) = w T x ( 1 ) + b , z ( 2 ) = w T x ( 2 ) + b , z ( 3 ) = w T x ( 3 ) + b

a ( 1 ) = σ ( z ( 1 ) ) , a ( 2 ) = σ ( z ( 2 ) ) , a ( 3 ) = σ ( z ( 3 ) )

X = [ x 1 1 x 2 1 x m 1 x 1 2 x 2 2 x m 2 x 1 n x x 2 n x x m n x ]

B = [ b , b , . . . , b ]

X.shape=(nx,m)
B.shape=(1,m)

Z = [ z ( 1 ) , z ( 2 ) , . . . , z ( m ) ] = W T X + B

改进

import numpy as np
Z=np.dot(W.T,X)+B

2.4 Vectorizing Logistic Regression’s Gradient

上述(伪)代码就是我们之前实现的,我们已经去掉了一个 for 循环,但用上述方法计算 d w 仍然需要一个循环遍历训练集,我们现在要做的就是将其向量化!

首先有:

d z ( 1 ) = a ( 1 ) y ( 1 ) , d z ( 2 ) = a ( 2 ) y ( 2 ) ,…, d z ( m ) = a ( m ) y ( m )

则:

d Z = [ d z ( 1 ) , d z ( 2 ) , . . . , d z ( m ) ]

A = [ a ( 1 ) , a ( 2 ) , . . . , a ( m ) ]

Y = [ y ( 1 ) , y ( 2 ) , . . . , y ( m ) ]

即:

d Z = A Y = [ a ( 1 ) y ( 1 ) , a ( 2 ) y ( 2 ) , . . . , a ( m ) y ( m ) ]

所以:

d b = 1 m i = 1 m d z ( i ) d b = ( 1 / m ) n p . s u n ( d Z )

d w = 1 m X d z T

2.5 Broadcasting in Python

猜你喜欢

转载自blog.csdn.net/turing365/article/details/80075055