Lifan's Note


  • Home

  • Tags

  • Categories

ML_knowledge

Posted on 2022-07-06

Machine Learning Knowledge

K-th Nearest Neighbor

[Supervised, regression]

已有一个带label的数据集,给定一个样本,求其label。计算与其他所有samples的距离,取前k近的samples,统计这k个samples的label,认为最多的那个为此样本的label。

  • k的选择不能太大,否则没有意义(当k=n是就是一个统计)同时k也不能太小,否则就overfit(当k=1时就近选择,对于测试集没有帮助);可以通过划分验证集的方式来找到合适的k
  • 数据的维度需要归一化,否则某个维度的距离会dominate其他的维度。
  • 时间复杂度高,kd tree

K-means clustering

  1. 选择初始化的k个样本作为初始聚类中心$a=a_1,a_2,…,a_k$
  2. 针对数据集中每个样本$x_i$计算它到k个聚类中心的距离并将其分到距离最小的聚类中心所对应的类中
  3. 针对每个类别$a_j$,重新计算它的聚类中心$a_j=\frac{1}{|c_i|}\sum_{x\in c_i}x$(即属于该类的所有样本的质心)
  4. 重复2,3两步操作,直到达到某个终止条件(迭代次数,最小误差变化等)

目标检测 整理

Posted on 2022-07-05

Object Detection目标检测

Two Stage Objection Detection

RCNN

将物体检测当做分类问题处理,即先提取一系列的候选区域,然后对候选区域进行分类。Two-staged

  1. 候选区域生成:region proposal,此时用的是selective search算法:先将图片分割成小区域,然后再合并包含同一物体可能性高的区域并输出,提取2000个候选区域,并对每一个区域进行归一化处理得到固定大小的图像
  2. CNN特征提取。用CNN网络得到固定维度的特征输出。
  3. SVM分类器:使用线性分类器对输出的特征进行分类,并采用了难样本挖掘来平衡正负样本的不平衡
  4. 位置精修:通过一个回归器,对特征进行辩解回归以得到更为精确的目标区域
  • 三个问题:
    • 多步训练:步骤繁琐且训练速度较慢
    • 分类需要用MLP网络,因此输入的尺寸固定
    • region proposal需要提取并保存,占用空间较大

Fast RCNN

有三点改进:

  1. 共享卷积:整幅图送到卷积网络中进行区域生成来减少计算量,但依旧采用selective search方法。
  2. RoI Pooling:region of interesting,利用特征池化的方法进行特征尺度变换,可以处理任意大小的图片
  3. 多任务损失:将分类和回归网络放在一起训练,放弃SVM,采用softmax函数进行分类

Faster RCNN

采用Region Proposal Network,利用Anchor机制将区域生成和卷积网络联系在一起。Anchor可以看作是图像上很多固定大小和宽高的方框,FasterRCNN认为只需要将anchor和物体进行匹配,然后对anchor进行分类和位置的微调就可以完成检测,降低了网络收敛的难度

包括4个部分:

  1. 特征提取网络Backbone:输入图像经过Backbone得到feature map
  2. RPN Module:区域生成模块,生成region proposal:

    RPN in Stage One

    1. Anchor生成:RPN对feature map上的每一个点都对应了9个anchor。这9个anchor大小宽高不同,[8,16,32]x[0.5,1,2]。每个点的9个anchor对应原尺寸图片上的9个框。
    2. Anchor与标签的匹配。这些框映射回输入图片的尺寸,然后和ground truth中的bbox做IOU。对于每个Anchor和每个标签,判断标准如下(注意顺序不能随意变动):
      • 对于任何一个Anchor,与所有标签的最大IoU小于0.3,视为负样本
      • 对于任何一个Label,与其最大IoU的Anchor,视为正样本(保证每个标注的物体有bbox)
      • 对于任何一个Anchor,与所有标签的最大IoU大于0.7,视为正样本
      • 为了保证这一阶段的召回率Recall,允许一个标签对应多个anchors,而不允许一个anchor对应多个标签。正样本视为前景(有物体的区域),负样本视为背景(无关注物体的区域)
    3. Anchor的筛选:因为生成了2万个anchor,如果全部采用则正负样本不均衡,不利于网络收敛。RPN默认选择256个Anchors进行损失计算,其中最多不超过128个正样本。
    4. 求解回归偏移值:对于这些anchor,我们计算其与ground truth的偏移值

      位置偏移$t_x$和$t_y$利用了宽高进行归一化,宽高偏移$t_w$和$t_h$进行了对数处理,限制了偏移量的范围,利于收敛。在后面预测值的时候,直接将预测的$x,y,w,h$替换上式中的gt,然后求真值 $t_x,t_y,t_w,t_h$ 和新得到的值的差值就可以进行学习。

        - 通过这样的方式缩小了框的坐标变化幅度,只需要预测相对这个anchor的移动量,使得网络易于收敛,准确预测。anchor相当于给了一个强先验,说物体都在我给的这些框里。
      
    5. 损失函数设计

      其中 $\sum_i L_{cls}(P_i, P_i^)$是256个筛选出来的Anchors的分类损失,$P_i$是每个Anchor的类别gt,$P_i^$是每个Anchor的预测值,此处指判断是否是前景,不判断具体class,用cross entropy。

      $\sum_i P_i^ L_{reg}(t_i, t_i^)$代表了回归损失,其中bbox_inside_weights实际上起到了$p_i^*$进行筛选的作用,bbox_outside_weights 起到了$\lambda\frac{1}{N_{reg}}$来平衡两部分损失的作用。

      当预测值与gt差距太大时,采用L1 loss免得导数太大无法收敛。

    RPN in Stage Two

    1. RPN的功能是region proposal。具体方式和训练RPN相同:
      1. backbones提取feature maps
      2. 过RPN网络得到(4x9xHxW)和(2x9xHxW)个值,
      3. 根据分类网络输出的得分(也就是后者)排序,取前12000个得分最高的anchors
      4. 通过Non-Maximum Suppression来将重叠的框去掉:
        先将anchors按得分排序,取最大的得分的anchor保留,去除所有与这个anchor IoU超过一定threshold的anchors。然后再取剩下的中的最大得分的anchor,重复上一个步骤,直到原始的anchors集都用完。
      5. 取前2000个作为最后的proposal regions
        1. 2000个proposal region与所有的物体标签的IoU,根据IoU矩阵的值来筛选出符合条件的正负样本,筛选标准如下:
      6. 对于任何一个proposal,其与所有标签的最大IoU如果大于等于0.5,视为正样本
      7. 对于任何一个proposal,其与所有标签的最大IoU如果大于等于0且小于0.5,视为负样本
        然后对于分类出来的正负样本,控制正负样本比例满足1:3,总数控制在256个。因此正样本数量不超过64个,超过就随机取64个。负样本取256-p个,超过也随机取256-p个。
        这样做的目的是:
      • 筛选出更贴近正式物体的RoI
      • 减少送入后续全连接网络的数量,有效减少了计算量
      • 完成了后续RCNN部分的真值计算
  1. RoI Pooling层

    RPN给出了256个proposal region以及对应的ground truth;Backbone给出了feature maps。因为proposal region是对于原图尺寸而言的,将RoI映射到feature上就是RoI Pooling。

    假设当前RoI为332x332,backbone提取的feature maps下采样率为16,目标features为512x7x7。

    1. 将332x332下采样16倍,得到20.75x20.75并向下取整,得到20x20.
    2. 要将20x20的区域处理为7x7的特征。因为 $ 20/7 \approx 2.857$再次向下取整,采取2x2大小,stride=2的max pooling,得到7x7的输出。

      • 以输入图片为参考坐标的候选框在feature maps上如何映射? 其中,f下标是feature map,i下标是image,$(X_f,Y_f)$位feature上的坐标点,$(X_i,Y_i)$为原始image上的坐标点。
      • 如何把形状和大小各异的RoI归一化为固定大小的目标识别区域?
        通过对feature map分块池化归一化到固定大小,即第二步,分成$(H_i/H_r)\times (W_i/W_r)$块,对每块MaxPool。

      这里的问题是:因为两次向下取整,势必带来偏差,影响正确率。

      An Alternative Way: RoI Align

      取消量化操作,利用双线性插值Bilinear Interpolation的方法获得坐标为浮点数的像素点上的图像数值,从而将整个特征聚集过程转为一个连续的操作。

    3. 遍历每一个候选区域,保持浮点数边界不做取整。
    4. 将候选区域分割成kxk个单元,每个单元的边界也不做量化。
    5. 在每个单元中计算固定四个坐标位置(即:假定4个采样点),用双线性差值的方法计算出这四个位置的值,然后做最大池化操作。以下图为例,将RoI分割成2x2的单元格,再将每个单元格子划分成4个小方格,以每个小方格的中心作为采样点(红色点)对它进行 双线性插值,得到该采样点的像素值。最后对4个采样点max pooling得到最后ROI Align的结果。

设一个点$(x,y)$,知道四个点$Q_{11}=(x_1,y_1),Q_{12}=(x_1,y_2),Q_{21}=(x_2,y_1)$以及$Q_{22}=(x_2,y_2)$

先按x方向进行线性插值
$$f(x,y_1) = \frac{x_2-x}{x_2-x_1}f(Q_{11})+\frac{x-x_1}{x_2-x_1}f(Q_{21})\\
f(x,y_2) = \frac{x_2-x}{x_2-x_1}f(Q_{12})+\frac{x-x_1}{x_2-x_1}f(Q_{22})\\
$$
再按y方向进行线性插值
$$f(x,y) = \frac{y_2-y}{y_2-y_1}f(x,y_1) + \frac{y-y_1}{y_2-y_1}f(x,y2)$$
![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Bilinear_interpolation_visualisation.svg/170px-Bilinear_interpolation_visualisation.svg.png)


