1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础

记录吴恩达深度学习专项课程笔记,方便之后回顾,共5门课,这是第一门课《神经网络与深度学习》第二周神经网络基础的课程笔记,那我们开始吧。

课程1-1深度学习概论的内容比较简单,主要对深度学习进行了简要概述。首先,我们使用房价预测的例子来建立最简单的单个神经元组成的神经网络模型。然后,我们将例子复杂化,建立标准的神经网络模型结构。接着,我们从监督式学习入手,介绍了不同的神经网络类型,包括Standard NN,CNN和RNN。不同的神经网络模型适合处理不同类型的问题。对数据集本身来说,分为结构化数据和非结构化数据。近些年来,深度学习对非结构化数据的处理能力大大提高,例如图像处理、语音识别和语言翻译等。最后,我们用一张对比图片解释了深度学习现在飞速发展、功能强大的原因。归纳其原因包含三点:数据(Data)计算能力(Computation)算法(Algorithms)

本节课,我们将开始介绍神经网络的基础:逻辑回归(Logistic Regression)向量化(Vectorization)。通过对逻辑回归模型结构的分析,为我们后面学习神经网络模型打下基础。

目录

《2.1二分分类》Binary Classification

《2.2logistic回归》Logistic Regression

《2.3logistic回归损失函数》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.9logistic回归中的梯度下降》Logistic Regression Gradient Descent

《2.10m个样本的梯度下降》Gradient descent on m examples

《2.11向量化》Vectorization

《2.12向量化的更多例子》More Vectorization Examples

《2.13向量化logistic回归》Vectorizing Logistic Regression

《2.14向量化logistic回归的梯度输出》Vectorizing Logistic Regression’s Gradient Output

《2.15python中的广播》Broadcasting in Python

《2.16关于python numpy 向量的说明》A note on python/numpy vectors

《2.17Jupyter Ipython笔记本的快速指南》Quick tour of Jupyter/iPython Notebooks

《2.18(选修)logistic成本函数的解释》explanation of logistic regression cost function(optional)

课程小结(Summary)

《2.1二分分类》Binary Classification

1.m个训练集的数据训练时并不是for循环进行。

2.神经网络的两个传播:正向传播和负向传播。

logistic回归是一个用于二分类(Binary Classification)的算法。二分类就是输出结果y只有0和1两个标签(也有-1和1的情况)。以一个图像识别为例,例如识别猫,1代表猫,0代表不是猫。用y表示输出的结果标签。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第1张图片

下面主要通过这个例子简要介绍神经网络模型中的一些标准化的、有效率的处理方法和概念。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第2张图片

如上图所示,这是经典的二分类问题。一般来说,彩色图片包含RGB三个通道,在计算机中保存一张图片,要保存三个独立矩阵,分别对应图片中的红、绿和蓝三个颜色通道。如果输入的图片是64*64像素的,就会有3个64*64的矩阵,分别对应图片中的红绿蓝三种像素的亮度。要把这些像素亮度值放进一个特征向量中,就要把这些像素值都提出来,放入一个特征向量(feature vector)x。(按照通道的顺序排列下来,如上图的X)如果图片是64*64的,那么向量x的总维度就是64*64*3,因为这是三个矩阵的元素数量,为12288。用n_x=12288来表示输入的特征向量x(列向量)的维度,为了简写用小写n代替。

在二分类问题中,目标是训练一个分类器,它以图片的特征向量x为输入,预测输出的结果标签y是0还是1。

一些符号:

用一对(x,y)表示一个单独的样本,其中x是n_x维的特征向量,y为0或者1。训练集大小为m。train为训练集,test为测试集。

定义一个矩阵X,矩阵有m列,n_x行,这里矩阵X的行n_x代表了每个样本x的特征个数,列m代表了样本个数。有时候矩阵X的定义是训练样本作为行向量堆叠,而不是这样列向量堆叠。在神经网络中,一般用列向量。X是一个n_x*m的矩阵。当你用python 实现时,X.shape=(n_x,m)

