Deep Learning(Andrew Ng)

本文最后更新于:2 个月前

  • 为什么整个机器学习都有数据依赖:
    • 维度诅咒 如果只选取1个特征,假如选取10个数据即可接近真实情况,那么选取两个特征时 两个轴都需要达到10,所以同样的数据密度就需要100个数据,同理 n个不同的特征,就需要10n个数据,因此特征选取的数量是几何倍数级的。
  • Representation Learning 表示学习
    • 主要目标是对数据进行降维
    • 传统机器学习方法是手工进行特征提取(hand-designed features) 而Representation Learning 则是自动进行特征提取。

以房价预测为例

如果只用到一个神经元,假设输入size(x), 输出price(y)

\(size \rightarrow O_{neuron} \rightarrow price\)

if you got more feature(like walk ability or zip code), you can stack together these neurons and then you form a neuro network.

诸如房价预测等方面,我们可以直接使用一般的神经网络模型(Standard NN),在图像领域则一般使用CNN,而序列数据(音频、语言)一般则会使用RNN,


从逻辑回归开始: 神经元在做什么

  • 神经网络如何组织数据:
  • 每张图片 \(x\) 拉成一个np array, 然后作为一列, 所有的输入图片 竖排组成输入 \(X\)
  • 每个label \(y\) 作为一列,和输入图片一一对应,所有的label 竖排组成label \(Y\)
一个简单的问题:

以猫的二分类问题为例,你需要提供这张图是🐱的概率。

最简单的方法就是令 \(y^{(i)}_{pred} =\sigma(w^Tx_{(i)} + b), \space(其中\sigma = \frac{1}{1+e^{-x}})\)

这个方法利用了sigmoid函数来对预测值进行激活,最后的结果在0~1之间,接下来的使用中,我们是把这两步分开来进行的

可以考虑使用常见的平方损失:\(L(y_{pred},y)=\frac{1}{2}(y_{pred}-y)^2\)

但这个方法的问题在于,在逻辑回归中可能出现多个局部最优,平方损失不能很好的让梯度下降找到全局最优。因此在逻辑回归中一般使用下面这种:

\(L(y_{pred},y)=-{ylog(y_{pred})+(1-y)(log(1-y_{pred}))}\)

以二元分类问题为例,例如,当 y = 1时, 那么 \(L=-log(y_{pred})\),显然\(y_{pred}\)的值越接近1,Loss的值就越接近0

而 y = 0时, \(L = log(1-y_{pred})\),显然 \(y_{pred}\)的值越接近0,Loss的值就越接近0

Loss func 与 Cost func

  • Loss是对每个sample而言的,而则是Cost是全局的Loss
  • 这也就是说Cost func可以被抽象为: \(J(w,b)=\frac{1}{m}\sum^{m}_{i=1}L(y^{(i)}_{pred},y^{(i)})\)
  • 找到作为空间曲面的\(J\)的全局最小值就是我们的目标

Gradient Descent的具体工作方式:

在这张图中,我们暂时忽略b并把W看作一个实数(这样就变成了二维的情况),W := 表示的是一次迭代

当然,去掉b只是因为二维的图更加直观,实际上对于 \(J(w,b)\)的更新直接利用偏导完成:(学习率\(\alpha\))

 $w:=w- $

\(b:=b-\alpha\frac{\part J(w,b)}{\part b}\)

利用计算图理解Gradient Descent

假设: \(J = 3(a+bc)\),我们现在将这个式子的计算分解开来,令 \(u=bc,\space v=a+u,\space J=3v\),得到下图

当你给定一组(a, b, c)的值,前向传播 => 计算结果

值得注意的是,我们关注的是: 改变(a, b, c)时, 最终的结果 J 将会改变多少,换言之,就是要研究 \(\frac {\part J}{\part a}\)\(\frac {\part J}{\part b}\)\(\frac {\part J}{\part c}\)的值,再通过梯度下降来更新参数