- ROI Align的反向传播

    普通RoI Pooling反向传播公式为:
    $$\frac{\partial L}{\partial x_i}= \sum_r\sum_j[i=i^*(r,j)]\frac{\partial L}{\partial y_{rj}}$$

    其中x_i是池化前feature map上的像素点,y_rj代表池化后第r个候选区域的第j个点,i^*(r,j)代表y_rj像素值的来源(最大池化的时候选出的最大像素值所在点的坐标)

    RoI Align的反向传播需要做出修改:
    $$\frac{\partial L}{\partial x_i}=\sum_r\sum_j[d(i,i^*(r,j)) < 1](1-\triangle h)(1-\triangle w)\frac{\partial L}{\partial y_{rj}}$$

    因为$x_i^*(r,j)$是一个浮点数的坐标位置,在池化前的特征图中,每个与$x_i^*(r,j)$横纵坐标均小于1的点都应该接受与此对应的点$y_{rj}$回传的梯度,d(.)表示两个点之间的距离,$\triangle h$和$\triangle w$表示$x_i$和$x_i^*(r,j)$横纵坐标的差,这里作为双线性内插的系数乘在原始梯度上。
  1. 全连接RCNN
    RoI Pooling得到256x512x7x7的features,将后面三维展开成1维,利用VGGNet的两个全连接层,得到256x4096的RoI特征。为了预测类别和回归,将4096维分别接入分类和回归的MLP中。

    分类网络输出num of class+1(background)维,回归网络输出每个类别下的4个位置偏移量。于是一共输出(num_of_cls+1)*4维。

    • 虽然256个ROI放在了一起计算,但是相互之间独立,并没有共享特征,造成了重复计算。

    损失函数与RPN类似,只不过此时分类softmax为21类不再是2类。回归时最多有64个正样本参与回归计算,负样本不参与回归计算。

  • 一些缺点和后续改进:
    • 卷积提取网络:对于多尺度和小尺寸的物体不友好,没有融合多层feature maps
    • NMS:对于遮挡物体不友好,因为会直接删除掉造成漏检。
    • RoI Pooling:两次向下取整带来feature上的影响,mask rcnn提出RoI Align
    • RCNN全连接:没有权值共享
    • 正负样本:需要超参来限制正负样本的数量
    • 两个阶段:无法达到实时。

YOLO系列

YOLO v1

  1. 首先将输入图片resize到448x448大小,送入CNN网络,最后输出得到7x7的特征图。
    • 特征提取网络有3个细节
      • 3x3的卷积过后通常会接一个通道数更低的1x1的卷积,降低计算量,提升模型的非线性能力
      • 除了最后一层使用线性激活函数外,其余层的激活函数Leaky ReLU(ReLU没有负数的导数,activate均值为正,导致bias shift)
      • 训练中使用了Dropout与数据增强的方法来防止过拟合
  2. 特征图的意义
    其精髓在于7x7x30的feature map。

    1. 将原图划分为7x7个区域,每个区域就对应着最后特征图上的一个点。
    2. 如果一个物体的中心点落在某个7x7的区域中,那么那个区域就负责检测该物体。具体的,我们希望提取的那个点的feature可以预测B个bounding box以及bbox的置信度confidence score。

      • 所谓置信包含两个方面,一是$Pr(object)$这个边界框包含目标的可能性大小,二是这个边界框的准确度(预测框与GT的IoU, $\text{IoU}^{truth}_{pred}$ )。所以置信度c定义为:$Pr(object) * \text{IoU}^{truth}_{pred}$

        所以需要对应feature maps上的点的channel等于 $B*|x,y,w,h,c|+C$。v1中B=2,C=20,所以最后生成的feature maps通道数为30。

        具体的实现上,前20个是类别概率值,中间两个是bbox的置信度,最后8个是两个预测框的x,y,w,h。纯粹是为了计算 切片方便。

    3. 损失计算
      1. 区分开正负样本:
        • 当一个真实物体的中心落在了某个区域内,该区域就负责检测该物体。具体做法是将与该真实物体有最大IoU的bbox设为正样本,这个区域的类别真值为该真实物体的类别,该边框的置信度为1
        • 除了上述被赋予正样本的bbox,其余bbox皆为负样本,负样本没有类别损失与边框位置损失,只有置信度损失,其真值为0
      2. Loss由5部分组成,均采用MSE损失:
        $$\lambda_{coord}\sum_{i=0}^{s^2}\sum_{j=0}^B\mathbb{1}^{\text{obj}}_{ij}[(x_i-\hat{x_i})^2+(y_i-\hat{y_i})^2]\\
      • \lambda_{coord}\sum_{i=0}^{s^2}\sum_{j=0}^B\mathbb{1}^{\text{obj}}_{ij}[(\sqrt{w_i}-\sqrt{\hat{w_i}})^2 + (\sqrt{h_i}-\sqrt{\hat{h_i}})^2] \\
      • \sum_{i=0}^{s^2}\sum_{j=0}^B\mathbb{1}^{\text{obj}}_{ij}(C_i-\hat{C_i})^2 \\
      • \lambda_{no\ obj}\sum_{i=0}^{s^2}\sum_{j=0}^B\mathbb{1}^{\text{no\ obj}}_{ij}(C_i-\hat{C_i})^2 \\
      • \sum_{i=0}^{S^2}\mathbb{1}^{\text{obj}}_i\sum_{c\in \text{classes}}(p_i(c)-\hat{p_i}(c))^2
        $$

    其中第一项是边界框中心坐标的误差项,$\mathbb{1}^{\text{obj}}_{ij}$是指第i个单元格存在目标,且该单元格的第j个bbox负载预测该目标。

    第二项是bbox的宽高的误差项,通过平方差,降低对尺度的铭感,强化小物体的损失权重

    第三项是包含目标的边界框的置信度误差项。

    第四项是不包含目标的bbox的置信度误差项。$\lambda_{no\ obj}=0.5$调低负样本置信度损失的权重。

    第五项是包含目标的单元格的分类误差项。$\mathbb{1}^{\text{obj}}_i$指的是第i个单元格存在目标。这里的C_i=$Pr(object) * \text{IoU}^{truth}_{pred}$

    推理的时候需要NMS7x7x2=98个框,需要按类别NMS。

  • 不足之处:
    • 每个区域只有两个框,且两个框都指向同一个类别。这个限制会导致模型对小物体,以及靠的特别近的物体检测效果不好
    • 由于没有anchor这类先验框,模型对新的,或者不常见宽高比例的物体检测效果不好,另外由于下采样率较大,边框的检测精度不高
    • 损失函数中,大物体的位置损失权重越小物体的位置损失权重是一样的,导致同等比例的位置误差,大物体的损失会比小物体大,小物体的损失在总损失中占比较小,会带来物体定位的不准确。

YOLOv2

  • Batch Normalization

    对于每一层的输入都做了归一化。提升2%mAP.

  • High resolution classifer高分辨率图像分类器

    采用224x224 ImageNet图像进行分类模型预训练160 epoch,再采用448x448的高分辨率样本对分类模型进行finetune(10个epoch),使得网络特征逐渐适应448x448的分辨率,缓解了分辨率突然切换造成的影响。

  • Convolution with anchor boxes使用先验框

    学习FasterRCNN预测anchor box的偏移量。在每个grid预先设定一组不同大小和宽高比的边框,来覆盖整个图像的不同位置和多种尺度,因为anchor bbox的大小都不同,所以不能再使用MLP,8将全连接层和最后一个pooling层去掉*

    将输入图片尺寸从448改为416,这样经过32倍downsample,可以得到13x13的feature map,使得特征图只有一个center cell(如果是偶数就会有四个)。

      - 为什么希望只有一个center cell?
      - 因为大的object一般会占据图像中心,所以希望用一个center cell去预测。
    

    最后recall提升7%,mAP只下降0.3%

  • Dimension clusters 聚类提取先验框的尺度信息

    通过Training GT的bbox的k-means聚类分析,自动寻找尽可能匹配样本的anchor box尺寸。传统欧式距离在bbox尺寸较大的时候误差也更大,而我们希望误差和bbox的尺寸没有太大关系,所以通过IoU定了如下距离函数:

    其中centroid是聚类是被选中作为中心的边框,box是其他的边框,于是IoU越大,两者越接近。

  • Direct Location prediction 约束预测边框的位置
    借鉴于Faster RCNN的先验框方法,其位置预测公式:

    由于没有RPN网络去直接学习预测位移,所以在YOLO中直接取学习$t_x,t_y$,导致他们的取值没有任何约束,因此预测边框的中心可能出现在任何位置,训练早期阶段不容易稳定。YOLOv2调整了预测公式,将预测边框的中心约束在特定的grid网格内:

    其中,

    • $b_x,b_y,b_w,b_h$是预测边框的中心和宽高。
    • $Pr(object)*IoU(b,object)$是预测边框的置信度,这里对预测参数$t_o$进行sigmoid变换后作为置信度的值。
    • $c_x,c_y$是当前网格的左上角到图像左上角的距离,要先将网格大小归一化,即令一个网格的宽=1,高=1.
    • $p_w,p_h$是先验框的宽高。
    • $\sigma$是sigmoid函数。
    • $t_x,t_y,t_h,t_w,t_o$是要学习的参数。
      因为使用了限制让数值变得参数化,也让网络更容易学习,更稳定。
  • Fine-Grained Features(passthrough层检测细颗粒度特征)