Y是一个1*m的矩阵,同样Y.shape=(1,m)。

《2.2logistic回归》Logistic Regression

接下来我们介绍如何使用逻辑回归来解决二分类问题。逻辑回归中,

表示y为1的概率,取值范围是(0,1)之间。

已知的特征输入向量x可能是n_x维度,logistic回归的参数w也是n_x维的向量,而b就是一个实数。所以已知输入x和参数w和b,我们如何计算输出预测y帽?y帽是预测的概率,应该介于0-1之间。这是其与二分类模型不同的地方。使用线性模型,引入参数w和b。权数w的维度是n_x,b是一个常数项。然后逻辑回归的线性预测输出可以写成如下格式:

值得注意的是,在很多其他机器学习资料中,可能把常数b当做w0处理,并引入x0=1。这样从维度来看,x和w都会增加一维。但是在本课程中,为了简化计算和便于理解,Andrew建议使用上式的形式,将w和b分开比较好。

注意到上式的线性输出区间为整个实数范围,而逻辑回归要求输出范围在[0,1]之间,所以需要进行转换。引入Sigmiod函数,让输出限定在[0,1]之间。

Sigmiod函数是一种非线性的S型函数,输出范围是[0,1],通常在神经网络中当激活函数(Activation function)。表达式和曲线如下:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第3张图片

从曲线可以看出,当z很大时,函数值趋于1;当z很小时,函数值趋于0;且当z=0时,函数值为0.5。注意,Sigmoid函数的一阶导数可以用自身表示:

证明过程如下:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第4张图片

这样,逻辑回归的预测输出就可以完整写成下式,输出装换为[0,1]之间:

Andrew建议实际情况中,当你实现你的神经网络参数时,将b和w看做独立的参数可能更好。

《2.3logistic回归损失函数》Logistic Regression Cost Function

逻辑回归中,w和b都是未知参数,需要反复训练优化得的。为了训练logistic回归模型的参数w以及b,需要定义一个成本函数(cost function)。为了让模型通过学习调整参数,要给一个m个样本的训练集,很自然地,你想通过在训练集找到参数w和b,来得到你的输出。

对于m个训练样本,我们通常使用上标来表示对应的样本。例如(表示第i个样本):

如何定义所有m个样本的cost function呢?先从单个样本出发,我们希望该样本的预测值与实际值越相似越好。

Loss(error) function:损失函数(误差函数),可以用来衡量算法的运行情况。你可以定义损失函数为y帽和y的差的平方,或者它们差的平方的1/2。结果表明你可以这样做,但通常在logistic回归中,大家都不这么做,因为当你学习这些参数的时候,你会发现之后讨论的优化问题,会变成非凸的,最后会得到很多个局部最优解,梯度下降法可能找不到全局最优解。这个的直观理解就是我们通过定义这个损失函数L来衡量你的预测输出值y帽和y的实际值有多接近。误差平方,似乎是个不错的选择,但用这个的话,梯度下降法就不太好用。因此我们选择的损失函数一般是凸的,另一个函数定义如下:

在logistic回归中,我们会定义一个不同的损失函数它有和误差平方相似的作用,这些会给我们一个凸的优化问题。一般而言,我们偏向研究凸函数问题。

对于这个损失函数,我们也想让它尽可能的小。

例子:

(1)y=1时,L= - log(y^)想要足够小,y^就要足够大,最大最大不能超过1。

(2)y=0时,L=- log(1-y^)想要足够小,(1-y^)要足够大,y^就要足够小,最小不能小于0。

有很多函数都能达到这个效果:如果y=1,我们尽可能让y^很大;如果y=0,尽可能让y^很小。以上两个例子就解释了为什么用这个作为损失函数。(后面的选修视频会给出更正式的原因)

说明:损失函数是在单个训练样本中定义的,它衡量了在单个训练样本上的表现。

下面定义一个成本函数,它衡量的是在全体训练样本上的表现。成本函数J是根据之前得到的两个参数w和b,J(w,b)=损失函数求和/m.,即所有m个训练样本的损失函数和的平均。

