深度学习入门笔记(一)

深度学习引言

ReLU激活函数

Rectified Linear Unit[1]

单神经元网络-> 多个单神经元叠加

在图上每一个画的小圆圈都可以是ReLU的一部分,也就是指修正线性单元,或者其它稍微非线性的函数

  • 输入层和中间层被紧密的连接
  • 隐藏单元圆圈,在一个神经网络中,它们每个都从输入的四个特征获得自身输入

神经网络非常擅长计算从x到y的精准映射函数

神经网络的监督学习

现在的大多数神经网络都离不开监督学习

扩展

对于图像应用,我们经常在神经网络上使用卷积(Convolutional Neural Network),通常缩写为CNN。对于序列数据,例如音频,有一个时间组件,随着时间的推移,音频被播放出来,所以音频是最自然的表现。作为一维时间序列(两种英文说法one-dimensional time series / temporal sequence).对于序列数据,经常使用RNN,一种递归神经网络(Recurrent Neural Network),语言,英语和汉语字母表或单词都是逐个出现的,所以语言也是最自然的序列数据,因此更复杂的RNNs版本经常用于这些应用

一个标准的神经网络:

一个卷积神经网络的例子:

结构化数据与非结构化数据

与结构化数据比较[2],通常让计算机理解非结构化数据很难

多亏了深度学习和神经网络,计算机现在能更好地解释非结构化数据

神经网络算法对于结构化和非结构化数据都有用处

为什么兴起

数据量增大

仅仅在过去的20年里对于很多应用,我们便收集到了大量的数据,远超过机器学习算法能够高效发挥它们优势的规模

而随着数据集规模的增大,神经网络的优势会越发的明显

算法方面的创新

例子,sigmoid函数转换到ReLU函数

sigmoid: 梯度接近零的时候,参数会更新的很慢,所以学习的速率也会变的很慢

仅仅通过将Sigmod函数转换成ReLU函数,便能够使得一个叫做梯度下降(gradient descent)的算法运行的更快

神经网络的编程基础

本节学习神经网络的基础知识:

  • 学会如何处理训练集
  • 学习前向传播和反向传播

逻辑回归是一个用于二分类(binary classification)的算法
二分类的目标就是习得一个分类器,它以图片的特征向量作为输入,然后预测输出结果为1还是0

本节将使用逻辑回归(logistic regression)来传达这些升级网络的基础知识与想法

符号定义

  • xx:表示一个nxn_x维数据,为输入数据,维度为(nx,1)(n_x,1)
  • y​:表示输出结果
  • (x(i),y(i))(x^{(i)},y^{(i)}):第ii组数据
  • X=[x(1),x(2),...,x(m)]X=[x^{(1)},x^{(2)},...,x^{(m)}]:所有的训练数据集的输入值,维度nx×mn_x \times m,其中mm为样本数目;
  • Y=[y(1),y(2),...,y(m)]Y=[y^{(1)},y^{(2)},...,y^{(m)}]:所有训练数据集的输出值,维度为1×m1\times m
  • MtrainM_{train}训练集,MtestM_{test}测试集

一般在实现神经网络的时候,数据按照列排

逻辑回归引入

sigmoid函数: σ(z)=11+ez\sigma \left(z\right) = \frac{1}{1+{ e^{-z} }},在这里zz为实数自变量

我们可以用sigmoid函数将线性函数转为值域在[0,1]之间的非线性函数[3]

显然实数z越大可以使得sigmoid函数更容易趋近于1

当你实现逻辑回归时,你的工作就是去让机器学习去调节z函数的参数,使得预测结果y^\hat{y}成为对这二分类的概率为一个很好的估计

损失函数与代价函数

为了让机器学习去调节z函数的参数,使得预测结果y^\hat{y}成为对这二分类的概率为一个很好的估计

我们需要一个代价函数[4]来实现这一点

而在此之前,让我们从损失函数开始

损失函数又叫做误差函数,用来衡量预测输出值和实际值有多接近

Loss function:L(y^,y)L\left( \hat{y},y \right).