图像中的对象会有大有小,输入图像经过多层网络特征提取,最后输出的feature map中较小的对象可能并不明显甚至被忽略掉了。于是引入了passthrough层:在最后一个pooling层之前,特征图大小为26x26x512,将其1拆4,让他们和经过pooling,conv后的feature map 13x13x1024直接concat,得到13x13x3072.

  • Multi-Scale Training 多尺度图像训练
    每10个batch,网络会随机选择一个新的图片尺寸,[320,608,32],希望网络在不同的输入尺寸上都达到一个很好的预测效果。

  • Hierarchical classification分层分类
    提出了一种在分类数据集和检测数据集上联合训练的机制:object detection的数据集取训练detection,classification的数据集只训练分类loss。

但是ImageNet有9000个种类,coco只有80种,作者使用multi-label模型,即假定一张图片可以有多个label,且不要求label间独立。采用以下策略重建了一个树形结构:

  1. 遍历ImageNet的label,然后在WordNet中寻找该label到根节点的路径
  2. 如果路径只有一条,那么就将该路径直接加入到分层数结构中
  3. 否则,从所有路径中选择最短的一条加入到分层树中。

这个分层树就称之为WordTree,作用在于将两种数据集按照层级进行结合。

分类时的概率计算借用了决策树思想,某个节点的概率值等于该节点到根节点的所有条件概率之积。最终结果是一颗 WordTree (视觉名词组成的层次结构模型)。用WordTree执行分类时,预测每个节点的条件概率。如果想求得特定节点的绝对概率,只需要沿着路径做连续乘积。

YOLOv3

从特征获取预测结果

多特征层进行目标提取,一共提取三个特征层,三个特征层位于darknet53的不同位置,分别位于中间层,中下层,底层,三个特征层的shape分别为(52,52,256),(26,26,512),(13,13,1024),这三个特征层后面用于与上采样后的其他特征层concat

第三个特征层(13,13,1024)进行5次卷积处理(提取特征),处理完后一部分过卷积并上采样,另一部分用于输出该尺寸下的预测结果(13,13,75)。Conv2d 3x3 和Conv2d 1x1起到通道调整的作用,调整成输出需要的大小。

上一步中上采样后得到(26,26,256)的特征层,然后与Darknet53网络中的特征层(26,26,512)进行Concat,得到的shape为(26,26,768),再进行5次卷积。同样一部分过卷积并上采样,另一部分用于输出对应的预测结果(26,26,75)。Conv2d 3x3 1x1同上。

重复上一步,将上采样的特征与(52,52,256)的特征Concat,再次5次卷积得到shape为(52,52,128),并过Conv2d 3x3 1x1得到(52,52,75)

  • 如果物体在图中较大就用13x13检测,较小就用52x52来检测。

预测结果的解码
和V2一样

Deep Learning基础知识 整理

Posted on 2022-07-05

Basic Component

Loss常见损失

机器学习中监督学习的本质是给定一系列样本$(x_i,y_i)$,尝试学习$x\rightarrow y$的映射关系。损失函数是用来估量模型的输出$\hat{y}$和真实值$y$之间的差距,从而给模型的优化指引方向。

其中,前面的均值函数为经验风险,$\mathcal{L}(y_i,f(x_i;\theta))$为损失函数,后面的项$\lambda \Phi(\theta)$为结构风险,$\Phi(\theta)$衡量模型复杂度。

A loss function is a part of a cost function which is a type of an objective function.

  • loss function:对单个训练样本而言
  • cost fucntion:对整个训练集而言
  • objective function:任意希望被优化的函数

MSE(Mean Squared Error) Loss

就是L2 Loss

  • 推导:通过假设模型预测与真实值之间的误差服从高斯分布$(\mu=0,\sigma=1)$,那么对于任意$x_i$,模型生成他对应真实值$y_i$的概率为:假设N个样本点相互独立,则这组$x$得到对于$y$的概率为他们的累乘:两边取对数:去掉第一项常数,转换成最小化负对数似然(Negative Log-Likelihood)就得到了:
  • 所以在假设成立的前提下使用是比较合适的,比如回归问题。而类似分类问题就不是一个好选择了。

MAE(Mean Absolute Error) Loss

就是L1 Loss

  • 推导:假设模型预测和真实值之间的误差服从Laplace分布$(\mu=0,\beta=1)$,则对于一个$x_i$其输出值为$y_i$的概率为:同上推导:
  • MSE和MAE的区别
    • 梯度不同,MSE为$-\hat{y_i}$,MAE为$\pm1$,对于梯度下降而言,MSE更好
    • MAE对异常点更鲁棒:平方项会拉大噪点的影响

BCE(Binary Cross Entropy) Loss

先通过sigmoid将输出$\hat{y_i}$限制在$(0,1)$之间,那么对于$x_i$其被判断为正例的概率为$p(y_i=1|x_i)=\hat{y_i}$,那么对应为负例的概率为$p(y_i=0|x_i)=1-\hat{y_i}$

同上

二元的cross entropy就是

CE(Cross Entropy) Loss

类似于二分类的BCE,此处的$y_i$变成了one-hot的向量,同时模型输出的压缩从Sigmoid函数变成了Softmax函数,其压缩输出在(0,1)之间,且所有输出之和为1

其中k属于class的种类数,

又由于$y_i$是one-hot向量,上式可以写成:

其中$c_i$是$x_i$的目标类。

  • 为什么分类中不使用MSE Loss?
    • 因为输出的$\hat{y_i}$和真实值$y_i$需要在分类的类别中,其差值不是高斯分布所以效果很差。
  • 为什么分类使用交叉熵损失?
    1. 最大似然来解释,即上面的推导
    2. KL散度,让输出分布和真实分布贴近可以用KL散度表示。$KL(y_i,\hat{y_i})=\sum_{k=1}^K y_i\log y_i-\sum_{k=1}^K y_i\log \hat{y_i}$,又第一项与优化无关,就变成了Cross Entropy $-\sum_{k=1}^K y_i\log{\hat{y_i}}$

Hinge Loss

当y_i=1的时候,hinge loss会对判断为负的结果有较大惩罚,同时还会在[0,1]区间对判断为正,但是不确定的结果有较小惩罚。所以hinge loss会给出一个清晰的决策边界

Exponential Loss

Adaboost中使用

Log-Likelihood Loss

非常好的表征概率分布,在很多场景尤其是多分类,如果需要知道结果属于每个类别的置信度,那它非常适合;健壮性不强,相比于hinge loss对噪声更敏感

Focal Loss

由于在one-stage的object detection中windows的前景类别和背景的可能达到1:1000,使用CE Loss,主要的class的Loss会overwhelm数量少的class(也就是背景的判断影响了对前景的学习),所以在CE Loss的基础上改进:

Activation 激活函数

通过激活函数给网络添加增加非线性,使得NN可以学习到非线性的复杂函数

  1. 连续并可导(允许少数点不可导)的分线性函数。可导的激活函数可以直接利用数值优化的方式来学习网络参数
  2. 激活函数及其导函数要尽可能简单,有利于提高计算效率
  3. 激活函数的导函数的值域要在一个合适的区间内,不能太大也不能太小,否则会影响训练的效率和稳定性(?ReLU)