成本函数(cost function)是关于未知参数w和b的函数,我们的目标是在训练模型时,要找到合适的w和b,让成本函数J尽可能的小。

结果表明,logistic回归可以看成是一个非常小的神经网络。下一个视频,我们将直观地了解神经网络能做什么。

《2.4梯度下降法》Gradient Descent

上一个视频中,损失函数是衡量单一训练样例的效果,成本函数用来衡量在全部训练集上参数w和b的效果。下面我们讨论如何使用梯度下降法来训练或学习训练集上的参数w和b。

回顾一下,这里使我们熟悉的logistic回归函数

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第5张图片

我们希望找到使成本函数J(w,b)尽可能小的w和b。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第6张图片

凸函数(convex function)的局部优化特性是logistic回归使用这个成本函数J的重要原因之一。使用梯度下降法很快地收敛到局部最优解或者全局最优解。

通过上式不断的更新迭代w。(微积分中的导数)

由于J(w,b)是凸函数,梯度下降算法(Gradient Descent)是先随机选组一组参数w和b值,然后每次迭代的过程中分别沿着w和b的梯度(偏导数)的反方向前进一小步,不断修正w和b。每次迭代更新w和b后,都能让J(w,b)更接近全局最小值。梯度下降的过程如下图所示。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第7张图片

梯度下降算法每次迭代更新,w和b的修正表达式为:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第8张图片

其中,alpha是学习因子(learning rate),表示梯度下降的步进长度,其值越大,w和b每次更新的“步伐”更大一些;越小,更新“步伐”更小一些。在程序代码中,我们通常使用dw来表示。

通常使用dw表示∂J(w,b)/∂w,用db表示∂J(w,b)/∂b。一般而言,在微积分中df/dx表示对单一变量求导数,∂f/∂x对多个变量中某个变量求偏导数。梯度下降算法能够保证每次迭代w和b都能向着J(w,b)全局最小化的方向进行。其数学原理主要是运用泰勒一阶展开来证明的。

《2.5导数》Derivatives

如果你是精通微积分的同学,你可以跳过这个视频。

在这个视频中,主要对微积分和导数有直观的理解。不论毕业了多久,请不要担心,你并不需要对非常深入理解微积分,就能高效应用神经网络和深度学习。如果你想要了解这些知识,Andrew建议:坚持学习视频,最好做好课后作业,成功完成编程作业,就能应用深度学习了。在第4周,将会定义很多种类的函数类型,它们能够帮助你通过微积分,把所有需要的知识结合起来,其中有“正向函数”、“反向函数”。你不需要了解很多微积分去使用这些函数,因此,你不需要担心它们超出理解范围,但在深度学习中,我将进一步深入了解微积分的细节,你只需要直观理解微积分,就可以构建和成功应用这些算法。如果你是精通微积分的同学,你可以跳过这个视频。

导数可以看成斜率。对于直线而言,函数中的斜率在任何地方都是一样的,例如f(a)=3a中为3。在下一个视频中,我们会看一个更复杂的例子。

这一部分的内容非常简单,Andrew主要是给对微积分、求导数不太清楚的同学介绍的。梯度或者导数一定程度上可以看成是斜率。关于求导数的方法这里就不再赘述了。

《2.6更多导数的例子》More Derivative Examples

下面我们看一下函数在不同点的斜率是不一样的,例如二次函数f(a)=a^2为2a。

Andrew给出了更加复杂的求导数的例子,略。

《2.7计算图》 Computation graph

可以说一个神经网络的计算过程是通过正向传播(Forward Propagation)反向传播(Back Propagation)过程来实现的,首先计算出神经网络的输出,紧接着进行一个反向传输操作,后者我们用来计算出对应的梯度或者函数。下面这个计算图(Computation graph)解释了为什么用这样的方式实现。

举个简单的例子,假如损失函数(Cost function)为J(a,b,c) = 3(a+bc),包含a,b,c三个变量。我们用u表示bc,v表示a+u,则J=3v。它的计算图可以写成如下图所示:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第9张图片

