一、简单的介绍:
深度学习指的是训练神经网络,
假设你有一个数据集,它包含了六栋房子的信息。所以,你知道房屋的面积是多少平方英尺或者平方米,并且知道房屋价格。这时,你想要拟合一个根据房屋面积预测房价的函数。
如果你对线性回归很熟悉,你可能会说:“好吧,让我们用这些数据拟合一条直线。”于是你可能会得到这样一条直线。
输入x 经过神经网络实现生成y这就是一个简单的神经网络
将这些独立的神经元叠在一起变成了一个预测器
同时可以用神经网络进行监督学习,从历史经验上看,处理非结构化数据是很难的,与结构化数据比较,让计算机理解非结构化数据很难,而人类进化得非常善于理解音频信号和图像,文本是一个更近代的发明,但是人们真的很擅长解读非结构化数据。循环神经网络非常适合处理一些一维序列数据其中包含时间部分,结构化数据意味着每个特征都有清楚的定义,非结构数据比如音频,这里的特征可能是图像的像素值,使计算机更难理解。因为神经网络深度学习的存在使计算机能够更好理解非结构数据。为什么深度学习会兴起,多亏了数字化社会是的处理海量数据,在很多应用中收集到了大量的数据,在时代的发展中,深度学习一步一步发展,实现大规模的神经网络研究算法的能力也在增强。下图是一张简单的神经网络结构图,有关于房地产的。
二、神经网络基础
二次分类
神经网络的计算过程可以有正向传播和反向传播,logistic回归是一个用于二分分类的算法,定义一个矩阵有输入x构成,用Python来输出则是Y.shape =(1,m),X.shape =(nx,m)m为行,nx为列。
用一对(x,y)表示一个独立的样本,直至m个,定义一个矩阵X使得元素更为紧凑,使其包含x
同理定义一个Y矩阵使得y更为紧凑
logistics回归
是一个学习算法,一直输入x,和参数b,w,输入x的线性函数,最终得出y,logistics损失函数可以衡量算法的运算情况,直观理解就是我们运用这个函数来衡量你的预测输出值y和实际输出值y有多接近,我们会使这个函数尽可能得小,,损失函数让y帽尽可能得小,因为y帽只能介于0到1之间,y帽通过一系列参数,运用logistic函数算出预测值,损失函数只用与单独的单个训练样本,所以在训练模型时我们要找到合适的参数w,j,且成本函数要尽可能得小,结果表明logistic函数可以是一个很小的神经网络。
对于二元分类问题来讲,给定一个输入特征向量 X ,它可能对应一张图片,你想识别这张图片
一个算法能够输出预测,但只能称为y^,也就是对实际y的估计。
输入一个x的线性函数,y在0到1之间,y^的输出等于上面式子作为自变量的sigmoid函数图像
如果把水平轴作为z轴,那么如图所示,我们通常都使用 z 来表示 wTx+b 的值。
有一个参数,能够将w和b分开的 σ 参数,但目前暂时用不到。
梯度下降法
成本函数衡量了参数的效果,而梯度下降法中,为了找到更好的参数值,我们需要优化参数w,b,梯度下降法所做的就是从初始点开始朝最陡的下坡方向走一步,梯度下降法:不断地更新w,在算法收敛之前,当我们开始写代码编写梯度下降量时,我们会使用代码中的量名约定,在你测试集上,通过最小化代价函数(成本函数) J ( w , b ) 来训练的参数 w 和 b 。
梯度下降法的形象化说明
这个图中,横轴表示你的空间参数 w 和 b ,在实践中, w 可以是更高的维度,但是为了更好地绘图,我们定义 w 和 b ,都是单一实数,代价函数(成本函数)J(w,b)是在水平轴 w 和 b 上的曲面,因此曲面的高度就是 J ( w , b ) 在某一点的函数值。我们所做的就是找到使得代价函数(成本函数) J ( w , b ) 函数值是最小值,对应的参数 w 和 b 。逻辑回归的代价函数(成本函数) J ( w ,b)有两个参数的。∂ 表示求偏导符号,可以读作round。至于导数就不用细细讲了。
计算图
可以说,一个神经网络的计算,都是按照前向或反向传播过程组织的。首先我们计算出一个新的网络的输出(前向过程),紧接着进行一个反向传输操作。后者我们用来计算出对应的梯度或导数。计算图解释了为什么我们用这种方式组织这些计算过程。在这个视频中,我们将举一个例子说明计算图是什么。让我们举一个比逻辑回归更加简单的,或者说不那么正式的神经网络的例子。
J是由a,b,c三个变量组成的函数,这个函数是3(a+bc),当然如图所示经过一系列计算步骤,当有不同的或者一些特殊的输出变量时,例如本例中的 J 和逻辑回归中你想优化的代价函数 J ,因此计算图用来处理这些计算会很方便。从这个小例子中我们可以看出,通过一个从左向右的过程,你可以计算出的 J 值。为了计算导数,从右到左(红色箭头,和蓝色箭头的过程相反)的过程是用于计算导数最自然的方式。 概括一下:计算图组织计算的形式是用蓝色箭头从左到右的计算。
下面用到的公式:
这是一个计算图导数计算的流程图·:
要计算dj/dv,可以使用反向计算法,在反向传播算法中的术语,我们看到,如果你想计算最后输出变量的导数,使用你最关心的变量对的导数,那么我们就做完了一步反向传播,在这个流程图中是一个反向步骤。
现在我想介绍一个新的符号约定,当你编程实现反向传播时,通常会有一个最终输出值是你要关心的,最终的输出变量,你真正想要关心或者说优化的。在这种情况下最终的输出变量是 J JJ ,就是流程图里最后一个符号,所以有很多计算尝试计算输出变量的导数,所以输出变量对某个变量的导数,我们就用 d v a r dvardvar 命名,所以在很多计算中你需要计算最终输出结果的导数,在这个例子里是 J JJ ,还有各种中间变量,比如 a 、 b 、 c 、 u 、 v ,当你在软件里实现的时候,变量名叫什么?你可以做的一件事是,在python中,你可以写一个很长的变量名,比如 FinalOutputvar_dvar ,但这个变量名有点长,我们就用 dJ_dvar ,但因为你一直对dJ 求导,对这个最终输出变量求导。我这里要介绍一个新符号,在程序里,当你编程的时候,在代码里,我们就使用变量名 dvar ,来表示那个量。
所以在程序里是dvar 表示导数,你关心的最终变量 J 的导数,有时最后是 L ,对代码中各种中间量的导数,所以代码里这个东西,你用 d v dvdv 表示这个值,所以 dv=3 ,你的代码表示就是da=3 。
logistics回归中的梯度下降法
通过计算偏导数来实现逻辑回归的梯度下降算法。它的关键点是几个重要公式,其作用是用来实现逻辑回归中梯度下降算法。以下为logistics回归的几个计算公式。
如果遇到m个样本的logistics回归梯度下降呢?
首先,让我们时刻记住有关于损失函数 J(w,b) 的定义。
当你的算法输出关于样本 y的a(i),a(i)是训练样本的预测值,即: σ ( z ( i ) ) = σ ( w T x ( i ) + 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循环的艺术,在深度学习安全领域、深度学习实践中,你会经常发现自己训练大数据集,因为深度学习算法处理大数据集效果很棒,所以你的代码运行速度非常重要,否则如果在大数据集上,你的代码可能花费很长时间去运行,你将要等待非常长的时间去得到结果。所以在深度学习领域,运行向量化是一个关键的技巧,让我们举个例子说明什么是向量化。
在不使用向量化的时候,python中代码输出如图所示:
x
z=0
for i in range(n_x)
z+=w[i]*x[i]
z+=b
这相比于向量化来说是非常慢了,输入z=np.dot(w,x)+b即可很大地提高速度。接下来可以用jupyter notebook来演示一下。
总结一下,在向量化方法和for语句的比较下,输出同种结果,向量化方法使用的时间远小于for语句使用的时间。当然向量化也有更多的例子,这里就不一一列举了。当把向量化运用到logistics回归中时,用一串代码即可解决问题。Z = np.dot(w.T,X) + b
显然,单单使用for循环是很慢的当运用向量化时
python中的广播
通过水果的形式举个例子 ,在jupyter notebook中输入以下代码,可以分别求出各个水果的营养成分占比。
下面使用如下代码计算每列的和,可以看到输出是每种食物(100g)的卡路里总和。
其中sum的参数axis=0表示求和运算按列执行其中sum的参数axis=0表示求和运算按列执行,接下来计算百分比,这条指令将 3 ∗ 4的矩阵 A 除以一个 1 ∗ 4 的矩阵,得到了一个 3 ∗ 4 的结果矩阵,这个结果矩阵就是我们要求的百分比含量。
关于python中numpy向量的说明
Python语言巨大的灵活性使得你仅仅通过一行代码就能做很多事情。但是这也是缺点,由于广播巨大的灵活性,有时候你对于广播的特点以及广播的工作原理这些细节不熟悉的话,你可能会产生很细微或者看起来很奇怪的bug。例如,如果你将一个列向量添加到一个行向量中,你会以为它报出维度不匹配或类型错误之类的错误,但是实际上你会得到一个行向量和列向量的求和。
首先设置 a=np.random.randn(5) ,这样会生成存储在数组 a 中的5个高斯随机数变量。之后输出 a ,从屏幕上可以得知,此时 a 的shape(形状)是一个 (5,) 的结构。这在Python中被称作一个一维数组。它既不是一个行向量也不是一个列向量,这也导致它有一些不是很直观的效果。举个例子,如果我输出一个转置阵,最终结果它会和 a 看起来一样,所以 a 和 a 的转置阵最终结果看起来一样。而如果我输出 a 和 a 的转置阵的内积,你可能会想: a 乘以 a的转置返回给你的可能会是一个矩阵。但是如果我这样做,你只会得到一个数。
相反,如果你设置 a 为 ( 5 , 1 ) ,那么这就将置于5行1列向量中。在先前的操作里 a 和 a 的转置看起来一样,而现在这样的 a 变成一个新的 a 的转置,并且它是一个行向量。请注意一个细微的差别,在这种数据结构中,当我们输出 a 的转置时有两对方括号,而之前只有一对方括号,所以这就是1行5列的矩阵和一维数组的差别。
如果你输出 a 和 a 的转置的乘积,然后会返回给你一个向量的外积,是吧?所以这两个向量的外积返回给你的是一个矩阵。
至于jupyter notebook则就交给大家了。



