本文是Deep Learning Specialization系列课程的第1课《Neural Networks and Deep Learning》中Logistic Regression as a Neural Network部分的学习笔记。
内容包括:
逻辑回归(Logistics Regression)是用来处理二进制分类(Binary Classification)的一个算法,比如简单的是猫(1)或不是猫(0)的图像分类问题。
对一张RGB图片,计算机是以像素来存储的,假如输入的是一个6464的RGB图片,其总共大小为6464*3=12288。 那么输入数据x的维度就是nx = 12288
。
二进制分类,就是输入图片(将其转换为向量x
),通过一个分类方法,来判断这个图片上的内容(输出y
)。
这里单个训练数据就是(x, y), 其中,x是 n x n_x nx维的特征向量,y是1或0的标注数据。
当训练数据集有m个时,训练数据就可表示为
{ ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , … , ( x ( m ) , y ( m ) ) } \{{(x^{(1)}, y^{(1)}), (x^{(2)}, y^{(2)}), …, (x^{(m)}, y^{(m)})}\} {(x(1),y(1)),(x(2),y(2)),…,(x(m),y(m))}
此时训练数据集中的X
就是 n x ∗ m n_x*m nx∗m维度的矩阵了,而Y
是 1 ∗ m 1*m 1∗m维度的矩阵。
继续上面的二进制分类问题,当我们输入x
(比如说转变为特征向量的图片),得到 y ^ \hat y y^,这个 y ^ \hat y y^是这个标注结果y
的一个概率,即 p ( y = 1 ∣ x ) p(y=1 | x) p(y=1∣x)。
这里,x
仍是一个 n x n_x nx维度的特征向量。
对于线性回归问题,这里会涉及到两个参数:w
和b
,其中w
是和x
同维度的向量,b
是一个实数(也成为偏置,bias)。最后的方程式是:
y ^ = w T ∗ x + b \hat y = w^T * x + b y^=wT∗x+b
由于 y ^ \hat y y^是 y=1
的概率,对上面的公式,我们应该加一个函数将其限定在(0, 1)这个区间内,这个函数就叫做激活函数(Activate Function),比如sigmoid、relu函数。
输出: y ^ = σ ( w T ∗ x + b ) \hat y = \sigma (w^T * x + b) y^=σ(wT∗x+b)
sigmoid函数: σ ( z ) = 1 / ( 1 + e − z ) \sigma (z) = 1 / (1 + e^{-z}) σ(z)=1/(1+e−z)
一般情况下,我们会把w
和b
分开来处理,但可能有些研究会将其合并为统一的参数。
由于我们的训练数据一般是一个数据集,因此针对某一个数据时,一般在对应的参数右上角加一个 ( i ) (i) (i)来标记,如:
则逻辑回归函数为:
y ^ ( i ) = σ ( w T ∗ x ( i ) + b ) \hat y^{(i)} = \sigma (w^T * x^{(i)} + b) y^(i)=σ(wT∗x(i)+b) where σ ( z ( i ) ) = 1 / ( 1 + e − z ( i ) ) \sigma (z^{(i)}) = 1 / (1 + e^{-z(i)}) σ(z(i))=1/(1+e−z(i))
损失函数(Loss Function)是为了量测输出值 y ^ \hat y y^是有多接近标注数据y
,表示为 ℓ ( y ^ , y ) \ell (\hat y, y) ℓ(y^,y),这里使用log函数,而不是平方误差(因为平方误差会得到带有多个局部最优值的优化问题。 因此,通过梯度下降法可能找不到全局最优值)。
ℓ ( y ^ , y ) = − ( y ∗ l o g y ^ + ( 1 − y ) ∗ l o g ( 1 − y ^ ) ) \ell (\hat y, y) = -(y*log\hat y + (1-y)*log(1-\hat y)) ℓ(y^,y)=−(y∗logy^+(1−y)∗log(1−y^))
y
为1时, ℓ ( y ^ , y ) = − l o g y ^ \ell (\hat y, y) = -log\hat y ℓ(y^,y)=−logy^,则期望 l o g y ^ log\hat y logy^越大越好,即 y ^ \hat y y^越大越好。y
为0时, ℓ ( y ^ , y ) = − l o g ( 1 − y ^ ) \ell (\hat y, y) = -log(1 - \hat y) ℓ(y^,y)=−log(1−y^),则期望 l o g ( 1 − y ^ ) log(1 - \hat y) log(1−y^)越大越好,即 y ^ \hat y y^越小越好损失函数(Loss Function)是针对一个数据的,当针对整个数据集时,需要用到的是代价函数(Cost Function),针对参数w
和b
的一个平均值:
J ( w , b ) = 1 / m ∗ ∑ ( ℓ ( y ^ ( i ) , y ( i ) ) ) = − 1 / m ∗ ∑ [ y ( i ) ∗ l o g y ^ ( i ) + ( 1 − y ( i ) ) ∗ l o g ( 1 − y ^ ( i ) ) ] J(w, b) = 1/m * \sum(\ell (\hat y^{(i)}, y^{(i)})) = -1/m * \sum \lbrack y^{(i)}*log\hat y^{(i)} + (1-y^{(i)})*log(1-\hat y^{(i)})\rbrack J(w,b)=1/m∗∑(ℓ(y^(i),y(i)))=−1/m∗∑[y(i)∗logy^(i)+(1−y(i))∗log(1−y^(i))]
损失函数选择的比较恰当后,会根据w
和b
值的不同,呈现出一个碗状,会=存在一个最小值。这就需要来应用梯度递减法来找到最小的参数w
和b
了。
这里引入了超参数学习率(learning rate),对w
,运用如下公式进行梯度递减的计算:
w = w − α ∗ d w w = w - \alpha * dw w=w−α∗dw
其中 d w dw dw是w
关于 J ( w , b ) J(w, b) J(w,b)的导数,也可以理解为在w
这点的斜率。如下图所示,不管dw
是正还是负,通过循环计算后,都会指向函数的最小值。
对偏置b也是一样: b = b − α ∗ d b b = b - \alpha * db b=b−α∗db
计算图(Computation Graph)是将计算的过程用图形表示出来,比如:
J ( a , b , c ) = 3 ( a + b c ) J(a, b, c) = 3(a + bc) J(a,b,c)=3(a+bc)这样一个简单的函数,可以将其拆分成更小的函数, u = b c u=bc u=bc, v = a + u v=a+u v=a+u, J = 3 v J=3v J=3v,并将每一步用图来表示出来。
在求复合函数的导数时,将组成符合函数的各个子函数按照计算图的方式列出来,先求各个子函数的导数,再通过链式法则(Chain Rule)来求最后复合函数的导数。
首先,我们来先求 J J J关于 v v v的导数 d v = ∂ J / ∂ v dv = \partial J/\partial v dv=∂J/∂v,因为 J = 3 v J=3v J=3v这里只有一步,所以能直接求得 d v = ∂ J / ∂ v = 3 dv = \partial J/\partial v = 3 dv=∂J/∂v=3
继续来通过链式法则来进行反向传播(Back Propagation)的计算。
如果要求 J J J关于 a a a的导数 d a = ∂ J / ∂ a da = \partial J/\partial a da=∂J/∂a,这里就有 J = 3 v J=3v J=3v和 v = a + u v=a+u v=a+u两步了,因此就需要用到链式法则, d a = ∂ J ∂ v ∗ ∂ v ∂ a = 3 ∗ 1 = 3 da = {\partial J\over \partial v} * {\partial v\over \partial a} = 3 * 1 = 3 da=∂v∂J∗∂a∂v=3∗1=3.
依次求J关于b和c的导数
这里假设b
由3稍微变大点为3.001,那么先是影响u
,将其从6变为6.002,再影响v
,将其从11变为11.002,最后影响到J
,将其从33变为33.006。这里也能看出,当b
增长0.001时,J
最终增长 0.001 ∗ 6 = 0.006 0.001 * 6 = 0.006 0.001∗6=0.006
上面逻辑回归的函数也是一个复合函数:
假设我们有两个输入值 x 1 x_1 x1, x 2 x_2 x2,为了计算 z z z,还需要 w 1 w_1 w1, w 2 w_2 w2和 b b b。将上面的函数以计算图的方式表现出来,如下所示:
通过反向传播求导:
d a = ∂ L ( a , y ) / ∂ a = − y / a + ( 1 − y ) / ( 1 − a ) da = \partial L(a, y)/\partial a = -y/a + (1-y) / (1-a) da=∂L(a,y)/∂a=−y/a+(1−y)/(1−a)
d z = ∂ L ( a , y ) / ∂ z = ∂ L ( a , y ) ∂ a ∗ ∂ a ∂ z = ( − y / a + ( 1 − y ) / ( 1 − a ) ) ∗ a ( 1 − a ) = a − y dz = \partial L(a, y)/\partial z = {\partial L(a, y)\over \partial a} * {\partial a\over \partial z} = (-y/a + (1-y) / (1-a)) * a(1-a) = a - y dz=∂L(a,y)/∂z=∂a∂L(a,y)∗∂z∂a=(−y/a+(1−y)/(1−a))∗a(1−a)=a−y
d w 1 = ∂ z / ∂ w 1 = x 1 ∗ d z d{w_1} = \partial z/\partial w_1 = x_1 * dz dw1=∂z/∂w1=x1∗dz
d w 2 = ∂ z / ∂ w 2 = x 2 ∗ d z dw_2 = \partial z/\partial w_2 = x_2 * dz dw2=∂z/∂w2=x2∗dz
d b = ∂ z / ∂ b = d z db = \partial z/\partial b = dz db=∂z/∂b=dz
那么 w 1 w_1 w1的梯度递减计算可表示为: w 1 = w 1 − α ∗ d w 1 w_1 = w_1 - \alpha * dw_1 w1=w1−α∗dw1
Cost Function的表达式是:
J ( w , b ) = 1 / m ∗ ∑ ( ℓ ( a ( i ) , y ( i ) ) ) J(w, b) = 1/m * \sum(\ell (a^{(i)}, y^{(i)})) J(w,b)=1/m∗∑(ℓ(a(i),y(i)))
其中, a ( i ) = y ^ ( i ) = σ ( z ) = σ ( w T X ( i ) + b ) a^{(i)} = \hat y{(i)} = \sigma(z) = \sigma(w^TX^{(i)} + b) a(i)=y^(i)=σ(z)=σ(wTX(i)+b)
其参数仍然为 w 1 w_1 w1, w 2 w_2 w2和 b b b,那通过Cost Function来对参数(如 w 1 w_1 w1)进行求导,公式如下:
∂ ∂ w 1 J ( w , b ) = 1 / m ∗ ∑ ∂ ∂ w 1 ℓ ( a ( i ) , y ( i ) ) {\partial \over \partial w_1} J(w, b) = 1/m * \sum{\partial \over \partial w_1}\ell (a^{(i)}, y^{(i)}) ∂w1∂J(w,b)=1/m∗∑∂w1∂ℓ(a(i),y(i))
在计算时,由于有m个训练数据集,因此需要一个循环来计算 d J dJ dJ, d w dw dw, d b db db的总和,再求均值。最后通过梯度递减算法来找到参数的最小值。
从上面对m个训练数据集的计算方式可以看出,我们还是在使用循环的方式,这在数值运算中,效率是很低的,这里,我们就需要用到向量化(Vectorization)。
the vectorization of a matrix is a linear transformation which converts the matrix into a column vector.
这里使用到的向量化,似乎与维基的解释不一样,简单的理解就是代替了原来的循环,将本来要做m次循环的计算转化为1次计算。
还是以之前的逻辑回归为例,其计算方式是将各个参数分开来计算,如下所示:
这里要做的向量化就是把各个量组合成向量或者矩阵,比如:
X = [ . . . . x ( 1 ) x ( 2 ) . x ( m ) . . . . ] X = \begin{bmatrix} . & . & .& . \\ x^{(1)} & x^{(2)} & .& x^{(m)}\\ . & . & .& . \end{bmatrix} X=⎣⎡.x(1)..x(2).....x(m).⎦⎤
Z = [ z ( 1 ) , z ( 2 ) , … , z ( m ) ] = w T X + b Z = [z^{(1)}, z^{(2)}, …, z^{(m)}] = w^TX + b Z=[z(1),z(2),…,z(m)]=wTX+b
再加上Numpy的广播功能这样,就可以表示成 Z = np.dot(w.T, X) + b
对逻辑回归的反向传播,也同样可以用这种向量化的方式。