令a=5,b=3,c=2,则u=bc=6,v=a+u=11,J=3v=33。计算图中,这种从左到右,从输入到输出的过程就对应着神经网络或者逻辑回归中输入与权重经过运算计算得到Cost function的正向过程。

《2.8计算图的导数计算》 Derivatives with a Computation Graph

上一部分介绍的是计算图的正向传播(Forward Propagation),下面我们来介绍其反向传播(Back Propagation),即计算输出对输入的偏导数。

还是上个计算图的例子,输入参数有3个,分别是a,b,c。(链式法则)

首先计算J对参数a的偏导数。从计算图上来看,从右到左,J是v的函数,v是a的函数。则利用求导技巧,可以得到:

根据这种思想,然后计算J对参数b的偏导数。从计算图上来看,从右到左,J是v的函数,v是u的函数,u是b的函数。可以推导:

最后计算J对参数c的偏导数。仍从计算图上来看,从右到左,J是v的函数,v是u的函数,u是c的函数。可以推导:

为了统一格式,当你编程的时候,在代码里,我们使用dvar来表示导数,例如da,db,dc来表示J对参数a,b,c的偏导数。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第10张图片

《2.9logistic回归中的梯度下降》Logistic Regression Gradient Descent

现在,我们将对逻辑回归进行梯度计算。对单个样本而言,逻辑回归损失函数(Loss function)表达式如下:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第11张图片

首先,该逻辑回归的正向传播过程非常简单。根据上述公式,例如输入样本x有两个特征(x1,x2),相应的权重w维度也是2,即(w1,w2)。则z=w1x1+w2x2+b,最后的Loss function如下所示:recap(概述、简要回顾)

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第12张图片

然后,计算该逻辑回归的反向传播过程,即由损失函数(Loss function)计算参数w和b的偏导数。推导过程如下:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第13张图片

知道了dz之后,就可以直接对w1,w2和b进行求导了。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第14张图片

则梯度下降算法可表示为:

更新w1为w1减去学习率乘以dw1;更新w2为w2减去学习率乘以dw2;更新b为b减去学习率乘以db。这就是单个样本实例的一次梯度更新步骤。但是训练logistic模型时不仅仅是一个样本,而是有m个训练样本的训练集。下一个视频中蒋介绍如何应用在整个训练样本中。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第15张图片

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第16张图片

《2.10m个样本的梯度下降》Gradient descent on m examples

上一部分讲的是对单个样本求偏导和梯度下降。首先,时刻记住成本函数(Cost function)的定义,说如果有m个样本,其成本函数表达式如下:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第17张图片

Cost function关于w和b的偏导数可以写成和平均的形式:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第18张图片

这样,每次迭代中w和b的梯度有m个训练样本计算平均值得到。其算法流程图如下所示:(下个视频细讲)

#1.初始化
J=0; dw1=0; dw2=0; db=0;
#2.for循环遍历训练集,并且计算相应的每个训练样本的导数
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);#n=2,两个特征w1,w2
    db += dz(i);
#3.最终对所有的m个训练样本都进行了这个计算,你还需要除以m,计算平均值
J /= m;
dw1 /= m;
dw2 /= m;
db /= m;

经过每次迭代后,根据梯度下降算法,w和b都进行更新:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第19张图片

这样经过n次迭代后,整个梯度下降算法就完成了。

在上述的梯度下降算法中,我们是利用for循环对每个样本进行dw1,dw2和db的累加计算最后再求平均数的。你会发现,在神经网络中显式地使用for循环会使算法很低效。在深度学习中会有越来越大的数据集,所以,应用你的算法完全不适用显式for循环的话,会帮助你处理更大的数据集。有一门向量化的技术可帮助你的代码摆脱这种显示for循环:向量化(vectorization)

《2.11向量化》Vectorization

在深度学习安全领域、深度学习练习中,你经常发现在训练大量数据时,深度学习算法表现才更加优越,所以你的代码运行的非常快至关重要,否则,你将要等待非常长的时间去得到结果。所以在深度学习领域向量化是一个关键技巧。

