神经网络和深度学习
深度学习概论
什么是神经网络
神经网络是一个受大脑工作方式启发而得的有效学习算法
单一神经网络:给定一维数据,如房屋面积,创建一个 \(ReLU\) (线性整流函数)函数,映射出房屋价格。
多元神经网络:多维数据预测结果,自动生成隐藏单元,只需给定输入输出数据集让模型自己去学习。
用神经网络进行监督学习
房地产价格预测 | 标准神经网络 |
---|---|
图像识别 | 卷积神经网络 \(CNN\) |
音频、语言 | 循环神经网络 \(RNN\) |
雷达信号、模型识别等 | 复杂的混合神经网络 |
结构化数据:数据库或数据序列,每个特征都有清晰的定义
非结构化数据:音频、图像、文本,特征可以是图像的像素值或文本内的单词
为什么深度学习流行起来
- 传统模型性能上限。传统模型适用于小型数据处理,到达性能上限后数据量增加也不能明显提高性能
- 数据量增大。传统模型不适用处理海量数据
- 深度学习模型性能依赖数据量。深度学习模型学习越多数据性能越好。
- 新的算法催动计算速度的更新,从而催生新的想法,继续推动计算速度更新
规模 (模型规模、数据规模) 推动深度学习性能增长。
神经网络基础
二分分类
举例:二分类一个 64*64 的图片,判断是否为猫,输出 1 (cat) or 0 (not cat)。
图像在计算机中的存储通常为三个 64*64 的矩阵,分布对应 Red、Green、Blue 三种像素的亮度。
将三个矩阵映射到一个特征向量 \(X\) 中,将每个矩阵中的值,按行逐个读取,组成一个大的 12288*1 的向量 ( 64 x 64 x 3 = 12288 )。用 \(n = 12288\) 表示特征向量的维度。
那么二分类模型的作用就是对于输入的特征变量 \(x\) 输出结果标签 \(y\) 来预测是否是猫。
一般记训练集有 \(m\) 个训练样本,其中 \((x^{(1)},y^{(1)})\) 表示第1个样本输入 \(x^{(1)}\) 输出 \(y^{(1)}\),为了区分,记训练集为 \(m_{train}\) 测试集为 \(m_{test}\)。用 \(X=(x^{(1)},x^{(2)},...,x^{(m)})\) 记为所有特征变量的集合。那么 \(X=n * m\),是特征维度*训练样本个数
Logistic Regression
计算 \(\widehat{y}=P(y=1|x) \in (0,1)\),其中 \(x\) 是一个特征变量,给定 \(x\),参数 \(w\) (也是一个向量) 和参数 \(b\),输出 \(\widehat{y}=\sigma(w^Tx+b)\) (\(\sigma(z)\) 是 \(Sigmoid\) 函数,将输出映射到 (0,1))
\[\widehat{y}=\sigma(z)=\frac{1}{1+e^{-z}}\quad z=w^Tx+b\]
损失函数:损失函数是在单个样本上体现的,衡量了单个样本的表现。因为 \(L-2\) norm 在后续的梯度下降求最优值中表现不好,所以 \(Logistic\ Regression\) 使用
\[L(\widehat{y},y)=-(ylog\widehat{y}+(1-y)log(1-\widehat{y}))\]
- 如果 \(y=1\):\(L(\widehat{y},y)=-log\widehat{y}\),想要 \(L(\widehat{y},y)\) 尽量小,就要 \(log\widehat{y}\) 尽量大,因为 \(\widehat{y}\) 是经过 \(Sigmoid\) 函数映射后的结果,\(\widehat{y}\in (0,1)\),所以 \(\widehat{y}\) 越大越接近真实值
- 同理 \(y=0\):\(L(\widehat{y},y)=-log(1-\widehat{y})\),就要 \(log(1-\widehat{y})\) 尽量大,那么 \(\widehat{y}\) 要尽量小
成本函数:基于参数的总成本,反映整体训练样本的表现。
\[J(w,b)=\frac{1}{m}\sum_{i=0}^mL(\widehat{y}^{(i)},y^{(i)})\]
- \(m\) 是训练样本个数
- \(L(\widehat{y}^{(i)},y^{(i)})\) 表示第 \(i\) 个训练样本的损失函数
前向反向传播
前向就是正常的计算顺序,反向传播是计算导数的顺序 (链式法则)
程序里 \(dvar\) 表示导数
Logistic 回归的梯度下降法
\[ \begin{array}{l}{z=w^{T} x+b} \\ {\hat{y}=a=\sigma(z)} \\ {\mathcal{L}(a, y)=-(y \log (a)+(1-y) \log (1-a))}\end{array} \]
单个样本:假设特征值只有两个,\(w=(w_1,w_2)^T\),输入 \(w_1,x_1,w_2,,x_2,b\),则 \(z=w_1x_1+w_2x_2+b\),则 \(\widehat{y}=a=\sigma(z)\),最后计算 \(L(a,y)\)。在 \(Logistic\) 回归中要做的就是改变 \(w_1,w_2,b\) 的值使得 \(L(a,y)\) 最小。
一次梯度更新的步骤:
\[ \begin{array}{l}{w_{1}:=w_{1}-\alpha d w_{1}} \\ {w_{2}:=w_{2}-\alpha d w_{2}} \\ {b:=b-\alpha}\end{array} \]
向量化
向量化通常是消去程序中显式 \(for\) 循环的艺术。向量计算和 \(for\) 循环之间的计算速度差异差不多是 300 倍。尽可能避免使用 \(for\) 循环!
numpy 库内置了许多向量函数,将 \(w\) 向量化,程序中调用 \(np.zeros()\),将训练集 \(X\) 和偏置 \(b\) 向量化
python的广播
- 不要使用 shape 为 \((n,)\) 这种秩为 1 的数组。使用\(a=np.random.randn(5,1)\) 这种声明具体大小的语句
- 如果已经得到了 \((n,)\) 这种秩为 1 的数组,可以使用 reshape 转换
- 随意申明 assert 语句,使用断言,确定矩阵的 shape,及时发现bug
浅层神经网络
神经网络表示
输入层、隐藏层、输出层,但输入层一般不看做一个标准层,从隐藏层开始对网络层数计数,数学标记 \(a^{[n]}_i\) 表示第 \(n\) 层网络的第 \(i\) 个节点的结果。
神经网络的输出
类比 \(Logistic\) 回归中的计算, \(Logistic\) 回归中先计算 \(z=w^Tx+b\),再计算 \(a=\sigma(z)=\widehat{y}\),单隐藏层的神经网络就是对每一个节点 \(a^{[1]}_i\) 都计算一遍 \(z^{[1]}_i=w^{[1]T}_ix+b^{[1]}_i\)
激活函数
\(Sigmoid\)、\(tanh\)、\(ReLU\)、\(Leaky ReLU\)
函数名 | 利弊 |
---|---|
Sigmoid | 除了二分类问题其他很少使用,输出区间在(0,1),不利于数据中心化 |
tanh | 性能很好,中心对称,比sigmoid常用 |
ReLU | 默认激活函数,梯度下降很友好 |
Leaky ReLU | 弥补ReLU在小于0的部分梯度为0的问题,但很少使用 |
随机初始化
权重矩阵不宜太大,一般0.01合适,权重矩阵太大会导致 \(z\) 值过大,落在激活函数的平缓部分,梯度下降小,学习速度减慢。
深层神经网络
技术上来说,\(Logistic\) 回归是单层神经网络。
正向传播是时候还是要用 \(for\) 循环的。
前几层识别简单的特征,后面的就可识别更复杂的特征,比如脸的轮廓 \(\rightarrow\) 五官 \(\rightarrow\) 脸部,音位 \(\rightarrow\) 单词 \(\rightarrow\) 词组 \(\rightarrow\) 句子
深度学习就是听着唬人,搁以前都叫有很多隐藏层的神经网络。。
超参数:控制实际参数的参数
不知道超参数如何取最优值,需要多次实验,练成超参数直觉。。 玄学学习率和超参 。。。