深度学习的一些基础知识
回过头再来看深度学习的基础知识,才发现之前掌握的根本不牢,许多基础的概念都没有深刻理解。
机器学习、深度学习的基本原理
模型的复杂度:模型的参数有多少种选择
最好的参数
我们希望训练集的数据分布与中数据分布相同,训练集中的数据之间 是的,即 independently and identically distributed,独立同分布。
数学地描述训练集与总数据集合
我们希望训练集能近似替代总数据集,即:
其充分条件如下:
proof:
due to the fact that
therefore
数据集的好与坏
只要存在一个参数param1使得:,则这个数据集是不好的。
任意挑选一个数据集是坏的的概率上限推导如下(认为模型参数的参数空间为):
因此,模型的参数空间越小,训练集的样本越大,得到一个好的训练集的概率越大。
为什么选择deep learning 而不是wide learning
一个函数可以通过若干个简单的函数叠加出来:表明神经网络有能力拟合任意函数。
若需要拟合同一个函数,那么更深的网络能比更宽的网络需要更少的参数量。(可以看作函数的嵌套)
套用数字逻辑的理论,要表达一个奇偶校验函数,对于深层网络(每层门电路数量固定),只需要个神经元即可,而对于浅层网络(层的数量固定),需要个神经元。
因此,深层的神经网络需要更少的参数就能达到相同的效果。
对于最优参数
我们希望参数空间尽可能少(减少搜索时间并增强稳定性),并且loss也尽可能少。而深度学习在保持loss基本不变的情况下显著减少了参数量,是一个非常好的方法。
生成式模型
Generater: 能够输出一个复杂的分布(将一个简单的分布变换而来的)
为什么是分布
在进行预测任务时,答案可能不止一种,有好几种可能的答案,我们希望模型能够输出一个分布,而不是一个确定的答案(否则模型容易投机取巧,将几种可能的情况揉在一起)。
为模型的输入加入一些噪声(从简单的分布采样),就能为模型的输出增加不确定性(本质是从复杂的分布采样)。
拿图片生成为例,有意义的图片的熵是比较低的(相对于噪音而言),有意义的图片一定符合某种规律,也就是一种分布。但是我们无法直接训练生成器学到这种分布,因为我们其实也不知道这个分布到底长啥样,更别说在数学上计算这个模型的输出与真实分布之间的散度了。
为了解决这个问题,GAN便应运而生了,我们只需要分布的采样,而不是分布本身。
Generative Adversarial Network: GAN
Discriminator: 判断目标是真实的还是生成的(假的)
训练过程
- 冻结生成器,训练判别器:将真实的图片打上标签1,将生成的图片打上标签0,训练判别器
- 冻结判别器,训练生成器:我们希望生成器能“骗过”判别器,得到高的分数。即,希望的输出值为1,但此时判别器的参数是被冻结的,模型会强迫让生成器学到能骗过判别器的方法。
重复以上过程
数学原理
对于判别器,我们的优化目标如下:
那么就是说,最优的判别器如下:
最优的生成器如下(最小化模型分布与真实分布之间的差异):
但是进一步可以证明与存在的正相关性
那么,优化生成器可以使用来替代散度,即
这与上述训练过程是对应的。
特点
生成器的生成的分布甚至具有连续性,在一定程度上是光滑的。将输入做插值,生成器的输出也会做展现出渐变效果。
训练
GAN的训练通常比较困难,但有一些技巧。
GAN使用的是js散度,对于两个无交集的分布,其输出始终为定值,导致梯度消失。而且由于生成器的参数是随机初始化的,其与真实分布大概率就是没有交集的。随之而来的另一个问题是,对于两个没有交集的分布,判别器可以非常容易判断真假,导致显示的判别准确率非常容易达到100%,但这实际上是没有意义的。
这可以通过更换散度函数改善(实际上是更换了优化目标),并加入一些限制条件(足够平滑,避免发散)
缺陷
GAN对于文本生成任务同样也比较困难:相较于图片,文本更为离散,参数微小的变化可能并不会造成输出的改变,出现梯度消失的问题。(argmax,sample不可微)
多样性不足:为了生成很真的图片,生成器的分布可能只是真实图片的一个子集(mode dropping),甚至几乎收敛到一个点(mode collapse)
overfitting:如果generator学会了产生真实数据集中的样本,那么最终的指标会很好看,但实际上没啥用。
Conditional GAN
之前的GAN是unconditional的,输入只有一段噪音,让模型产生一个样本。
而conditional GAN则还增加了一个输入x,用来影响输出,使其与x有关。
flowchart LR
A[x:prompt] -->B{Generator}
C[噪音]--> B
B--> D[image]
D--> E{Discriminator}
A--> E
E--> F[score]
cycle GAN
对于unsupervised的任务,我们只有大量的输入数据、输出数据,但是输入与输出不是配对的。我们就可以使用cycle GAN技术使模型学到某种对应关系。
flowchart LR
A[x:dom1] -->B{Generator1}
B-->C[y:dom2]
B-->G{Discriminator1}
G-->H[score1]
C-->D{Generator2}
D-->E[x':dom1]
D-->I{Discriminator2}
I-->J[score2]
A-->F(similarity loss)
E-->F
虽然cycle GAN只能保证x与y之间存在相关性,不能保证这种相关性就是我们视觉上看到的相关性,但由于神经网络的特性(比较懒),使得模型在实践训练中,更容易学习到视觉上的相关性(相较而言比较简单)。而不是学到把红头发变成绿头发,然后把绿头发变成红头发。
Encoder & Decoder
feature disentangle
tangle: 纠缠
disentangle: 解开
可以将嵌入向量分解为多个部分,每个部分对应一个特征。比如可以将声音学习嵌入为[content,tune],通过替换不同的tune,decoder就能将声音转换成不同的人说的。
离散的潜空间
如果我们将潜空间离散为binary的,那么模型就能学到对于不同特征的分类。
如果我们将潜空间离散为one-hot,那么模型就能学习到聚类。
VQVAE:将潜空间离散化为一个有限的集合
潜空间也可以是文本序列,对于文档,模型或许能学到总结文档的内容。(当然需要潜空间中文本的分布与人类文本的分布相似)
异常检测
异常检测有很多种实现的方式,但是很难直接通过二分类实现。因为异常数据的分布过大,你给出的异常数据集并不能覆盖整个数据分布;二是很多时候异常数据的数据量远远小于正常数据,导致模型训练时,异常数据的权重会非常低。
encoder/decoder模型
对于此模型,它只能针对特定分布的数据进行嵌入、还原。如果我们将一个异常的数据输入到模型中,它最终还原的结果会与输入的结果有很大的差异,可用于异常检测。
classifier模型
classifier模型并不直接分类出异常模型,而是分类已知的类型。
方法不止一种:
- 如果max的信心仍然不足,那么就可以认为这个数据是异常的。
- 计算这个分布的熵,如果熵过大也认为这个数据是异常的。
概率模型
使用一个概率密度函数,计算这个数据的概率密度,如果概率密度过低,那么就可以认为这个数据是异常的。
值得注意的是,可以使用神经网络去拟合这个概率密度函数。
可解释性
解释到什么程度叫可解释性,现在并没有一个统一的答案。对于神经网络的解释,其实也并不是能够完完全全透彻地解释的。
- local explanation: 针对特定输入,解释数据是如何变化的
- global explanation: 针对模型,分析模型认为的特征是什么
local explanation
图像遮盖
可以用中性颜色遮盖图片的区域,看看神经网络对不同遮盖区域的反应。
梯度图 saliency map
可以计算神经网络对输入的每个像素的梯度,从而得到一个 saliency map,这个 map 可以告诉我们神经网络关注的区域。
局限性:如果这个点已经饱和了,梯度图无法反映这个点对神经网络是否重要
探针 probing
一个神经网络有许多层
graph LR
layer1["layer1"] --> layer2["layer2"] --> layer3["layer3"]-->...["..."]
layer1-->prob1{probe1}
layer2-->prob2{probe2}
layer3-->prob3{probe3}
用一个神经网络将不同层的输出作为输入,然后将其重建(人类可理解的),比较不同层之间重建的差异,就能推断这一层神经网络干了什么。
global explanation
特征可视化
例如对于卷积而言,可以根据卷积的参数,找到能使这个卷积输出最大的输入。可视化这个卷积在检测什么样子的特征。
输入可视化
对于classifier
可以分析模型认为最符合这个类别的输入是哪些。
但实际上,这样求得的图片可能是无意义的,还需要加入正则项来限制。
trick
连接一个generator:
flowchart LR
A[z]-->B(Generator)-->C[image]-->D(Classifier)-->E[label]
这样,就能获得有意义的,并且符合分类器认为最好的输入。
用简单模型拟合神经网络
因为简单模型很容易自解释,可以使用简单模型去拟合神经网络的某些区域,尝试解释在这一部分神经网络干了什么。
Attack
white box attack
需要事先知道模型的参数
benign image:
adversarial image:
限制输入的改变范围,同时希望模型的输出与原始输出差距越大越好。
black box attack
不需要事先知道模型的参数
一般通过构建原始模型的proxy
- 尝试使用相同的数据源去训练一个“近似”的模型
- 蒸馏原始模型
增强操作:使用多个模型去拟合,然后投票,将这个整体视为proxy。这样的attack更容易成功。
一种解释:攻击能成功是因为data,而不是模型。(理由:同一个adversarial image能对不同架构但训练数据相同的模型进行攻击)
防御 adversarial training
训练完成后攻击自己,然后将adversarial image加入到训练数据中,重新训练模型,不断强化自己,增强鲁棒性,这样还更不容易过拟合。