\(\frac {\part J}{\part a}\)\(\frac {\part J}{\part b}\)\(\frac {\part J}{\part c}\) 可以通过链式法则来计算

假如你有两个特征(它们对应了两个权重w(实数)),使用 a 来代替 \(y_{pred}\),那么就可以得到下图:

其中\(\sigma(z)=\frac{1}{1+e^{-z}}\), \(L(a,y)=-ylna+(1-y)ln(1-a)\)

我们的目标:更新 \(w_1,w_2\)的值,使得 \(L(a,y)\)尽可能小

为了使用梯度下降的方法,我们需要得到这些参数的值: \(\frac{\part L}{\part w_1}\)\(\frac{\part L}{\part w_2}\)\(\frac{\part L}{\part b}\)

\(\frac{\part L}{\part w_1}\)为例,根据链式法则: \(\frac{\part L}{\part w_1}=\frac{\part L}{\part a}*\frac{da}{dz}*\frac{\part z}{\part w_1}=x_1*(a-y)\)

因此, \(w_1 := w1-\alpha \frac{\part L}{\part w_1}\),这样我们就完成了一次参数的更新

⚠️ 这里的 \(x_1,x_2\)不是两个sample,而是同一个sample的两个feature!也就是说,刚刚计算的是 一个样例的两个不同特征的损失函数(Loss)。接下来针对 m 个sample,我们来研究一下整体的代价函数 \(J(w, b)\)

  • 从这里开始 由于使用编程语言的原因,将会对偏导符号进行简记,如 \(\frac{\part L}{\part w_1}\) 就记为 dw1

\(J(w,b)=\frac{1}{m}\sum^{m}_{i=1}L(a^{(i)},y^{(i)})\) 注意此处的w和之前计算损失函数时的w就不一样了,它是所有的 w 的结合

参数矩阵W:对第i个样本的第j个特征而言,其 \(w^{(i)}_{j}\) 是作为一个实数存在的,它是矩阵中的一个元素

每增加一个样本,W就要增加一列。 每增加一种特征,W就要增加一行 (注意计算时W取转置)

在一个sample两个feature的例子里,我们需要的是 \(\frac{\part L}{\part w_1}\)「dw1」\(\frac{\part L}{\part w_2}\)「dw2」\(\frac{\part L}{\part b}\)「db」 这三个参数,而现在出现了m个sample,每个sample都有2个feature,那么对于每一个sample(如第i个样例),我们都需要求其Loss,并更新这个样例的三个参数:\(dw_1^{(i)},dw_2^{(i)},db^{(i)}\), 也就是说一共出现了3*m个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
J, dw1, dw2, db = 0, 0, 0, 0
for i in range(m):
z_i = w*x_i + b
a_i = sigma(z_i) # 计算得到预测值a_i
J += -(y_i*(ln(a_i)) + (1-y_i)*ln(1-a_i)) #对每个sample的loss求和
dw1 += ___ #通过链式求导,计算dw1
dw2 += ___ #...............dw2
db += ___ #...............db
J, dw1, dw2, b /= m # 最终的值就是所有的权重求平均

# 接下来就可以通过梯度下降的方法,对参数进行更新了 (学习率为lr)
w1 = w1 - lr*dw1
w2 = w2 - lr*dw2
b = b - lr*db

这种方法的弊端在于,对于m个参数,和n个特征,整个程序的时间复杂度将会来到O(m*n),这样做的效率是很低的,且不适合扩展到更大的数据集上。因此我们就引入了 矢量化(vectorization)技术,来避免使用显式for循环

让我们从宏观的角度来解释一下逻辑回归问题,对于m个参数,n个特征,其结果矩阵 \(Y_{pred}\)

\(Y_{pred} = \sigma(W^T·X)+B\)

==从第17个视频开始 再看一遍==

神经网络

Input layer => Hidden layer => Output layer

  • Hidden layer 的意思在于,训练时我们并不观察这些层的值,我们关系的是输入和输出层
  • Input layer是第0层(也就是说不算一层)