常见激活函数

  • tanh: $\tanh(x)=\frac{\exp(x)-\exp(-x)}{\exp(x)+\exp(-x)}$
    • zero-centered,[0,1]区分
  • Sigmoid: $\sigma (x)=\frac{1}{1+e^{-x}}$
    • 梯度消失,[0,1]区分
  • Softplus: $ln(1+e^{x}$
    • [0,inf]区分
  • Softmax: $\frac{e^{x_i}}{\sum_{j=1}^J e^{x_j} }\text{for} i=1,…,J$
  • ReLU: $max(0, x)$
    • 解决梯度消失的问题。[0,inf]区分
  • LeakyReLU: $\begin{cases} 0.01x & \text{ if } x<0 \\ x & \text{ if }>0 \end{cases}$
  • ELU: $f(x)=\begin{cases} x &\text{if }x >0 \\ \alpha(e^x-1) &\text{if} x\leq 0 \end{cases}$
    • relu没有负值,导致激活值的均值不在零,在多层的激活函数累加下会导致bias shift。elu既利用了负值的信息,又让均值为0.

Batch Normalization

在深层网络的训练过程中,由于网络中参数变化而引起内部节点数据分布发生变化的过程被称为Internal Covariate Shift。以MLP的一层线性变换为例:$Z^{[l]}=W^{[l]}\times input + b^{[l]}$,其中l代表层数;非线性变换为$A^{[l]}=g^{[l]}(Z^{[l]})$,g为激活函数。随着梯度下降,每一层的$W^{[l]},b^{[l]},Z^{[l]}$都会被更新,进而$A^{[l]}$也同样出现分布的改变。但是$A^{[l]}$作为第l+1层的输入,第l+1蹭的参数需要不断去适应新的数据分布的变化。

  • 上层网络需要不停调整来适应输入数据分布的变化,导致网络学习速度降低
  • 网络的训练过程容易陷入梯度饱和取,减缓网络收敛速度
    • 解释:当我们采用sigmoiod这类饱和激活函数(saturated activation function)时,随着模型训练的进行,我们的参数$W^{[l]}$会逐渐更新并变大,$Z^{[l]}=W^{[l]}A^{[l-1]}+b^{[l]}$也会随之变大,随着网络层数的加深,$z^{[l]}$越来越大,而饱和激活函数在数值较大的区域的梯度逐渐变小直至接近于0,于是更新速度就会变慢。ReLU是解决这个问题的一个方法。

要解决ICS的问题,就要解决由于梯度更新带来的数据分布变化的问题。 机器学习中白化whitening 对输入数据分布进行变化

  • 使得输入特征分布具有相同的均值与方差。其中PCA白化保证了所有特征分布均值为0,方差为1;而ZCA白化则保证了所有特征分布均值为0,方差相同;
  • 去除特征之间的相关性。
  • 但是 1. 白化计算成本太高,2. 白化过程改变了网络每一层的分布,从而影响了网络层中本身数据的表达能力。

BN具体步骤:

  1. 对每个特征进行独立的normalization,假设输入为$Z$,对于这个输入的第j个维度,
  2. Normalization操作虽然解决了ICS问题,让每一层网络的输入数据分布都变得稳定,但却导致数据表达能力的确实,另外因为所有输入均值为零,方差为1,集中在sigmoid和tanh的中间的线性区域,缺失非线性的表达能力。

    所以BN引入了两个可学习的参数$\gamma,\beta$,目的是恢复数据本身的表达能力,$\tilde{Z_j}=\gamma_j\hat{Z_j}+\beta_j$
    3.在training的时候,每次过minibatch时,记录并更新每一层的$\mu_{batch}$和$\sigma^2_{batch}$

    所以pytorch的model.train()和model.eval()会影响bn层。

  • 好处:
    • 使得网络中每层输入数据的分布相对稳定,加速模型学习速度
    • 使得模型对网络中的参数不那么敏感,简化调参过程,学习稳定
    • 允许使用saturated activation function,缓解梯度消失
    • 有一定正则化效果,相当于对每个mini-batch加随机噪音。

Convolution卷积

Input $\begin{bmatrix} a & b & c \\ d & e & f \\ g & h & i \\ \end{bmatrix}$, kernel $\begin{bmatrix} 1 & 2 \\ 3 & 4 \\ \end{bmatrix}$

Output的尺寸:$output = (input-kernel+2*padding)/stride+1$

  • 为什么用卷积代替mlp
    • 全链接层参数太多,导致训练效率低下
    • Convolution优点:
      • 局部连接local connection:局部感知野:对于一个部分,左右移动一个pixel应该不影响结果(所以mlp中连接所有点的操作过于冗余),局部内的像素连接比较紧密,对较远的像素连接稀疏,通过多层全链接,深处的一个点就相当于原图的一块区域。
      • 权值共享weight sharing:减少了weights的数量,降低了网络复杂度。kernel中每一个channel可以理解为不同的特征提取方法,比如边缘检测的算子,这些channel可以通用在整个图片上。
      • 池化Pooling:降尺寸,减少计算量,特征压缩。通过pooling层,提取特征(max pooling最大的,avg pooling平均的)来减缓卷积层对位置的敏感性。(注:conv2d配合stride同样可以达到downsample的效果,且可能可以学到不一样的特征,而pooling的操作时固定的,但是其占用的计算量和存储量更小。有文章证明conv2d with stride更好)(注2:BP的时候,avg pooling将gradient平均到上一层的每个位置,max pooling将gradient传到最大的那个位置)
  • 1x1卷积和mlp层的关系
    • 对于1x1的输入而言,两者没有区别,而对于[b,c,h,w]的输入,1x1的卷积的输出尺寸不变,[b,c’,h,w],c’可以进行升维或者降维。而对于MLP层来说,其输出维[b,c,1,1]。另外参数量在h x w的情况下会更多。
  • 空洞卷积
    • 对于每次stride,kernel对应的每一个点中间都要隔开dilation个点。以此希望在不改变参数量的情况下增加感受野。(卷积核填充0,或者输入等间隔采样)
    • 网格效应:局部信息丢失,远距离获取的信息没有相关性

Transpose Convolution转置卷积/反卷积

Input $\begin{bmatrix} a & b &c \\ d & e & f \\ g & h & i \end{bmatrix}$, kernel $\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix}$, 反卷积操作:

$H_{out}=(H_{in}−1)×stride[0]−2×padding[0]+dilation[0]×(kernel_size[0]−1)+output_padding[0]+1$

先将input两边补零(kernel_size-1):

如果stride > 1:

把kernel 180度旋转:

然后进行正常卷积。

  • ConvTranspose2d会导致什么?
    • Checkerboard Artifact 转置卷积因为stride=2和kernelsize的倍数关系,总会有些下层的点upsampling到上层的时候被多次计算,但是我们又不希望去专门设计不会overlap的filter这样会限制模型的自由度,所以提出了Nearest Neighbor Interpolation-Resize Deconvolution,Bilinear-Resize Deconvolution,虽然一定程度上能减轻棋盘格现象,但是不一定是最好的。

Optimizer优化器

待优化参数$\theta$,目标函数$f(\theta )$,学习率$\eta$

每一次epoch t迭代优化:

  1. 计算目标函数关于当前参数的梯度:$g_t=\triangledown_{\theta} f(\theta_{t})$
  2. 根据历史梯度计算一阶动量和二阶动量:$m_t=\phi(g_1,g_2,…,g_t); V_t = \psi(g_1,g_2,…,g_t)$
  3. 计算当前时刻的下降梯度: $\triangle\theta_t=-\eta\times m_t/\sqrt{V_t}$
  4. 根据下降梯度进行更新:$\theta_{t+1}=\theta_t+\triangle\theta_t$

Stochastic Gradient Descendent随机梯度下降

对于一个数据量大,复杂度高的模型,不可能一口气看完所有数据然后计算其梯度。所以才用了minibatch的方法,以一个minibatch的数据为单位,计算一个批次的梯度,然后再反向传播,并更新参数

没有动量$m_t = g_t; V_t = I^2$,所以:

其中,$g_t$参数梯度,$\eta$学习率。

  • 好处
    • 分担训练压力
    • 加速收敛,因为一个epoch中有多次更新梯度的机会。
  • 坏处
    • 开始的学习率难以确定
    • 容易陷入局部最优解:为了解决这个问题,通常我们会加入动量(momentum)保留一些历史的更新方向,希望增加优化的稳定性,降低陷入局部最优无法跳出的风险
      • 理论上,如果$m_t,m_{t-1}$的方向相同的话,梯度会变大,加快收敛。如果方向不同,则梯度会变小,抑制梯度更新的震荡增加稳定性。当训练结束的中后期,$g_t$可能趋近于0,动量可以使得梯度不为零从而跳出局部最优。

AdaGrad

自适应学习率:对于经常更新的参数,已经积累了大量关于他的只是,不希望被单个样本影响太大,希望学习率慢一点;对于偶尔更新的参数,了解的信息太少,希望从每个偶然出现的样本上多学一点,希望学习率快一些。那么应该如何度量历史更新频率呢?二阶动量,即迄今为止所有梯度值的平方和:

那么我们得到:

于是学习率变成了$\frac{\eta}{\sqrt{V_t}}$,更新的越多$\sqrt{V_t}$越大,学习率就越小。

  • 但是由于$\sqrt{V_t}$是单调递增的,最后会导致学习率递减至0,提前结束学习。

AdaDelta/RMSProp

既然基于所有历史二阶动量的AdaGrad太过激进,那么何不只选择关注一段时期内,关注过去一段时间窗口的下降梯度。

指数移动平局值:

Adam(Adaptive + Momentum)

SGD的一阶动量:

加上AdaDelta的二阶动量:

得到

Some Problem

  • AdaGrad和SGD都会收敛,只是有会提前收敛的问题。但是AdaDelta和Adam由于用的是一段时间内的累积,$V_t$可能时大时小导致训练不稳定,模型无法收敛。可以通过$max(V_{t-1},Adam)$的方式保证收敛。
  • 自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。

对抗生成网络 整理

Posted on 2022-07-05

GAN Metrics

Inception Score

  • Concept 用图片分类器来评估生成图片的质量。清晰度:对于清楚的图片,分类器应该可以确定的判断该图的种类,那么其熵$p(y|x)$(即不确定性)比较小。多样性:对于所有生成的图片,每个种类应该均匀生成,所以$p(y)=\sum p(y|x^{(i)})$
  • Equation: $IS(G)=\exp(\mathbb{E}_{x\sim p_g}D_{KL}(p(y|x)||p(y)))$

    • $\mathbb{E}_{x\sim p_g}$: 循环所有样本
    • $D_{KL}$: KL散度
    • $p(y|x)$: 对于图片x,属于所有类别的概率分布,对于给定图片x,表示为一个1000维向量
    • $p(y)$: 边缘概率,具体实现为对于所有的验证图片x,计算得到$p(y|x)$,再求所有向量的平均值。
  • IS 有什么问题

    1. 数据集,因为基于InceptionV3,只能使用ImageNet1000,所以不能直接生成图片套用在InceptionV3上。
    2. 使用框架的不同,pytorch,tensorflow等,IS差别会很大
    3. IS高的图片不一定真实:因为是根据分类器来给分的,所以可以根据分类器的结果来刷分(提高全体图片的类别多样性,那么每一张图片的熵就会低)
    4. IS低的图片不一定虚假:如果图片的类不在1000类中则会低
    5. 多样性检测有局限性:如果每个类只生成一个样子,依旧是mode collapses
    6. IS不能反映过拟合:如果模型完全记忆数据集,给出Train集的数据,IS也会很高。