什么是向量化?

在logistic回归中,

import numpy as np

a = np.array([1,2,3,4])
print(a)

#[1 2 3 4]
import time 
a = np.random.rand(1000000)
b = np.random.rand(1000000)

tic = time.time()
c = np.dot(a,b)
toc = time.time()

print(c)
print("Vectorized version:" + str(1000*(toc-tic)) + "ms")

c = 0
tic = time.time()
for i in range(1000000):
    c += a[i]*b[i]
toc = time.time()

print(c)
print("For loop version:" + str(1000*(toc-tic)) + "ms")

#249866.84361136454
#Vectorized version:1.9810199737548828ms
#249866.8436113724
#For loop version:531.0003757476807ms

上述运行结果看出向量化之后,运行速度会大幅上升,该例子使用for循环运行时间是使用向量计算运行时间的200多倍。

你可能听说过可扩展深度学习实现是在GPU上做的,GPU(graphics processing unit)也叫图像处理单元,但我们做的所有案例都在jupyter notebook上面实现,这里只有CPU。CPU和GPU都有并行化(parallelization)的指令,有时候也会叫SIMD(Single Instruction Multiple Data)指令,意思是单指令流多数据流,这个词的意思是如果你使用了这样的内置函数,np.function或者其他能让你去掉显式for循环的函数,这样python的numpy能够充分利用并行化去更快的计算,大大提高程序运行速度。这点对GPU和CPU上计算都是成立的。但相对而言,GPU更擅长SIMD计算,但CPU事实上也不是太差。

《2.12向量化的更多例子》More Vectorization Examples

上个视频中,我们看到使用内置函数,可以避免显示for循环,可以让程序运行速度显著加快。下面我们再看几个例子。

要记住,经验法则是当你编写新的网络时,或者你做的只是回归,那么一定要尽量避免for循环,能不用就不用。如果你可以使用内置函数,或者找出其他方法去计算循环,通常会比直接用for循环更快。

(1)已经矩阵A和向量v,想求乘积,我们通常使用u = np.dot(A,v)函数来进行矩阵乘积。(涉及python的numpy库)

(2)已经向量v,想做指数运算,作用到向量v的每一个元素。使用u = np.exp(v),v作为输入向量,u作为输出向量。这样代码会快很多。

实际上,numpy库有很多向量值函数,例如np.log()会逐个元素计算log;np.abs()会计算绝对值;np.maxinum计算所有元素中的最大值;v**就是v中每个元素的平方;1/v就是每个元素求倒数。所以当你想使用for循环时,应该看看可不可以调用numpy的内置函数。下面我们看看这些函数怎么应用到logistic回归梯度下降算法实现中来。

#1.初始化
J=0; dw1=0; dw2=0; db=0;
#2.for循环遍历训练集,并且计算相应的每个训练样本的导数
#循环1
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);
    #循环2  for j = 1 to n_x
    dw1 += x1(i)dz(i);
    dw2 += x2(i)dz(i);#n_x=2,两个特征w1,w2
    db += dz(i);
#3.最终对所有的m个训练样本都进行了这个计算,你还需要除以m,计算平均值
J /= m;
dw1 /= m;
dw2 /= m;
db /= m;12345678910111213
J = 0,dw = np.zeros(n_x,1)
#上面代码的11,12行改为:
dw += X(i)dz(i)
#上面代码的16,17行改为:
dw /=m
#现在值剩下一个循环,对单独的训练例子循环

下一个视频我们将学习不使用任何循环处理logistic模型。

《2.13向量化logistic回归》Vectorizing Logistic Regression

让我们先回顾logistic回归的正向传播步骤,如果你有m个训练样本,那么对第一个样本预测你需要这样计算:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第20张图片

以此类推,你需要做m次。结果表明要进行正向传播,需要对m个训练样本都计算预测结果。有一个方法不使用for循环也能做到。