在逻辑回归中用到的损失函数是:L(y^,y)=ylog(y^)(1y)log(1y^)L\left( \hat{y},y \right)=-y\log(\hat{y})-(1-y)\log (1-\hat{y})

损失函数的构造

一种常见的思路是,如果yy等于1,我们就尽可能让y^\hat{y}变大,如果yy等于0,我们就尽可能让 y^\hat{y} 变小
L(y^,y)=ylog(y^)(1y)log(1y^)L\left( \hat{y},y \right)=-y\log(\hat{y})-(1-y)\log (1-\hat{y})就是这样的一个例子

损失函数是在单个训练样本中定义的,它衡量的是算法在单个训练样本中表现如何

为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数:

J(w,b)=1mi=1mL(y^(i),y(i))J \left( w,b \right)= \frac{1}{m} \sum \limits_{i=1}^{m}{L\left( \hat{y}^{(i)},y^{(i)} \right)}[5]

显然就是求所有训练样本的损失函数的平均值

损失函数只适用于像这样的单个训练样本,而代价函数是参数的总代价,所以在训练逻辑回归模型时候,我们需要找到合适的wwbb,来让代价函数 JJ 的总代价降到最低

逻辑回归可以看做是一个非常小的神经网络

梯度下降

逻辑回归的代价函数为一个凸函数

因为是一个凸函数,所以初始化对结果几乎没有影响(都会收敛到最优解)

只有一个参数的代价函数:

两个参数的代价函数:

所谓梯度下降,就是通过不断调整参数w和b, 朝最陡的下坡方向走一步,不断地迭代, 直到找到最低点(或近似最低点)

对于一个参数的代价函数,我们有:

w:=wαdJ(w)dww:=w-\alpha\frac{dJ(w)}{dw}

α\alpha为学习率,用来控制控制步长

dJ(w)dw\frac{dJ(w)}{dw}即为原函数求导

对于逻辑回归的代价函数,我们有:

微积分复习

偏导数(Partial Derivative)是微积分中的一个概念,用来描述多元函数中某个变量对另一个变量的变化率。在多元函数中,有多个自变量,而偏导数描述了函数沿着其中一个自变量的变化率,而其他自变量保持不变。

偏导数的符号通常用 \partial(读作"del")来表示,其计算方法与普通的导数类似,只是在求导时将其他自变量视为常数对待。

偏导数的定义如下:

对于一个多元函数 f(x1,x2,...,xn)f(x_1, x_2, ..., x_n),其关于第 ii 个自变量 xix_i 的偏导数为:

fxi=limh0f(x1,x2,...,xi+h,...,xn)f(x1,x2,...,xi,...,xn)h\frac{\partial f}{\partial x_i} = \lim_{h \to 0} \frac{f(x_1, x_2, ..., x_i + h, ..., x_n) - f(x_1, x_2, ..., x_i, ..., x_n)}{h}

其中其他自变量 x1,x2,...,xi1,xi+1,...,xnx_1, x_2, ..., x_{i-1}, x_{i+1}, ..., x_n 在求导时被视为常数。

偏导数的计算方法和普通的导数计算类似,可以应用求导法则,包括幂规则、乘法规则、链式法则等。

偏导数在多元函数的优化、梯度下降法、偏微分方程等领域有广泛的应用。

计算图

一个神经网络的计算,都是按照前向或反向传播过程组织的:

  • 先计算出一个新的网络的输出(前向过程)
  • 再反向传输操作用来计算出对应的梯度或导数

计算图解释了为什么我们用这种方式组织这些计算过程

所谓计算图,其实就是变量代换+链式法则的流程图

带回去的过程就是反向传输

向量化

向量化是非常基础的去除代码中for循环的艺术

SIMD指令: CPU/GPU的并行指令

# 对比向量化与非向量化

c = np.dot(a,b)

for i in range(len(a)):
    c += a[i]*b[i]


  1. rectify:修正 ↩︎

  2. 如数据库 ↩︎

  3. 线性函数作为sigmoid函数的自变量 ↩︎

  4. 即Logistic Regression Cost Function,又名成本函数 ↩︎

  5. 这里的w,b是假设的z函数: z=wTx+bz=w^Tx+b ↩︎