FID

  • Definition: The Frechet distance $d(\cdot,\cdot)$ between the Gaussian with mean $(m, \Sigma)$ obtained from $p(\cdot)$ and the Gaussian with mean $(m_r, \Sigma_w)$ obtained from $p_w$. 假设原始图片和生成图片都服从高斯分布,计算两个分布的均值和协方差,算均值和协方差的距离。
  • Equation: $d^2((m_g, \Sigma_g), (m_r, \Sigma_w) = ||m_g-m_r||^2_2 + Tr(\Sigma_g+\Sigma_w-2(\Sigma_g\Sigma_w)^{0.5})$
  • Method:

    1. 加载图片[B,C,H,W], 文件数最好是bs的倍数否则会导致少读几个文件。
    2. Inception V3去除输出层,只取到最后一个pooling层,
        得到[Bx2048x1x1] feature(如果输入图片尺寸不对,
        增加一个adaptive_avg_pool2d到1x1)
    3. diff = m_g-m_r
        diff.dot(diff)+np.trace(sigma_g)+np.trace(sigma_r)-2*linalg.sqrtm(simga_g.dot(sigma_r))
    
  • FID 优缺点
    1. 优点1:生成模型的训练集可以和InceptionV3不同
    2. 优点2:刷分不会导致生成图片的质量变差
    3. 缺点1:强假设 提取的图片特征符合Gaussian
    4. 缺点2:无法反映过拟合的问题

LPIPS(Learned Perceptual Image Patch Similarity)

  • $d(x,x_0)=\sum_l \frac{1}{H_l W_l} \sum_{h,w}||w_l \bigodot (\hat{y}^l_{hw}-\hat{y_{0}}^l_{hw})||$
  • 通过预训练的VGG,AlexNet等网络,对一对图片x,x_0进行特征提取,对每层提取出来的特征计算归一化后相减得到diff并平方(?),将每层的diff过一个1x1的卷积(乘以w),并进行空间尺度上的平均,最后每层的输出相加。
  • StarGANv2里使用LPIPS来测量多样性,数值越大说明越不相似。
    • 对此存疑,原文中是通过训练一个simple network,将diff的结果输入到这个网络中让他判断是原图和distort图一对,来反过来finetune整个pretrained network。但是starganv2里好像直接采用了vgg的网络?

Precision and Recall(Improved)

  • Motivation: 因为IS,FID等只有一个维度的分数,所以无法区分不同失败的例子。(无法同时满足真实性和多样性两个指标)
  • Definition: 对于参考分布P(X)和学习到的分布Q(Y),
    • Precision: 生成的图片可以落在真实分布的流型上的比例
    • Density: 真实的图片覆盖生成分布的比例其中N,M是真实和生成的数量,流型Manifold定义为:其中$B(x,r)$是以x为球心,r为半径的D维球形;$\text{NND}_k(X_i)$是$X_i$到除了自己以外第k近的邻居的距离。

Density and Coverage

  • Motivation:precision和recall会受到outliers的影响且计算效率低。

    • outlier: 在没有归一化操作前,一个outlier会使得得到的流型覆盖一大块在outlier附近的区域,从而让流型overestimate。
      • precision: 生成的样本可能落在overestimate的流型部分中从而让percision看起来更高。
      • recall:因为模型倾向于生成不真实但不同的样本,所以生成流型也经常比真正的生成分布大。另外由于每个模型的fake manifold都不同,每次都需要重新计算流型。
    • computational inefficiency:需要两两计算距离,每个样本都需要计算$O(kM\log M)$
  • 于是提出了Density和Coverage

    • Density:计算有多少个真实样本的neighborhood sphere包含$Y_j$,
    • Coverage:计算所有真实样本中,neighborhood sphere包含至少一个生成样本的比例。
  • mode collapse 和 mode dropping的区别?
    • mode collapse是 many z to ~one x
    • mode dropping是 real data not inG(z)

Perceptual Path Length

  • Idea: 除了清晰度和多样性,生成器能否很好的把不同图片的特征分离出来也是一个关注的指标。StyleGAN的作者希望当我们给定一个z from latent space的时候,$z_1$能控制人的头发,$z_2$能控制人的眉毛等等,当调整$z_1$时,生成的图片只会有头发的变换。
  • Equation: PPL评估利用生成器从一个图片变到另一个图片的距离,越小越好
    • $\epsilon$ 细分的小段,1e-4
    • $d(\cdot,\cdot)$ perceptual distance,用预训练的VGG来衡量
    • slerp:spherical linear interpolation球面线性插值
    • $t\sim U(0,1)$插值参数,服从均匀分布

Generative Adversarial Network、

WGAN

书接JS散度
考虑到几乎不可能去便利所有的联合分布$\gamma$去计算距离$||x-y||$的期望$\mathbb{E}_{(x,y)\sim\gamma}[||x-y||]$,因此直接计算$W(p_r, p_g)$是不现实的,WGAN提出用 Kantorovich-Rubinstein 对偶性将W转化为:

$\sup(\cdot)$是上确界,$||f||_L \leq K$表示函数$f: R\rightarrow R$满足K-阶Lipschitz连续性,即满足

于是,我们使用判别网络$D_\theta (x)$参数化$f(x)$函数,在$D_\theta$满足1阶Lipschitz约束的条件下,K=1,得到:

因此求解$W(p_r, p_g)$的问题转化为:

也就是在满足D(x)处处导数小于1的情况下求解最大值。所以在实际应用上作者的做法是,限制神经网络的所有参数$\theta$都不会超过某个范围[-c,c],这样关于输入样本x的导数$\frac{\partial f_\theta}{\partial x}$也就不会超过这个范围,所以通过这个上届,满足小于某个K值的上确界。

  • 可以防止mode collapse,但不能提升图像质量。

WGAN-GP

添加了Gradient Penalty来迫使判别器满足1阶Lipschitz函数约束,同时发现在1周围工作效果更好

所以Discriminator的目标函数为:

第一项是EM距离,第二项是GP,其中$\hat{x}=tx_r+(1-t)x_f,\;\; t\in[0,1]$
Generator的目标函数为:

又第一项与G无关,可以省去得到

  • WGAN做了什么?

    • 判别器去掉最后一层sigmoid
    • discriminator和generator在算loss时没有log
    • 每次更新判别器的参数后把他们的绝对值clip到一个孤单常数c
    • 不使用Adam等基于动量的优化算法,推荐使用RMSProp,SGD也行
  • 为什么WGAN要把vanilla GAN的最后一层sigmoid拿掉

    • 因为原始的GAN的目标是判断图片的真假,所以用sigmoid来获取类别的概率。WGAN中判别器作为EM距离的度量网络,其目标是衡量生成分布$p_g$和真实分布$p_r$之间的EM距离,属于实数空间,所以不需要加Sigmoid。

Vanilla GAN

  • Idea: 给定一个latent z使用generator来生成图片,使用discriminator来判断区分生成图片和真实图片,并返还gradient给Generator更新参数。Discriminator的目标是最大化区分真假的结果,Generator的目标是最小化其生成图片被判断为假的概率。最后两者大道纳什均衡。
  • Equation:

    • Discriminator:

    • Generator:

      • 因为$\log(1-D(G(x)))$的梯度很小,作者用了一个log D trick,将其替换为最大化$\log(D(G(x))$,其梯度更大,且和Discirminator学习的方向一致。
    • 所以总的目标函数为:

  • Vanilla GAN的问题

    • 判别器越好,生成器梯度消失越严重。

      • 当固定G的时候D Loss变为:$-P_r(x)\log(D(x))-P_g(x)\log(1-D(x))$
        令其关于D(x)的导数为0的道论文里于是证明:当$P_r(x)=0$且$P_g(x)\neq0$时,最优判别器应该为给出0(也就是说判断生成的图片都为假);而当$P_r(x)=P_g(x)$时,最优判别器应该给出0.5(也就是说无法判断谁真谁假)

      于是我们回头看Generator的loss,加上一项判断$x_r$的值对于gradient并无影响(最小化他等同于最小化之前的loss),得到:

      把公式【2】带回,得到

      根据JS散度:

      在假设中JS散度对于有重叠的两个分布则公式是成立,但是因为GAN的z的取值有限(比如2^6维)而要生成的图片维度极高(比如256*256=2^16),则图片虽然在高维,但是其变化受到z值的限制,于是两个$p_r$和$p_g$的分布就很难会有重叠;如果没有重叠,那么JS散度就变成了0,而损失也就变成了-2log2,而梯度就变成了0。

    • 最小化第二种生成器loss函数,会等价于最小化一个不合理的距离衡量,导致两个问题,一是梯度不稳定,二是mode collapse。
      经过推导,最小化第二个G loss函数等同于最小化一边是要最小化生成分布和真实分布的KL散度,另一边却又要最大化两者JS散度,于是会梯度不稳。另外,$KL(P_g||P_r)$项对生成的样本不真实时惩罚巨大,对没生成真实样本的情况惩罚微小,导致生成器偏向生成几种确定的样本,从而导致模式坍塌。

LSGAN

惩罚离群的点,让生成图像接近真实数据
但是会使得生成图像失去多样性

DCGAN

  • 把GAN的mlp转变为全卷积。Generator里用Conv2dTranspose进行上采样,一步一步扩大图片尺寸。
    • Generator中使用ReLU作为激活函数
  • Discriminator和Generator对称,取消pooling层,用带步长的卷积代替,一步一步缩小图片,最后判断图片真假。
    • Discriminator中使用Leaky ReLU。
  • Generator和Discriminator中使用BN层(稳定GAN的训练)
    • 实验表示但不要对generator的输出层和discriminator的输入层使用BN,会不稳定
  • 提出latent interpolation,对于z1,z2生成的两张图片x1,x2, 如果对z1,z2进行线性插值生成的图片应该显示从x1逐渐渐变到x2。如果图像发生急剧变化,则就是模型没有学到特征只是记住了图像。
  • 通过生成模型输入向量的加减发修改图像,类似word2vec,king-man+woman=queen

Improved Techiques for Training GANs

  • Feature matching: 因为generator和discriminator在进行min max的纳什均衡游戏,但是两者的目标函数又是凹函数,会导致两者loss此消彼长。提出使用discriminator作为feature extractor,然后将generator的目标改为$||\mathbb{E}_{x\sim p_r}f(x)-\mathbb{E}_{z\sim p_z}f(G(z))||_2^2$。
    • 个人认为虽然在统计意义上是合理的,但是不是很make sense,在多轮epoch中一张图片会有不同z生成,势必导致G混淆latent的作用。
  • Minibatch Discriminator:认为mode collapse的原因和discriminator每次只看一张图片有关,由于每次只看一张图片,discriminator容易落入local minimal无法跳出。所以使用minibatch,对于discriminator中间的一层输出,每个图的特征$x_i\in minibatch$通过一个矩阵T,映射成一个矩阵。然后每个图对应的矩阵的第k行两两做L1距离的计算并求和,然后重新组成一个n x B的矩阵作为下一层的输入。
    • 后来的文章基本没有用这个方法。
  • Historical averaging 生成和判别器的损失函数中添加一项正则项,$||\theta-\frac{1}{t}\sum_{i=1}^{t}\theta[i]||^2$,通过保证和之前的参数的抖动不过大来控制GAN的稳定性(后来的文章几乎也没见过,有使用衰减系数来记录参数的)
  • One-side Label Smoothing
  • Virtual Batch Normalization
  • 提出了IS ,感觉是本文唯一被引用的原因。

Conditional GAN

在Vanilla GAN的基础上添加了条件概率,使得目标函数变为

具体操作中就是

  1. 把输入的z和类别c做concat,作为输入给generator
  2. 把$x$和c作为输入给到判别器,让他判断(1)x是否是真实的,(2)x是否属于类别c

Pix2Pix

  • Generator:使用Unet结构,输入的轮廓图x进行encode,然后再decode成图片
    • Unet:输入和输出的图像的surface appearance应该不同,而潜在的结构(underlying structure)应该相似。对于I2IT的任务来说,输入和输出应该共享一些底层信息,因此使用Unet这种跳跃连接(skip connection)的方法,i层与n-i层concat。
  • Discriminator:使用条件判断器PatchGAN,将图片变成70x70的区块并判断每个区块的真假并统计。
    • 因为L1和L2 loss重建的图像很模糊,并不能很好的恢复图像的高频部分(图像的边缘等),而对于低频部分(色块等)恢复良好,所以采用patch的方式分区块对局部进行判断。
  • Loss Function
  • 作者认为L1 loss可以来补充低频信息,而GAN Loss可以来补充高频信息
  • 缺点:x到y之间是一对一的映射,应用范围有限,且test的数据与train数据差距较大时效果很差。

BicycleGAN

为了增加多样性

  • VAE-GAN

    VAE-GAN
    图片压缩成z,再还原成图片最后GAN loss判断

  • cVAE-GAN

    cVAE-GAN

    • 不变的是:

      • L1 和 D的loss
      • 从 B到 z 再到B
    • 在VAEGAN的基础上添加了

      • 压缩的z和随机采样的z做kl损失,使得压缩的z符合随机分布
      • Generator take A and z as input
  • cGAN
    • 将class和latent concat作为输入给generator
  • cLR-GAN
    cLR-GAN
    • 不变的是:
      • A对应的就是y, z还是随机的变化,作为G的输入
      • 真实B和生成的B做D的判断
    • 在cGAN的基础上添加了
      • Encoder,并重新压缩B得到$\hat{z}$和z做L1 loss
  • Unet中z有两种concat的方法:
    • unet concat

CycleGAN

不再需要paired data,通过cycle consistency loss,即$A\underset{G_A}{\rightarrow} B \underset{G_B}{\rightarrow} \hat{A}$后求$||A-\hat{A}||_1$
cyclegan

  • discriminator中使用了LSGAN的最小二乘损失MSE

MathForDL

Posted on 2022-07-05

Base Math Knowledge for Deep Learning

范数

具有“距离”概念的函数。一个满足半正定(非负),齐次$p(av)=ap(v)$,和三角不等性$p(u+v)\leq p(u)+p(v)$的函数我们称之为距离/半范数。而再保证 正定$p(v)=0, \text{if}\ v=\vec{0}$的额外性质,那么这个函数p就是范数。

p-norm p范数

对应Lp-Norm,也就是闵科夫斯基距离,一组距离的定义,当计算距离的时候$x=x_1-x_2$

因此当p=1的时候就是L1-Norm,就是曼哈顿距离,即所有非零数的绝对值之和

当p=2的时候就是L2-Norm,就是欧几里得距离,即所有数的平方和的开方

当p=$+\infty$的时候,就是取x中绝对值最大的那个元素的绝对值,也就是切比雪夫距离

Lasso回归 Ridge回归

Entropy

$离散随机变量 X = \{x_1,x_2,…,x_n\}, 其概率为 p_i=p(X=x_i) $

x越不可能发生,则p(x)的概率越小,而其log p(x)的值则越大,意味着信息量越大,统计每件x的概率和信息。

联合熵

对于服从联合分布为P(x,y)的一对离散随机变量(X,Y),

条件熵

Mutual Information

互信息: 度量两个随机变量的“相关性”,随机事件X的不确定性或者熵H(X),以及在知道随机事件Y条件下的不确定性(条件熵)的差异

KL Divergence/相对熵

Equation

  • 度量两个随机变量的距离
  • $D_{KL}(p||q) \neq D_{KL}(q||p)$
  • $D_{KL}(p||q) > 0$
  • 对于两个分布距离很远的分布,没有重叠时,$D_{KL}(p||q)=\sum 1\cdot \log \frac{1}{0}=+ \infin$,没有意义。

Cross Entropy

一个真实分布$p(x)$和一个非真实分布$q(x)$
要用非真实分布q(x)来表示来自真实分布p(x)的平均编码长度

我们希望生成数据和原始数据分布越接近越好,所以可以用KL散度,但又因为KL的一项只于p(x)有关,所以可以用交叉熵做loss评估模型、

%3D%5Csum_%7Bi%3D1%7D%5E%7Bm%7D%5Cleft%5B-y%5E%7Bi%7D%20%5Clog%20h_%7B%5Ctheta%7D%5Cleft(x%5E%7Bi%7D%5Cright)%2B%5Cleft(1-y%5E%7Bi%7D%5Cright)%20%5Clog%20%5Cleft(1-h_%7B%5Ctheta%7D%5Cleft(x%5E%7Bi%7D%5Cright)%5Cright)%5Cright%5D)

Jensen-Shannon Divergence

是KL散度的一个变形

  • $JS(p||q) \in [0,1]$,相同是0,相反是1.
  • $JS(p||q) = JS(q||p)$
  • 对于两个分布距离很远的分布,没有重叠时,$JS(p||q)=\sum 1\cdot \log \frac{1}{1/2}+\sum 1\cdot \log \frac{1}{1/2}=\log 2$. 当两个分布完全等于零是,JS=0
    因此得到所以Vanilla GAN的生成器的梯度很有可能近似为0,导致梯度消失。那么
  • Vanilla GAN不稳定的原因
    • discriminator训练的太好 会导致梯度消失,generator的loss降不下去
    • discriminator训练的不好 generator的梯度不准,到处乱跑
1
2
3
4
5
def JensonShannonDivergence(p,q):
p = np.array(p)
q = np.array(q)
M = (p+q)/2
return 0.5*np.sum(p*np.log(p/M)) + 0.5*np.sum(q*np.log(q/M))

Earth-Mover Distance / Wasserstein Distance

从一个分布变换到另一个分布的最小代价

  • $\prod(p,q)$是p和q组合起来的所有可能的联合分布的集合(p的每一个搬到q的任意一个地方的组合),所以$\gamma$就是每一个可能的联合分布,
  • ||x-y||是cost,期望$\mathbb{E}_{(x,y)\sim\gamma}[||x-y||]$就是这些组合的搬运代价。
  • $\inf_{\gamma\sim\prod(p,q)}$表示下确界,即小于这组数的值中那个最大的值。

Transformer

Posted on 2021-01-30

Transformer seems like a new promising land of

Attention

Pyro SVI 第三部分:ELBO梯度估计器

Posted on 2020-03-22

Setup

我们已经定义了由观察x,隐变量z通过 $p_{\theta}(x,z) = p_{\theta}(x|z)p_{\theta}(z)$ 形式组成的model。我们同时也定义了 $q_{\phi}(z)$ 组成的guide。在这里,$\phi$ 和 $\theta$ 都是对model和guide的变分参数。(特别的,这里没有随机变量需要使用贝叶斯?)。

我们想要通过最大化ELBO的方法最大化对数证据 $log\:p_{\theta}(x)$ :

通过这样做,我们将能在 ${\theta,\phi}$ 的空间中对ELBO使用(随机)梯度下降(这个方法的前期工作请参考【1,2】)。这样我们需要计算无偏估计:

我们如何在随机函数model()和guide()上使用它呢?为了简化字符,让我们概括这个讨论一点,直接讨论我们如何计算任意一个损失函数 $f(z)$ 的期望的梯度。让我们同时忽略 $\theta$ 和 $\phi$ 之间的不同。所以我们希望计算:

让我们从最简单的例子开始。

简单:可重新参数化的随机变量

假设我们可以重新参数化下面这个:

重点是,我们去除了期望之中所有对 $\phi$ 的依赖; $q(\epsilon)$ 是一个对 $\phi$ 没有依赖的固定的分布。这样的重新参数化可以在很多分布上使用(例如,正态分布);详细讨论见参考【3】。在这个例子中我们直接向期望传递梯度,来得到:

假设 $f({\cdot})$ 和 $g({\cdot})$ 都足够平滑,我们现在可以通过这个期望的蒙特卡洛估计,得到感兴趣的梯度的无偏估计。

进阶:没有可重新参数化的随机变量

如果我们不能做上面的重新参数化呢?不幸的是,我们感兴趣的很多分布(distributions of interest?),比方说所有离散分布,都属于这种情况。在这个例子中,我们的估计器面对更复杂一点的形式。

我们先拓展感兴趣的梯度为:

然后使用链式规则写成:

在此处我们将遇到一个问题。我们知道如何从 $q(\cdot)$ 中生成取样 ——我们直接跑guide就行—— 但是 $\triangledown_{\phi}q_{\phi}(z)$ 甚至不是一个合格的概率密度。那么我们需要改变这个公式使得它是一个可用 $q(\cdot)$ 表示的期望。这可以通过下面这个identity轻松完成:

这样就让我们可以重新熟悉梯度为:

这个梯度估计器的形式——也有叫做加强估计器(REINFORCE estimator)或者评分函数估计器(score function estimator)或似然比例估计器(likelihood ratio estimator)——很适合做蒙特卡洛估计。

注意到,一个打包此结果的(方便实现的)方法是引入一个替代目标函数(surrogate objective function):

这里横线意味着这一项保持不变(这样就不会被 $\phi$ 求导了)。为了得到一个(单个样本)蒙特卡洛梯度估计,我们对隐随机变量采样,计算替代对象,并求导。结果是 $\triangledown_{\phi}\mathbb{E}_{q_{\phi}(z)}[f_{\phi}(z)]$ 的无偏估计。 等式:

方差或者为什么我希望我在做MLE Deep Learning

我们现在有了对损失函数期望的无偏梯度估计的配方了。不幸的是,更宽泛的情况,即我们的 $q(\cdot)$ 包括了不可重新参数画的随机变量的情况,这个估计器会有很高的方差。实际上,在很多感兴趣的例子中,这个方差高到使得估计器无法有效使用。所以我们需要一个方法来减少方差(详细讨论见参考【4】)。我们将跟随两个策略。第一个方法利用了 $f(\cdot)$ 的特殊结构。第二个方法有效地利用了之前的 $\mathbb{E}_{q_{\phi}(z)}[f_{\phi}(z)]$ 的估计来减少方差。这个方法和利用动量进行随机梯度下降有异曲同工之妙。

通过依赖结构减少方差

在上面的讨论中,我们受困于一个宽泛的损失函数 $f_{\phi}(z)$。我们可以在此路上继续前进(我们将讨论的这个方法适用于大多数情况)但是对于具体性,让我们放大来看。在随机变分推断中,我们对特定的损失函数形式感兴趣:

其中,我们分割对数比率 $log\:\frac{p_{\theta}(x,z)}{q_{\phi}(z)}$ 为一个观测的对数似然片段和不同隐随机变量 $\{z_i\}$ 的和。我们同时引入了 $Pa_p(\cdot)$ 和 $Pa_q(\cdot)$ 来表示model和guide中给定的随机变量的parents。(读者可能会担心在广泛的随机函数中什么是合适表示依赖的字符;这里我们简单地意为常规的一个单一执行踪迹中的前者依赖)。重点是,损失函数中不同的项会对随机变量 ${z_i}$ 有不同的依赖,而这是我们可以利用的地方。

简短的来说,对于任何不可重新参数画的隐随机变量 $z_i$,替代目标就是:

这使得我们可以去除 $\overline(f_{phi}(z))$ 的某些项,同时可以依旧得到一个无偏的梯度估计器;进一步,这样做通常将会减少方差。特别的(详见参考【4】)我们可以移去 $\overline(f_{phi}(z))$ 中不是隐变量 $z_i$ 的下游(downstream of latent variables)的项(downstream指的是guide的依赖结构)。注意到这个技巧——处理某些随机变量来减少方差——通常会被称为Rao-Blackwellization。

在Pyro中,所有的此类逻辑都自动被SVI类所纳入。具体的来说,只要我们使用TraceGraph_EBLO类,Pyro就将持续追踪model和guide里执行踪迹中的依赖结构,并建立移除了所有非必要项的替代目标:

1
svi = SVI(model, guide, optimizer, TraceGraph_EBLO())

注意到,利用这种依赖信息将花费额外的计算量,所以TraceGraph_EBLO应该只在模型中有不可重新参数化的随机变量时才使用;在多数应用中Trace_ELBO就足够了。

一个使用Rao-Blackwellization的例子

假设我们有一个k个元素组成的混合高斯模型。对于每个数据,我们:(1)先对各个组成的分布 $k \in [1, …, K]$ 取样,(2)使用第k个组成分布观察数据。最简单的方法是用如下方式写下模型:

1
2
3
ks = pyro.sample("k", dist.Categorical(probs).to_event(1))
pyro.sample("obs", dist.Normal(locs[ks], scale).to_event(1),
obs=data)

因为使用者没有注意去标记模型中的任何条件独立,PryoSVI类生成的梯度估计器无法利用Rao-Blackwellization,而其结果就是梯度估计器将伴有高方差。要解决这个问题,使用者需要明确的标记条件独立。值得高兴的是,这个工作量并不大:
1
2
3
4
5
6
7
# mark conditional independence
# (assumed to be along the rightmost tensor dimension)
with pyro.plate("foo", data.size(-1)):
ks = pyro.sample("k", dist.Categorical
(probs))
pyro.sample("obs", dist.Normal(locs[ks], scale),
obs=data)

就是这么简单。

其他:Pyro中的依赖跟踪

最后,讨论一个依赖跟踪(dependency tracking)。在包括任意Python代码的随机函数中做依赖追踪是有点麻烦的。目前Pyro实现的方法和WebPPL中用的相类似(参考【5】)。简单的来说,这里使用了一个依赖序列顺序的保守的依赖概念?。如果在一个给定的随机函数中随机变量 $z_2$ 在 $z_1$ 之后,那么 $z_2$ 可能依赖于 $z_1$, 进而假设他们是依赖的。要解决这种过度草率的假设行为,Pyro包含了plate和markov两种结构,用他们申明的事物是独立的(见之前的教程)。对于不可重新参数化变量的情况,使用者(当可以用时)完全利用SVI提供的方差减少的的结构是相当重要的。在一些例子中,也需要考虑(如果可能的话)重新安排一下随机函数中随机变量的顺序。在未来的Pyro版本中,我们期望添加更好的依赖跟踪概念。

用数据依赖基线减少方差

第二个减少ELBO梯度估计器的方差的方法名叫基线(baselines)(见参考【6】)。它实际利用了一点同样的,基于上文所提到的方差减少方法的数学。不同的是现在,我们添加项而不是减少项。基本上就是,我们不再移去那些会增加方差但又期望为0的项,我们将会添加一些特别选择的0期望的项,让他们来减少方差。这就是一个控制方差的方法。

更具体的,这个想法就是利用以下这个事实:对于任意常量b,下面这个表达一直成立:

因为 $q(\cdot)$ 是被正则过的,我们可以得到:

这就意味着我们可以将替代目标中的任意项:

替换为

这样做不会影响我们的梯度估计器的均值,但是它能影响到方差。如果我们巧妙的选择b,我们就能减少方差。事实上,b并不需要是一个常量:它可以依赖任意一个随机选择的 $z_i$ 的上游(或侧游)。

Pyro中的基线

在随机变分推断中,使用者有很多方法可以让Pyro来使用基线。因为基线可以被附加在任何不可重新参数化的随机变量上,目前的基线接口baseline interface在pyro.sample一层中。具体的,基线接口使用参数baseline,这个参数是申明基线选项的字典。注意到,只有在guide中申明对于采样语句的基线,它才有意义,在model则无用。

衰减均值基线 Decaying Average Baselines

最简单的基线可以从一个从 $\overline{f_{\phi}(z)}$ 的最近的样本的动态均值中建立。在Pyro中,这类基线可以按如下方式调用:

1
2
3
z = pyro.sample("z", dist.Bernoulli(...),
infer=dict(baseline={'use_decaying_avg_baseline':True,
'baseline_beta': 0.95}))

可选参数baseline_beta申明了衰减均值的衰减速度(默认值是0.90)。

神经基线 Neural Baselines

在一些情况中,一个衰减均值基线表现的很好。但在其他的的情况下,使用一个依赖上游随机性的基线,对于得到更好的方差减少是相当重要的。一个有力的方法是建立一个可以使用神经网络来通过学习调整的基线。Pyro提供了两条申明这种基线的途径(可以在AIR教程中见到扩展的例子)。

首先使用者需要决定机选将那些输入将被使用(比如,当前的考虑的数据,或者之前采样的随机变量)。然后,使用者需要建立一个nn.Module,他将封装基线的计算。他将长这个样:

1
2
3
4
5
6
7
8
9
10
class BaselineNN(nn.Module):
def __init__(self, dim_input, dim_hidden):
super().__init__()
self.linear = nn.Linear(dim_input, dim_hidden)
# ... finish initialization

def forward(self, x):
hidden = self.linear(x)
# ... do more computations ...
return baseline

然后,假设BaselineNN对象baseline_module已经被初始化过了,在guide中我们有如下:

1
2
3
4
5
6
def guide(x):  # here x is the current mini-batch of data
pyro.module("my_baseline", baseline_module)
# ... other computations ...
z = pyro.sample("z", dist.Bernoulli(...),
infer=dict(baseline={"nn_baseline": baseline_module,
'nn_baseline_input': x}))

这里,参数nn_baseline告诉Pyro使用哪个nn.Module来建立基线。在后端的参数nn_baseline_input被传入forward方法中来计算基线b。注意到基线module需要又一个pyro.module被Pyro注册,这样Pyro才能知道module中要训练的参数。

本质上来说,Pyro建立如下形式的损失:

它将被用于神经网络调整参数。没有理论证明这个是在此处最佳的损失函数,但实际上,它表现的相当的好。就像衰减均值基线,主要想法是一个可以追踪 $\overline{f_{\phi}(z)}$ 均值的基线可以帮助减少方差。实际上,SVI在基线损失中下降一步,就是在ELBO上下降一步。

注意,在实际中,对基线参数使用一组不同的学习超参(比如,更大的学习率)是相当重要的。在Pyro中,这可以用如下方式实现:

1
2
3
4
5
6
def per_param_args(module_name, param_name):
if 'baseline' in param_name or 'baseline' in module_name:
return {"lr": 0.010}
else:
return {"lr": 0.001}
optimizer = optim.Adam(per_param_args)

注意到,为了让整个过程正确,基线参数应该只通过基线损失被优化。相似的,model和guide的参数应该只通过ELBO被优化。为了保证这个情况,SVI从autograd graph中分离了进入ELBO的基线b。同时,因为神经基线的输入可能依赖于model和guide的参数,这些输入同样应该在被送入神经网络前,从autograd graph中分离。

最后,另一种方式申明神经基线的方法是直接使用参数baseline_value:

1
2
3
b = # do baseline computations
z = pyro.sample("z", dist.Bernoulli(...),
infer=dict(baseline={'baseline_value': b}))

如上可行,除了在这个例子中使用者需要自己保证任何连接b与model和guide中参数的autograd tape需要被切断。换言之,任何依赖 $\theta$ 或者 $\phi$ 的对b的输入需要被从autograd graph中用detach()来分离。

一个使用基线的复杂例子

记得在SVI的第一个教程中,我们考虑了一个抛硬币的伯努利-贝塔模型。因为beta随机变量是一个不可重新参数化(或者说不容易重新参数化)的变量,对应的ELBO梯度变得噪声相当大。那时,我们使用了Beta分布来提供(近似)重新参数化的梯度来解决这个问题。现在我们已经展示了,在Beta分布被当作不可重新参数化(这样ELBO梯度估计器就相当于打分函数)时,一个简单的衰减均值基线可以减少方差。尽管我们使用了这个方法,我们仍然用plate来写我们全向量化的model。

作为替代直接对比梯度方差,我们将看到它让SVI收敛要多少步。对于这种特殊的model(因为他是共轭的),我们可以计算明确的后验。那么要评估基线在此处的用处,我们预设如下简单的实验。我们用一组特定的变分参数初始化guide。然后我们待变分参数达到后验的参数的一定范围之内后做SVI。我们同时使用和不使用衰减均值基线。然后我们比较梯度下降的步数。下面是完整的代码:

(因为分隔使用了plate和 use_decaying_avg_baseline,这段代码将和SVI教程的第一第二部分很相似,我们就不逐行解释了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import os
import torch
import torch.distributions.constraints as constraints
import pyro
import pyro.distributions as dist
# Pyro also has a reparameterized Beta distribution so we import
# the non-reparameterized version to make our point
from pyro.distributions.testing.fakes import NonreparameterizedBeta
import pyro.optim as optim
from pyro.infer import SVI, TraceGraph_ELBO
import sys

# enable validation (e.g. validate parameters of distributions)
assert pyro.__version__.startswith('1.3.0')
pyro.enable_validation(True)

# this is for running the notebook in our testing framework
smoke_test = ('CI' in os.environ)
max_steps = 2 if smoke_test else 10000


def param_abs_error(name, target):
return torch.sum(torch.abs(target - pyro.param(name))).item()


class BernoulliBetaExample:
def __init__(self, max_steps):
# the maximum number of inference steps we do
self.max_steps = max_steps
# the two hyperparameters for the beta prior
self.alpha0 = 10.0
self.beta0 = 10.0
# the dataset consists of six 1s and four 0s
self.data = torch.zeros(10)
self.data[0:6] = torch.ones(6)
self.n_data = self.data.size(0)
# compute the alpha parameter of the exact beta posterior
self.alpha_n = self.data.sum() + self.alpha0
# compute the beta parameter of the exact beta posterior
self.beta_n = - self.data.sum() + torch.tensor(self.beta0 + self.n_data)
# initial values of the two variational parameters
self.alpha_q_0 = 15.0
self.beta_q_0 = 15.0

def model(self, use_decaying_avg_baseline):
# sample `latent_fairness` from the beta prior
f = pyro.sample("latent_fairness", dist.Beta(self.alpha0, self.beta0))
# use plate to indicate that the observations are
# conditionally independent given f and get vectorization
with pyro.plate("data_plate"):
# observe all ten datapoints using the bernoulli likelihood
pyro.sample("obs", dist.Bernoulli(f), obs=self.data)

def guide(self, use_decaying_avg_baseline):
# register the two variational parameters with pyro
alpha_q = pyro.param("alpha_q", torch.tensor(self.alpha_q_0),
constraint=constraints.positive)
beta_q = pyro.param("beta_q", torch.tensor(self.beta_q_0),
constraint=constraints.positive)
# sample f from the beta variational distribution
baseline_dict = {'use_decaying_avg_baseline': use_decaying_avg_baseline,
'baseline_beta': 0.90}
# note that the baseline_dict specifies whether we're using
# decaying average baselines or not
pyro.sample("latent_fairness", NonreparameterizedBeta(alpha_q, beta_q),
infer=dict(baseline=baseline_dict))

def do_inference(self, use_decaying_avg_baseline, tolerance=0.80):
# clear the param store in case we're in a REPL
pyro.clear_param_store()
# setup the optimizer and the inference algorithm
optimizer = optim.Adam({"lr": .0005, "betas": (0.93, 0.999)})
svi = SVI(self.model, self.guide, optimizer, loss=TraceGraph_ELBO())
print("Doing inference with use_decaying_avg_baseline=%s" % use_decaying_avg_baseline)

# do up to this many steps of inference
for k in range(self.max_steps):
svi.step(use_decaying_avg_baseline)
if k % 100 == 0:
print('.', end='')
sys.stdout.flush()

# compute the distance to the parameters of the true posterior
alpha_error = param_abs_error("alpha_q", self.alpha_n)
beta_error = param_abs_error("beta_q", self.beta_n)

# stop inference early if we're close to the true posterior
if alpha_error < tolerance and beta_error < tolerance:
break

print("\nDid %d steps of inference." % k)
print(("Final absolute errors for the two variational parameters " +
"were %.4f & %.4f") % (alpha_error, beta_error))

# do the experiment
bbe = BernoulliBetaExample(max_steps=max_steps)
bbe.do_inference(use_decaying_avg_baseline=True)
bbe.do_inference(use_decaying_avg_baseline=False)

Sample output:

1
2
3
4
5
6
7
8
Doing inference with use_decaying_avg_baseline=True
....................
Did 1932 steps of inference.
Final absolute errors for the two variational parameters were 0.7997 & 0.0800
Doing inference with use_decaying_avg_baseline=False
..................................................
Did 4908 steps of inference.
Final absolute errors for the two variational parameters were 0.7991 & 0.2532

对于这个特别的运行,我们可以看到基线基本减半了SVI步数。结果是随机的,每次都会变换,但是这仍是个正奋人心的结果。尽管这是个设计过的例子,但对于特定的model和guide组合,基线可以提供确实的好处。

参考

[1] Automated Variational Inference in Probabilistic Programming, David Wingate, Theo Weber

[2] Black Box Variational Inference, Rajesh Ranganath, Sean Gerrish, David M. Blei

[3] Auto-Encoding Variational Bayes, Diederik P Kingma, Max Welling

[4] Gradient Estimation Using Stochastic Computation Graphs, John Schulman, Nicolas Heess, Theophane Weber, Pieter Abbeel

[5] Deep Amortized Inference for Probabilistic Programs Daniel Ritchie, Paul Horsfall, Noah D. Goodman

[6] Neural Variational Inference and Learning in Belief Networks Andriy Mnih, Karol Gregor

Pyro SVI 第二部分:条件独立,二次取样和摊销

Posted on 2020-03-20

目标:拓展SVI到大数据集

对于一个有N个观察的模型,跑model和guide,建立ELBO这两件事涉及了估计对数概率密度函数,而这个估计的复杂程度挺糟糕的。如果我们想要扩展到大数据集,这将是个问题。幸运的是,ELBO目标天然支持二次采样,只要我们的model/guide有一些可供我们使用的条件独立的结构。比方说,当观察对隐变量条件独立,ELBO中的对数似然就可以被近似为:

Read more »

Pyro SVI 第一部分:随机变分推断简介

Posted on 2020-03-20

支持随机变量推断作为一个通用的推断算法被重点设计在Pyro之中。现在我们就来看一下Pyro中我们如何使用变分推断。

Read more »

循环神经网络

Posted on 2020-03-19

动机

无论是简单的FNN,还是CNN,异或是GAN,似乎都只关心一次性的输入数据,有什么办法能处理一串数据么?

或者说有什么办法能够利用之前学习到的知识,作用在之后的学习上么?

所以我们有了循环神经网络。

Read more »
123
Lifan Zhao

Lifan Zhao

23 posts
10 tags
Github Linkedin E-Mail
© 2022 Lifan Zhao
Powered by Hexo
|
Theme — NexT.Muse v5.1.4