首先,我们曾定义过一个矩阵X来作为你的训练输入,这是一个n_x * m的矩阵,维度是(n_x,m)。先构建一个1*m的矩阵Z来作为你的训练输出,w^T是一个1*n_x的矩阵,转置之后的维度是(1,n_x)。b是一个常数值,维度为(1,m)。

在python中表示为:

import numpy as np
Z = np.dot(w.T,X) + b  #w.T表示w的转置,b为1*1,Z为1*m矩阵
#python中自动扩展为一个1*m的行向量,这个操作在python中叫做广播(broadcasting)
A = sigmoid(Z)

同样构建Sigmiod函数,用小写sigma同时计算所有小写的a。这就是正向传播同时处理所有m个训练样本的一步迭代的向量化实现。这样可以对所有m个样本同时运算,大大提高了运算速度。接下来你会发现同样可以用向量化来高效地计算反向传播,并以此来计算梯度。

《2.14向量化logistic回归的梯度输出》Vectorizing Logistic Regression’s Gradient Output

回归之前的讲解,我们有:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第21张图片

我们已经去掉了一个循环,此时仍有一个遍历训练集的循环,回顾之前的操作,我们使用dw=0将dw初始化为0向量

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第22张图片

在这里,db也可以写成

对应的代码为:

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

那么dw呢?我们先写出公式:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第23张图片

对应代码为:

dw = 1/m*np.dot(X,dZ.T)

我们把整个logistic回归向量化,for循环尽可能用矩阵运算代替,对于单次迭代,梯度下降算法流程如下所示:

Z = np.dot(w.T,X) + b
A = sigmoid(Z)
dZ = A-Y
dw = 1/m*np.dot(X,dZ.T)
db = 1/m*np.sum(dZ)

w = w - alpha*dw
b = b - alpha*db

其中,alpha是学习因子,决定w和b的更新速度。上述代码只是对单次训练更新而言的,外层还需要一个for循环,表示迭代次数。Andrew认为该层循环应该没有方式把它去掉。

《2.15python中的广播》Broadcasting in Python

广播(broadcasting )是一种手段,可以让你的代码更快。

下面列表是不同食物(每100g)中不同营养成分的卡路里含量表格,表格为3行4列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。那么,我们现在想要计算不同食物中不同营养成分中的卡路里百分比。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第24张图片

现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和 56+1.2+1.8=59,然后用56/59=94.9%算出结果。对于其他食物,计算方法类似。

import numpy as np
A = np.array([[56.0,0.0,4.4,68.0],
             [1.2,104.0,52.0,8.0],
             [1.8,135.0,99.0,0.9]])

print(A)

#[[ 56.    0.    4.4  68. ]
# [  1.2 104.   52.    8. ]
# [  1.8 135.   99.    0.9]]

cal = A.sum(axis=0) #axis=0意味着竖直轴相加,而水平轴是1
print(cal)

#[ 59.  239.  155.4  76.9]
 
percentage = 100*A/cal.reshape(1,4) #其实也可以不调用reshape(),但是使用会更保险,时间复杂度为o(1),调用成本极低
print(percentage)
#[[94.91525424  0.          2.83140283 88.42652796]
# [ 2.03389831 43.51464435 33.46203346 10.40312094]
# [ 3.05084746 56.48535565 63.70656371  1.17035111]]

我们再来看看几个广播的例子:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第25张图片

大体原则:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第26张图片

计算方法如上图,python中可以对不同维度的矩阵进行四则混合运算,但至少保证有一个维度是相同的。其实很简单,如:(m,n)与(1,n)进行运算,就是把(1,n)复制m次,变成(m,n)后再进行运算。其它的类似。(非常厉害的MATLAB和Octave用户用用到bsxfun)

Andrew建议:在python程序中为了保证矩阵运算正确,可以使用reshape()函数来对矩阵设定所需的维度。这是一个很好且有用的习惯。

《2.16关于python numpy 向量的说明》A note on python/numpy vectors

