第二周:神经网络的编程基础(Basics of Neural Network programming)
文章目录
第二周:神经网络的编程基础(Basics of Neural Network programming)
2.1 二分类(Binary Classification)
2.2 逻辑回归(Logistic Regression)
2.3 逻辑回归的代价函数(Logistic Regression Cost Function)
2.4 梯度下降法(Gradient Descent)
2.5 导数(Derivatives)
2.6 更多的导数例子(More Derivative Examples)
2.7 计算图(Computation Graph)
2.8 使用计算图求导数(Derivatives with a Computation Graph)
2.9 逻辑回归中的梯度下降(Logistic Regression Gradient Descent)
2.10 m 个样本的梯度下降(Gradient Descent on m Examples)
2.11 向量化(Vectorization)
2.12 向量化的更多例子(More Examples of Vectorization)
2.13 向量化逻辑回归(Vectorizing Logistic Regression)
2.14 向量化 logistic 回归的梯度输出(Vectorizing Logistic Regression's Gradient)
2.15 Python 中的广播(Broadcasting in Python)
2.16 关于 python _ numpy 向量的说明(A note on python or numpy vectors)参考视频:
2.17 Jupyter/iPython Notebooks快速入门(Quick tour of Jupyter/iPython Notebooks)
2.18 (选修)logistic 损失函数的解释(Explanation of logistic regression cost function)
2.1 二分类(Binary Classification)
这周我们将学习神经网络的基础知识,其中需要注意的是,当实现一个神经网络的时候,我们需要知道一些非常重要的技术和技巧。例如有一个包含m mm个样本的训练集,你很可能习惯于用一个for循环来遍历训练集中的每个样本,但是当实现一个神经网络的时候,我们通常不直接使用for循环来遍历整个训练集,所以在这周的课程中你将学会如何处理训练集。
另外在神经网络的计算中,通常先有一个叫做前向暂停(forward pause)或叫做前向传播(foward propagation)的步骤,接着有一个叫做反向暂停(backward pause) 或叫做反向传播**(backward propagation**)的步骤。所以这周我也会向你介绍为什么神经网络的训练过程可以分为前向传播和反向传播两个独立的部分。
在课程中我将使用逻辑回归(logistic regression)来传达这些想法,以使大家能够更加容易地理解这些概念。即使你之前了解过逻辑回归,我认为这里还是有些新的、有趣的东西等着你去发现和了解,所以现在开始进入正题。
逻辑回归是一个用于二分类(binary classification)的算法。首先我们从一个问题开始说起,这里有一个二分类问题的例子,假如你有一张图片作为输入,比如这只猫,如果识别这张图片为猫,则输出标签1作为结果;如果识别出不是猫,那么输出标签0作为结果。现在我们可以用字母 y yy来 表示输出的结果标签,如下图所示:
我们来看看一张图片在计算机中是如何表示的,为了保存一张图片,需要保存三个矩阵,它们分别对应图片中的红、绿、蓝三种颜色通道,如果你的图片大小为64x64像素,那么你就有三个规模为64x64的矩阵,分别对应图片中红、绿、蓝三种像素的强度值。为了便于表示,这里我画了三个很小的矩阵,注意它们的规模为5x4 而不是64x64,如下图所示:
为了把这些像素值放到一个特征向量中,我们需要把这些像素值提取出来,然后放入一个特征向量x xx。为了把这些像素值转换为特征向量 x xx,我们需要像下面这样定义一个特征向量 x xx 来表示这张图片,我们把所有的像素都取出来,例如255、231等等,直到取完所有的红色像素,接着最后是255、134、…、255、134等等,直到得到一个特征向量,把图片中所有的红、绿、蓝像素值都列出来。如果图片的大小为64x64像素,那么向量 x xx 的总维度,将是64乘以64乘以3,这是三个像素矩阵中像素的总量。在这个例子中结果为12,288。现在我们用n x = 12 , 288 n_x=12,288n
x
=12,288,来表示输入特征向量的维度,有时候为了简洁,我会直接用小写的n nn来表示输入特征向量x xx的维度。所以在二分类问题中,我们的目标就是习得一个分类器,它以图片的特征向量作为输入,然后预测输出结果y yy为1还是0,也就是预测图片中是否有猫:
接下来我们说明一些在余下课程中,需要用到的一些符号。
符号定义 :
x xx:表示一个n x n_xn
x
维数据,为输入数据,维度为( n x , 1 ) (n_x,1)(n
x
,1);
yyy:表示输出结果,取值为( 0 , 1 )(0,1)(0,1);
( x ( i ) , y ( i ) ) (x^{(i)},y^{(i)})(x
(i)
,y
(i)
):表示第i ii组数据,可能是训练数据,也可能是测试数据,此处默认为训练数据;
X = [ x ( 1 ) , x ( 2 ) , . . . , x ( m ) ] X=[x^{(1)},x^{(2)},...,x^{(m)}]X=[x
(1)
,x
(2)
,...,x
(m)
]:表示所有的训练数据集的输入值,放在一个 n x × m n_x×mn
x
×m的矩阵中,其中m mm表示样本数目;
Y = [ y ( 1 ) , y ( 2 ) , . . . , y ( m ) ] Y=[y^{(1)},y^{(2)},...,y^{(m)}]Y=[y
(1)
,y
(2)
,...,y
(m)
]:对应表示所有训练数据集的输出值,维度为1 × m 1×m1×m。
用一对( x , y ) (x,y)(x,y)来表示一个单独的样本,x xx代表n x n_xn
x
维的特征向量,y yy 表示标签(输出结果)只能为0或1。
而训练集将由m mm个训练样本组成,其中( x ( 1 ) , y ( 1 ) ) (x^{(1)},y^{(1)})(x
(1)
,y
(1)
)表示第一个样本的输入和输出,( x ( 2 ) , y ( 2 ) ) (x^{(2)},y^{(2)})(x
(2)
,y
(2)
)表示第二个样本的输入和输出,直到最后一个样本( x ( m ) , y ( m ) ) (x^{(m)},y^{(m)})(x
(m)
,y
(m)
),然后所有的这些一起表示整个训练集。有时候为了强调这是训练样本的个数,会写作M t r a i n M_{train}M
train
,当涉及到测试集的时候,我们会使用M t e s t M_{test}M
test
来表示测试集的样本数,所以这是测试集的样本数:
最后为了能把训练集表示得更紧凑一点,我们会定义一个矩阵用大写X XX的表示,它由输入向量x ( 1 ) x^{(1)}x
(1)
、x ( 2 ) x^{(2)}x
(2)
等组成,如下图放在矩阵的列中,所以现在我们把x ( 1 ) x^{(1)}x
(1)
作为第一列放在矩阵中,x ( 2 ) x^{(2)}x
(2)
作为第二列,x ( m ) x^{(m)}x
(m)
放到第m mm列,然后我们就得到了训练集矩阵X XX。所以这个矩阵有m mm列,m mm是训练集的样本数量,然后这个矩阵的高度记为n x n_xn
x
,注意有时候可能因为其他某些原因,矩阵X XX会由训练样本按照行堆叠起来而不是列,如下图所示:x ( 1 ) x^{(1)}x
(1)
的转置直到x ( m ) x^{(m)}x
(m)
的转置,但是在实现神经网络的时候,使用左边的这种形式,会让整个实现的过程变得更加简单:
现在来简单温习一下:X XX是一个规模为n x n_xn
x
乘以m mm的矩阵,当你用Python实现的时候,你会看到X.shape,这是一条Python命令,用于显示矩阵的规模,即X.shape等于( n x , m ) (n_x,m)(n
x
,m),X XX是一个规模为n x n_xn
x
乘以m mm的矩阵。所以综上所述,这就是如何将训练样本(输入向量X XX的集合)表示为一个矩阵。
那么输出标签y yy呢?同样的道理,为了能更加容易地实现一个神经网络,将标签y yy放在列中将会使得后续计算非常方便,所以我们定义大写的Y YY等于y ( 1 ) , y ( m ) , . . . , y ( m ) {{y}^{\left( 1 \right)}},{{y}^{\left( m \right)}},...,{{y}^{\left( m \right)}}y
(1)
,y
(m)
,...,y
(m)
,所以在这里是一个规模为1乘以m mm的矩阵,同样地使用Python将表示为Y.shape等于( 1 , m ) (1,m)(1,m),表示这是一个规模为1乘以m mm的矩阵。
当你在后面的课程中实现神经网络的时候,你会发现,一个好的符号约定能够将不同训练样本的数据很好地组织起来。而我所说的数据不仅包括 x xx 或者 y yy 还包括之后你会看到的其他的量。将不同的训练样本的数据提取出来,然后就像刚刚我们对 x xx 或者 y yy 所做的那样,将他们堆叠在矩阵的列中,形成我们之后会在逻辑回归和神经网络上要用到的符号表示。如果有时候你忘了这些符号的意思,比如什么是 m mm,或者什么是 n nn,或者忘了其他一些东西,我们也会在课程的网站上放上符号说明,然后你可以快速地查阅每个具体的符号代表什么意思,好了,我们接着到下一个视频,在下个视频中,我们将以逻辑回归作为开始。
备注:附录里也写了符号说明。
2.2 逻辑回归(Logistic Regression)
在这个视频中,我们会重温逻辑回归学习算法,该算法适用于二分类问题,本节将主要介绍逻辑回归的Hypothesis Function(假设函数)。
对于二元分类问题来讲,给定一个输入特征向量X XX,它可能对应一张图片,你想识别这张图片识别看它是否是一只猫或者不是一只猫的图片,你想要一个算法能够输出预测,你只能称之为y ^ \hat{y}
y
^
,也就是你对实际值 y yy 的估计。更正式地来说,你想让 y ^ \hat{y}
y
^
表示 y yy 等于1的一种可能性或者是机会,前提条件是给定了输入特征X XX。换句话来说,如果X XX是我们在上个视频看到的图片,你想让 y ^ \hat{y}
y
^
来告诉你这是一只猫的图片的机率有多大。在之前的视频中所说的,X XX是一个n x n_xn
x
维的向量(相当于有n x n_xn
x
个特征的特征向量)。我们用w ww来表示逻辑回归的参数,这也是一个n x n_xn
x
维向量(因为w ww实际上是特征权重,维度与特征向量相同),参数里面还有b bb,这是一个实数(表示偏差)。所以给出输入x xx以及参数w ww和b bb之后,我们怎样产生输出预测值y ^ \hat{y}
y
^
,一件你可以尝试却不可行的事是让y ^ = w T x + b \hat{y}={{w}^{T}}x+b
y
^
=w
T
x+b。
这时候我们得到的是一个关于输入x xx的线性函数,实际上这是你在做线性回归时所用到的,但是这对于二元分类问题来讲不是一个非常好的算法,因为你想让y ^ \hat{y}
y
^
表示实际值y yy等于1的机率的话,y ^ \hat{y}
y
^
应该在0到1之间。这是一个需要解决的问题,因为w T x + b {{w}^{T}}x+bw
T
x+b可能比1要大得多,或者甚至为一个负值。对于你想要的在0和1之间的概率来说它是没有意义的,因此在逻辑回归中,我们的输出应该是y ^ \hat{y}
y
^
等于由上面得到的线性函数式子作为自变量的sigmoid函数中,公式如上图最下面所示,将线性函数转换为非线性函数。
下图是sigmoid函数的图像,如果我把水平轴作为z zz轴,那么关于z zz的sigmoid函数是这样的,它是平滑地从0走向1,让我在这里标记纵轴,这是0,曲线与纵轴相交的截距是0.5,这就是关于z zz的sigmoid函数的图像。我们通常都使用z zz来表示w T x + b {{w}^{T}}x+bw
T
x+b的值。