python可以使用广播运算,一般来说,python的numpy程序语言给你提供了很高的灵活性,这是一门编程语言的优势(strength),同时也是弱势(weakness)。Andrew认为是一种优势,因为它让语言的表现力更强,语言的灵活性很大,但是也有弱点,因为广播和这么大的灵活性,有时可能出现非常细微的错误和bug。下面将分享一些技巧。

import numpy as np a = np.random.randn(5) 
#生成5个随机高斯变量,储存在数组a中

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第27张图片

上述语句生成的a的维度是(5,),这是所谓的python中秩为1的数组,称为rank 1 array,它既不是行向量也不是列向量,这导致它有一些略微不直观的效果。

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第28张图片

Andrew建议当你在编写神经网络程序时,就不要用这种数据结构。

如果我们要定义(5,1)的列向量,最好使用下面代码:

a = np.random.randn(5,1) print(a)

#[[-1.04511918] [-0.74705054] [-0.53671784] [ 0.66077854] [ 1.57372222]]

我们输出一下此时的转置和內积:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第29张图片

除此之外,我们还可以使用assert语句对向量或数组的维度进行判断:

assert(a.shape == (5,1)) 
#执行起来很快,也可以看成是代码的文档

assert会对内嵌语句进行判断,即判断a的维度是不是(5,1)的。如果不是,则程序在此处停止。使用assert语句也是一种很好的习惯,能够帮助我们及时检查、发现语句是否正确。

当然,如果你得到了一个“rank 1 array”,可以用reshape转换成5*1数组:

a.reshape((5,1))

《2.17Jupyter Ipython笔记本的快速指南》Quick tour of Jupyter/iPython Notebooks

Jupyter notebook(又称IPython notebook)是一个交互式的笔记本,支持运行超过40种编程语言。本课程所有的编程练习题都将在Jupyter notebook上进行,使用的语言是python。输入Shift+Enter执行代码块。当看到内核卡死时,你可以尝试重启内核。

推荐教程:https://hub.packtpub.com/getting-started-jupyter-notebook-part-1/

《2.18(选修)logistic成本函数的解释》explanation of logistic regression cost function(optional)

之前我们介绍了logistic回归的成本函数,下面我们来说明成本函数的表达式为什么是这种形式?

首先,预测输出y帽可以写成:

1-2 Coursera吴恩达《神经网络与深度学习》第二周课程笔记-神经网络基础_第30张图片

y帽可以看成是给定训练样本x条件下y=1的概率:

那么,当y=1时:

当y=0时,

把两个式子整合到一个式子中,得到:

由于log函数严格单调递增,等式两边同时取log:

我们希望上述概率P越大越好,加上负号就是单个成本的损失函数,我们希望越小越好,这与之前介绍的一致,如下式:

假设所有m个训练样本服从同一分布且相互独立,也即独立同分布。所有这些样本的联合概率就是每个样本概率的乘积(极大似然概率)。我们希望总的概率越大越好:

引入log函数,加上负号,上式转换为成本函数:

其中,1/m表示对m个样本的损失函数求平均,为缩放因子。

课程小结(Summary)

本节课的内容比较简单,主要介绍了神经网络的基础——逻辑回归和神经网络基础——梯度下降算法和向量化。首先,我们介绍了二分类问题,以图片为例,将多维输入x转化为特征向量,输出y只有{0,1}两个离散值。接着,我们介绍了逻辑回归及其对应的成本函数形式。然后,我们介绍了梯度下降算法,并使用计算图的方式来讲述神经网络的正向传播和反向传播两个过程。我们在逻辑回归中使用梯度下降算法,总结出最优化参数w和b的算法流程。最后我们主要介绍了在深度学习程序中,使用向量化和矩阵运算的方法能够大大提高运行速度,节省时间。以逻辑回归为例,我们将其算法流程包括梯度下降转换为向量化的形式。同时,我们也介绍了python的相关编程方法和技巧。

说明:记录学习笔记,如果错误欢迎指正!转载请联系我。

你可能感兴趣的:(吴恩达深度学习笔记,笔记,AI,神经网络,算法,python,机器学习,深度学习)