Zhangzhe's Blog

The projection of my life.

0%

URL

https://arxiv.org/pdf/1901.05555.pdf

TL;DR

  • 本文提出一种在 不平衡数据分类 场景使用的 Loss —— Class-Balanced Loss
  • 提出一个理论模型,对每类的 有效样本数量 进行估计,从而对每类设计损失权重
  • 理论可概括为:对某一类的所有样本(样本容量为 n)进行采样,每一次采样,有 p 的概率和之前采样过的样本 重复,有 1-p 的概率不重复,n 越大,冲突可能越大,所以 p 越大
  • 该理论模型简化后可用数学归纳法证明,Class-Balanced Loss 最终化简为包含一个超参 β\beta 的权重系数

Algorithm

常用的不平衡数据处理方法

  • 重采样
    • 对大类欠采样
      • 缺点:学习能力变差
    • 对小类过采样
      • 缺点:过拟合
      • 缺点:训练变慢
    • both
  • 重赋权
    • 以类间样本容量比例直接作为权重
      • 缺点:虽然最为常用,但不科学,因为样本容量的比值不能代替样本中有效样本的比值

有效样本

  • 本文提出一种类中有效样本的计算方式,类中样本容量用 nZ>0n \in \mathbb Z_{>0} 表示,有效样本量用 NZ>0N \in \mathbb Z_{>0} 表示,有效样本的期望用 EnZ>0E_n \in \mathbb Z_{>0} 表示
    En=1βn1β,    β=N1NE_n = \frac{1-\beta^n}{1-\beta},\ \ \ \ \beta=\frac{N-1}{N}
    cbloss1.png
  • 实际使用时,β\beta 为一个超参,取值范围:{0.9, 0.99, 0.999, 0.9999}

实际使用时的损失函数

  • 理论模型只提供一个权重,实际使用时还需要结合其他的分类损失函数,例如 [Softmax Loss(交叉熵), Sigmoid Loss, Focal Loss]

    CB(p,y)=1EnyL(p,y)=1β1βnyL(p,y)CB(p, y) = \frac{1}{E_{n_y}} L(p, y)=\frac{1-\beta}{1-\beta^{n_y}}L(p, y)

    其中,p[0,1]p \in [0, 1] 表示输入样本 x 后模型输出的各类的概率分布,yy 表示样本 xlabelβ\beta 是一个超参数,L(p,y)L(p, y) 是分类常用损失函数

  • class-balanced softmax cross-entropy loss
    CBsoftmax(z,y)=1β1βnylog(exp(zy)j=1Cexp(zj))CB_{softmax}(z, y) = -\frac{1-\beta}{1-\beta^{n_y}}log(\frac{exp(z_y)}{\sum_{j=1}^C exp(z_j)})

  • class-balanced sigmoid cross-entropy loss
    CBsigmoid(z,y)=1β1βnyi=1Clog(11+exp(zit))CB_{sigmoid}(z, y) = -\frac{1-\beta}{1-\beta^{n_y}}\sum_{i=1}^C log(\frac{1}{1+exp(-z_i^t)})

  • class-balanced focal loss
    CBfocal(z,y)=1β1βnyi=1C(1pit)γlog(pit)CB_{focal}(z, y) = -\frac{1-\beta}{1-\beta^{n_y}}\sum_{i=1}^C (1-p_i^t)^\gamma log(p_i^t)
    γ{0.5,1,2}\gamma \in \{0.5, 1, 2\}

Thought

  • 理论被不停简化,条件过于理想化,最后变成一个很简单的公式
  • 和其他损失函数结合后,准确率比较随机

效果

  • 其中 Imbalanced factor=Sample size for largest classSample size for least classImbalanced\ factor = \frac{Sample\ size\ for\ largest\ class}{Sample\ size\ for\ least\ class}
    cbloss2.png
    cbloss3.png
    cbloss4.png
    cbloss5.png

URL

https://arxiv.org/pdf/2007.11301.pdf

TL;DR

  • 深度学习在光栅图上取得了极大的成功,但在矢量图上的表示和应用未被探索,矢量图相较于光栅图有无损缩放能力
  • 本文给出一种便于深度学习使用的矢量图表示方法,且将 SVG 的最小表示集合缩小为 {<path>}
  • 本文提出一个 SVG 数据集 SVG-Icons8

Dataset/Algorithm/Model/Experiment Detail

SVG 图像的结构化表示

  • 一个 SVGNpN_ppath 组成,即 V={P1,...,PNp}V = \{P_1, ..., P_{N_p}\}
  • 一个 path 由一个三元组表示,即 Pi={Si,fi,vi},  Si:shape,  fi:fill property,  vi:visibilityP_i = \{S_i, f_i,v_i\},\ \ S_i:shape,\ \ f_i:fill\ property,\ \ v_i: visibility
  • 一个 shapeNcN_c 个 command 组成,即 Si={Ni1,...,NiNc}S_i = \{N_i^1,...,N_i^{N_c}\}
  • fi{0,1,2},  vi{0,1}f_i\in\{0,1,2\}, \ \ v_i\in\{0,1\}
  • 一个 command 由一个二元组表示,即 Cij=(cij,Xij)C_i^j = (c_i^j,X_i^j) ,分别表示 command type 和 argument
  • command type \in {<SOS>, <M>, <L>, <C>, <Z>, <EOS>}
  • 一个 command argument 由一个六元组表示,即 Xij=(qx1,ij,qy1,ij,qx2,ij,qy2,ij,x2,ij,y2,ij)X_i^j = (q^j_{x_1,i},q^j_{y_1,i},q^j_{x_2,i},q^j_{y_2,i},x^j_{2,i},y^j_{2,i}) ,默认值为 -1,使用六元组的原因是对齐 <C> 的参数长度
  • 为了简化 Nc, NpN_c, \ N_p 都采用确定值

SVG Embedding

每个 command CiC_i 被映射到一个 dEd_E 维的向量 eije_i^jeij=ecmd,ij+ecoord,ij+eind,ije_i^j = e_{cmd,i}^j + e_{coord,i}^j + e_{ind,i}^j

  • command embedding
    ecmd,ij=Wcmd δcijRdEe_{cmd,i}^j = W_{cmd}\ \delta_{c_i^j}\in\mathbb{R}^{d_E} ,其中 WcmdRdE×6,  δcijR6,  δcij is one hot vectorW_{cmd} \in \mathbb{R}^{d_E\times 6},\ \ \delta_{c_i^j}\in\mathbb{R}^6,\ \ \delta_{c_i^j}\ is \ one \ hot \ vector
  • coordinate embedding
    ecoord,ij=Wcoord vector(WX Xij)RdE,   Xij=[qx1,ij,qy1,ij,qx2,ij,qy2,ij,x2,ij,y2,ij]R257×6e_{coord,i}^j = W_{coord}\ vector(W_X\ X_i^j)\in \mathbb{R}^{d_E}, \ \ \ X_i^j = [q^j_{x_1,i},q^j_{y_1,i},q^j_{x_2,i},q^j_{y_2,i},x^j_{2,i},y^j_{2,i}] \in \mathbb{R} ^{257 \times 6}
  • index embeding
    eind,ij=Wind δjRdE,  WindRdE×Ns,   δj is one hot vectore_{ind,i}^j =W_{ind}\ \delta_j \in \mathbb{R}^{d_E}, \ \ W_{ind}\in\mathbb{R}^{d_E\times N_s},\ \ \ \delta_j\ is \ one\ hot \ vector

path 标签使用方式

svg1.png

SVG-Icon8 数据集样例

svg2.png

DeepSVG 网络结构

  • 一个 VAE 结构,由两层 Encoder 和 两层 Decoder 构成
    svg3.png

Thoughts

  • 本文提出的 SVG 结构化表示有利于应用矢量图作为神经网络的输入
  • 本文的 SVG 数据集都是矢量 Icon,只包含 path 标签且无填充无透明度,对于真实光栅图应该用 path 标签 + 填充 + 透明度来表示,即拓展上述的 SVG 表示

URL

https://arxiv.org/pdf/1809.02966.pdf

TL;DR

  • 提出一种端到端的可训练的优化方法,通过近似 Hessian 优化方法,解决非线性最小二乘法问题
  • 从训练数据中隐式的学习正则化与先验信息
  • 第一个将可学习的优化器用于单目视觉光度误差估计任务中

Algorithm

背景知识

非线性最小二乘法求解

  • 最小二乘法问题: E=12jrj2(x),     rj(x)E = \frac{1}{2}\sum_{j} r_j^2(x),\ \ \ \ \ r_j(x) 表示 x 第 j 项的 L1 误差
  • 常用方法: Gauss-Newton (GN)Levenberg-Marquadt (LM)
  • 求解过程:
    • 对误差进行一阶估计: r(xi+Δxi)=r(xi)+JiΔxi,   Ji=drdxx=xir(x_i+\Delta x_i)=r(x_i)+J_i\Delta x_i,\ \ \ J_i = \frac{dr}{dx}|_{x=x_i} ,J 是雅各比矩阵
    • 最优变化量: Δxi=argΔximin12ri+JiΔxi2\Delta x_i=\arg_{\Delta x_i}\min \frac{1}{2}||r_i+J_i\Delta x_i||^2
    • GN 法获得最优变化量: JiTJiΔxi=JiTriJ_i^TJ_i\Delta x_i = - J_i^Tr_i ,如果 JiTJiJ_i^TJ_i 可逆,则最优变化量 Δxi=(JiTJi)1JiTri\Delta x_i=-(J_i^TJ_i)^{-1}J_i^Tr_i
    • LM 法获得最优变化量(在 GN 的基础上加入超参数—— 阻尼系数 λ\lambda): Δxi=(JiTJi+λ diag(JiTJi))1JiTri\Delta x_i=-(J_i^TJ_i + \lambda \ diag(J_i^TJ_i))^{-1}J_i^Tr_i
    • 本方法:基于 GN 加入了更多的可学习参数,使用梯度下降优化

任务描述

  • 输入一段图像序列,输出深度估计(depth)与姿态估计(pose),为了估计较大范围的深度,所以网络实际估计深度的倒数: z=1dz = \frac{1}{d}
  • 所以本任务优化目标函数: E(x)=12r(x)2,   x=(z,p)E(x) = \frac{1}{2}||r(x)||^2,\ \ \ x=(z, p)

网络结构

网络结构包含 bootstrap networkiterative networkrefinement network

  • bootstrap network: 生成低分辨率( H4,W4\frac{H}{4}, \frac{W}{4} )的粗糙估计(一个简单的包含下采样的CNN)
  • iterative network:重复迭代与细化,本文使用 LSTM (非线性最小二乘法优化也用于此处)
  • refinement network:上采样(双线性插值法)
    lsnet_1.png

iterative network 优化过程

lsnet_2.png

  • 其中 fθ0f_{\theta_0} 表示 bootstrap networkfθf_{\theta} 表示 Convolutional LSTM Cell
  • 由于 J 具体空间局部性,所以这里使用的 LSTM 是 Convolutional LSTM
  • [Δxihi+1]=LSTMcell(Φ(Ji,ri),hi,xi;θ),   xi+1=xi+Δxi\begin{bmatrix} \Delta x_i\\ h_{i+1} \end{bmatrix} = LSTM_{cell}(\Phi(J_i,r_i),h_i,x_i;\theta),\ \ \ x_{i+1} = x_i + \Delta x_i ,这里的 xix_i 并不是真的输入到 LSTM 中,如 Algorithm 1 所示, xix_i 用来产生 JiJ_i 从而产生 Φ(Ji,ri)\Phi(J_i, r_i)
  • 其中雅各比矩阵的变形 Φ(Ji,ri)=[JTJ,r]\Phi(J_i,r_i) = [J^TJ,r]
    • 理论上 Φ(Ji,ri)=[(JTJ)1J,r]\Phi(J_i,r_i) = [(J^TJ)^{-1}J,r] ,但由于求逆会引入较大的计算量,并且不会产生额外的信息量,所以简化 Φ(Ji,ri)=[JTJ,r]\Phi(J_i,r_i) = [J^TJ,r]
    • 由于雅各比矩阵是稀疏的,所以使用了下图的方法对 JTJJ^TJ 进行了压缩
      lsnet_3.png

损失函数

  • depth 与 pose 的 L1 误差的加权和

Thoughts

  • 本文的创新点在于 Convolutional LSTM 中输入的不是 xix_i ,而是压缩后的二阶雅各比矩阵,用来拟合 Δxi\Delta x_i ,可以通过近似 GN 法,产生超一阶优化的效果
  • GNΔxi=(JiTJi)1JiTri\Delta x_i=-(J_i^TJ_i)^{-1}J_i^Tr_i ,本文: Δxi=LSTM(JiTJi,ri)\Delta x_i=LSTM(J_i^TJ_i,r_i) ,即把 [(JiTJi)1Ji,ri]>[JiTJi,ri][(J_i^TJ_i)^{-1}J_i,r_i] --> [J_i^TJ_i,r_i] 并加入了 LSTM 梯度下降优化
  • 本文的网络没有官方开源,也找不到民间实现,所以对网络的细节不是特别明白

URL

https://dl.acm.org/doi/pdf/10.1145/3219819.3220007

TL;DR

  • 本文提出一种多任务神经网络结构,称为 Multi-gate Mixture-of-Experts 简称 MMOE
  • 与传统多任务网络共享 bottom 相比,该结构可以在 任务相关性较弱 的情况下有较好的鲁棒性
  • MMOE 中的 Multi-gate 本质就是一种 Softmax Attention,针对不同的任务给出不同的专家组合

Algorithm

总体网络结构

mmoe1.png

其中 AB 分别表示两个 任务Tower 表示与任务相关的金字塔头部,Expert 表示专家 bottom network,Gate 表示任务相关的权重生成网络

  • 上图 a 表示 Bottom Shared Architecture: 传统共享 bottom network 的多任务结构,共享 bottom network (Backbone) 进行特征提取,将提取到的特征分别送入任务相关头部,缺点是如果任务 AB 之间的相关性较弱,那么共用一个 Backbone 是危险的
  • 上图 b 表示 One-gate Mixture-of-Experts Architecture,有多个 ExpertBackbone 进行不同维度的特征提取,只有一个 Gate network 用于给每个任务生成 Expert 权重
  • 上图 c 表示 Multi-gate Mixture-of-Experts Architecture,有多个 ExpertBackbone 进行不同维度的特征提取,每个任务有单独的 Gate network 生成唯一的 Expert 权重

数学定义

  • Bottom Shared
    yk=hk(f(x))y_k = h^k(f(x))

    其中 kk 表示 任务数f()f() 表示 shared bottomhkh^k 表示 第 k 个任务的 Tower

  • OMOE
    yk=hk(i=1ng(x)ifi(x))y_k=h^k(\sum_{i=1}^n g(x)_i f_i(x)), where i=1ng(x)i=1,  g(x)Rn\sum_{i=1}^n g(x)_i=1,\ \ g(x) \in \mathbb R^n
    其中 nn 表示 专家数gg 表示 Gate network(由于 g(x)g(x) 要经过 Softmax,使得 logits -> prob,所以 i=1ng(x)i=1\sum_{i=1}^n g(x)_i=1

  • MMOE
    yk=hk(i=1ngk(x)ifi(x))y_k=h^k(\sum_{i=1}^n g^k(x)_i f_i(x)), where i=1ngk(x)i=1\sum_{i=1}^n g^k(x)_i=1
    gk(x)=softmax(Wgkx)g^k(x)=softmax(W_{gk}x),其中 xRd,  WgkRn×d, so  gk(x)Rnx \in \mathbb R^d,\ \ W_{gk} \in \mathbb R^{n\times d}, \ so \ \ g^k(x) \in \mathbb R^n
    OMOE 不同之处在于: 每个任务有单独的 Gate network,不共享

Thoughts

  • 是有效的优化,针对任务相关性差的多任务场景,确实能有效涨点
  • 本质是一种参数的堆砌,没看到很创新的点
  • 除了堆参数之外,还有一个很致命的问题,每个 Gate 以及 Expert 都是独立的,实际实现过程中只能使用 for loop 依次计算,效率很低,速度很慢

Experiments

mmoe2.png
mmoe3.png
mmoe4.png

URL

https://arxiv.org/pdf/2009.04759.pdf

TL;DR

  • 本文将常见的激活函数分为两大类,基于 Maxout 和基于 Smooth maximum
  • 基于 Maxout 的主要是 XXXReLU 家族
  • 基于 smooth maximum 的本文命名为 activate or not 家族,著名的 Swish 在 β=1\beta=1 时就是 ACON-A

Dataset/Algorithm/Model/Experiment Detail

Smooth maximumn

  • Sβ(x1,...,xn)=i=1nxi×eβxi=1neβxS_{\beta}(x_1,...,x_n) = \frac{\sum_{i=1}^nx_i \times e^{\beta x}}{\sum_{i=1}^n e^{\beta x}} ,当 β,Sβmax\beta \rightarrow \infty, S_\beta \rightarrow max ,当 β0,Sβmean\beta \rightarrow 0, S_\beta \rightarrow mean
  • 当 n = 2 时, Sβ(ηa(x),ηb(x))=(ηa(x)ηb(x))×σ[β(ηa(x)ηb(x))]+ηb(x)S_\beta(\eta_a(x),\eta_b(x)) = (\eta_a(x)-\eta_b(x))\times\sigma[\beta(\eta_a(x)-\eta_b(x))]+\eta_b(x) ,其中: σ\sigma 表示 Sigmoid, η\eta 表示 per channle 的线性函数
    acon1.png

Meta-ACON

  • ACON 中的 β\beta 从一个 learnable parameter 变成一个 network,ACON -> Meta-ACON,这里的 network 与 SENet 中的 channel-scale 用到的两层 fc 结构相同

代码 (ACON-C 和 Meta-ACON-C)

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
import torch
from torch import nn
class AconC(nn.Module):
r"""ACON activation (activate or not).
# AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter
# according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
"""
def __init__(self, width):
super().__init__()
self.p1 = nn.Parameter(torch.randn(1, width, 1, 1))
self.p2 = nn.Parameter(torch.randn(1, width, 1, 1))
self.beta = nn.Parameter(torch.ones(1, width, 1, 1))
def forward(self, x):
return (self.p1 * x - self.p2 * x) * torch.sigmoid(
self.beta * (self.p1 * x - self.p2 * x)
) + self.p2 * x
class MetaAconC(nn.Module):
r"""ACON activation (activate or not).
# MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network
# according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
"""
def __init__(self, width, r=16):
super().__init__()
self.fc1 = nn.Conv2d(
width, max(r, width // r), kernel_size=1, stride=1, bias=True
)
self.bn1 = nn.BatchNorm2d(max(r, width // r))
self.fc2 = nn.Conv2d(
max(r, width // r), width, kernel_size=1, stride=1, bias=True
)
self.bn2 = nn.BatchNorm2d(width)
self.p1 = nn.Parameter(torch.randn(1, width, 1, 1))
self.p2 = nn.Parameter(torch.randn(1, width, 1, 1))
def forward(self, x):
beta = torch.sigmoid(
self.bn2(
self.fc2(
self.bn1(
self.fc1(
x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True)
)
)
)
)
)
return (self.p1 * x - self.p2 * x) * torch.sigmoid(
beta * (self.p1 * x - self.p2 * x)
) + self.p2 * x

效果

acon2.png

Thoughts

  • 是一种动态上下界的几乎函数,并很 general 的解释了 Smooth maximum 机制的作用

URL

https://arxiv.org/pdf/2104.13371.pdf

TL;DR

  • BasicVSRPropagationAlignment 组件进行了加强,达到了新的 SOTA
  • Propagation 的加强主要是把 BasicVSR 使用的单层双向传播结构改成了 多层 + 双向 + 二阶传播
  • Alignment 的加强主要是把 BasicVSR 使用的基于光流估计的对齐方式改成了基于光流估计指导的可变形卷积对齐,光流估计 + warp 的对齐方式似乎比可变形卷积要弱,可变形卷积单独训练容易崩,二者结合效果更好

Dataset/Algorithm/Model/Experiment Detail

Propagation

  • 加入了二阶(跳帧)传播
    1.png

Alignment

2.png
3.png
使用一个比较复杂的对齐结构(论文中对齐过程的数学表达式写的很清楚),通过 光流估计 + Warp + 残差 生成 DCN 的 offset 和 mask,再通过 DCN 对齐

最终结果

4.png

Thoughts

  • 目前还没有开源代码,但是从结构上看 BasicVSR++ 集成了 BasicVSR 的大部分结构 + IConVSR 的 Propagation 级联结构 + EDVR 的可变形卷积特征对齐
  • mmediting repo 中还是有不少可以借鉴的结构,比如 DCN bloack 这些对齐结构就很 make sense

URL

https://arxiv.org/pdf/2012.02181.pdf

TL;DR

  • 将 VSR 任务所需的网络结构拆分成四个部分,分别是 PropagationAlignmentAggregationUpsampling,并对常见的 VSR 模型进行了总结
  • 只使用常见结构没有使用奇怪操作建立了 BasicVSR 结构和针对 BasicVSR 的改进版 IconVSR,达到了当时的 SOTA
  • 代码开源在:mmediting

BasicVSR

对常见的 VSR 模型结构的总结

bvsr1.png

BasicVSR 总体结构

bvsr2.png

Propagation

  • 从重建后 PSNR 角度证明了 双向传播结构比单向传播结构和局部不传播结构更好

Alignment

  • 同样从重建后 PSNR 角度证明了 VSR 任务中,特征对齐比图像对齐和不对齐效果更好,相较于特征对齐,图像对齐重建后平均 PSNR 降低 0.17dB,不对齐重建后平均 PSNR 降低 1.19dB
  • 本文的对齐模块使用基于光流对齐的方式,即: 双向视频光流估计 + Warp feature + 残差,光流估计网络用的 SPyNet

Aggregation

  • 双向传播 + 双向对齐后的 feature 直接 concat

Upsampling

  • PixelShuffle

IconVSR

bvsr3.png

在 BasicVSR 的基础上增强了 PropagationAggregation 两个部分:

  • Aggregation 部分加入了一个 Information-Refill 结构,对关键帧额外做一次图像级的前后帧信息融合,从代码上看是用 EDVR 做前后帧信息融合
  • Propagation 是将之前的 Bidirectional Propagation 变成 Coupled Bidirectional Propagation,具体来说就是将 BasicVSR 中的独立的双向传播变成了串联的双向传播

最终结果

bvsr4.png

Thoughts

  • 将 VSR 任务的模型结构解耦,每个部分单独做 Ablation experiment,感觉作为一个 VSR 任务的 baseline 是不错的

URL

https://arxiv.org/pdf/2004.02803.pdf

TL;DR

  1. Deformable 3D 简称 D3D,是 C3DDeformable
  2. 在视频超分中引入了可变形3D卷积,看上去很合理
  3. 使用的超分网络结构很简单,与 VDSR 有一点相似

Dataset/Algorithm/Model/Experiment Detail

Algorithm

1. D3D:3D 卷积的可变形版本(或者说可变性卷积的3D版)

deform1.png
可变形2D卷积全过程(图来自论文Deformable Convolutional Networks
deform2.png
可变形3D卷积全过程 (图来自本论文)您这也太像了吧

C3D计算过程:


$y(p_0) = \sum_{n=1}^Nw(p_n)*x(p_0 + p_n)$
其中 $p_0$ 表示卷积核中心所在feature上的位置, $p_n$ 表示卷积核到中心偏移,由于是C3D所以, $N=27$ , $p_n = \{(-1,-1,-1), (-1,-1,0),...,(1,1,0),(1,1,1)\}$ ### D3D计算过程
$y(p_0) = \sum_{n=1}^Nw(p_n)*x(p_0 + p_n + \Delta p_n)$
$p_n$ 表示到卷积核到原始位置的偏移, $p_n + \Delta p_n$ 表示卷积核到中心偏移 ## 2. 超分网络结构 ![deform3.png](https://i.loli.net/2021/09/04/qNWlp6C1T4X8uw3.png) **图中’Conv‘表示C3D,3x3 Conv表示2D Conv** 输入:连续 3 / 5 / 7 frames ## Thoughts 1. 对比了C3D和D3D的效果,说明D3D还是有点用的 2. 与[EDVR](https://arxiv.org/pdf/1905.02716.pdf)对比可知,即使D3D单个算子再强大,网络设计也十分重要! 3. 速度好慢,flops好大 4. 脑补[C3D](https://ieeexplore.ieee.org/document/7410867)的[DConv](https://openaccess.thecvf.com/content_ICCV_2017/papers/Dai_Deformable_Convolutional_Networks_ICCV_2017_paper.pdf)作者会由衷的说一句:优(jiu)秀(zhe?) ## 3. 算法效果对比 ![deform4.png](https://i.loli.net/2021/09/04/ZBLQHNac3ixsXuk.png) ![deform5.png](https://i.loli.net/2021/09/04/rvE5inczPky7uTQ.png) 输入帧数与算法效果的关系: ![deform6.png](https://i.loli.net/2021/09/04/WUAOTtvZhLYzDXu.png) ![deform7.png](https://i.loli.net/2021/09/04/g9zBL8kYeuIWR5U.png) ![deform8.png](https://i.loli.net/2021/09/04/9uJvpgMiqDU1WHR.png) 为什么不和[paperswithcode](https://paperswithcode.com/sota/video-super-resolution-on-vid4-4x-upscaling)里的VSR模型比一比? **Vid4数据集上:** ![deform9.png](https://i.loli.net/2021/09/04/jJkKzqVPmxDH5hA.png) 论文中对比结果巧妙的避开了前五(截图于 2020-08-01),~~优秀~~

URL

https://arxiv.org/pdf/2007.00649.pdf

TL;DR

  • 传统的集成学习能提高算法效果,但是深度学习多 model 集成学习实在是太慢了
  • 所以作者提出一种深度学习多 group 集成学习,本质是在网络的末尾处使用 分组卷积,分成多路,每一路独立监督,监督得到的 loss 加权求和 作为总 loss,然后反向传播、优化,优点是:理论上不产生额外计算量
  • 加权求和的方式一共有三种,分别是 Group AveragingGroup WaggingGroup Boosting

Algorithm

Group Ensemble 与 Model Ensemble 的区别

group10.png
group1.png

网络结构

网络结构

加权方式

  • Loss=1i=1mWiLiLoss = \frac{1}{\sum_{i=1}^m}W_i*L_iLiL_i 表示第 i 个分支上的损失, WiW_i 表示对应权重
  • Group Averaging
    • Wi=1,     i=1,2,...,mW_i = 1, \ \ \ \ \ i = 1, 2, ..., m
  • Group Wagging
    • WiN(1,δ2),     i=1,2,...,mW_i \sim N(1, \delta^2), \ \ \ \ \ i = 1, 2, ..., m
  • Group Boosting
    • Wi=log(Pi1T),     i=2,3,...,mW_i = -log(\frac{P_{i-1}}{T}), \ \ \ \ \ i = 2, 3, ..., m
      • 其中 T 表示 温度,类似于模型蒸馏时的蒸馏温度
      • Pi1P_{i-1} 表示上一个分支算对的概率
      • 即上一个分支预测的越正确,本分支的权重就越小,这与 boosting 还真的有点像
        group2.png

最终效果

  • ImageNet 数据集上,top-1 errorResNeXt-50 降低了 1.83%
  • 几乎不改变 Flopsparams,在几乎所有网络上使用都会有明显提升
  • 在多种任务中都能提高成绩,包括:
    • 目标检测
    • 动作识别
    • 图像识别

Thoughts

  • Group Boosting 这种串行计算 loss 权重的方法确定在 inference 阶段不会影响速度?
  • 为什么在 CIFAR 数据集上,Group Wagging 这种随机方法反而效果好

对比表格

group3.png
group4.png
group5.png
group6.png
group8.png
group7.png
group9.png

URL

https://arxiv.org/pdf/1606.06160.pdf

TL;DR

  • DoReFa-Net是一种神经网络量化方法,包括对weights、activations和gradients进行量化
  • 量化模型的位宽重要性:gradient_bits > activation_bits > weight_bits

Algorithm

算法与实现角度理解:

总体流程

dorefa

quantization of weights (v1) (上图 fωWf_\omega^W )

  • STE (straight-through estimator)
    一种对本身不可微函数(例如四舍五入函数round()、符号函数sign()等)的手动指定微分的方法,量化网络离不开STE

  • 当1 == w_bits时:
    Forward:ro=sign(ri)×EF(ri)Forward: r_o = sign(r_i) \times E_F(|r_i|)
    Backward:cri=croBackward: \frac{\partial c}{\partial r_i} = \frac{\partial c}{\partial r_o}
    其中 EF(ri)E_F(|r_i|) 表示weight每层通道的绝对值均值

  • 当1 < w_bits 时:
    Forward_v1:ro=2quantizek(tanh(ri)2max(tanh(ri))+12)1Forward\_v1: r_o = 2 quantize_k(\frac{tanh(r_i)}{2max(|tanh(r_i)|)} + \frac{1}{2}) - 1

    Backward:cri=crororiBackward: \frac{\partial c}{\partial r_i} = \frac{\partial c}{\partial r_o} \frac{\partial r_o}{\partial r_i}
    其中 quantize_k()函数是一个量化函数,使用类似四舍五入的方法,将 [0,1,232][0, 1, 2^{32}] 之间离散的数聚类到 [0,1,2w_bits][0, 1, 2^{w\_bits}]

    • quantize_k():
      $ Forward: r_o = \frac{1}{2k-1}round((2k-1)r_i)$

      Backward:cri=croBackward: \frac{\partial c}{\partial r_i} = \frac{\partial c}{\partial r_o}

  • quantization of weights 源码

    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
    def uniform_quantize(k):
    class qfn(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input):
    if k == 32:
    out = input
    elif k == 1:
    out = torch.sign(input)
    else:
    n = float(2 ** k - 1)
    out = torch.round(input * n) / n
    return out
    @staticmethod
    def backward(ctx, grad_output):
    # STE (do nothing in backward)
    grad_input = grad_output.clone()
    return grad_input
    return qfn().apply
    class weight_quantize_fn(nn.Module):
    def __init__(self, w_bit):
    super(weight_quantize_fn, self).__init__()
    assert w_bit <= 8 or w_bit == 32
    self.w_bit = w_bit
    self.uniform_q = uniform_quantize(k=w_bit)
    def forward(self, x):
    if self.w_bit == 32:
    weight_q = x
    elif self.w_bit == 1:
    E = torch.mean(torch.abs(x)).detach()
    weight_q = self.uniform_q(x / E) * E
    else:
    weight = torch.tanh(x)
    max_w = torch.max(torch.abs(weight)).detach()
    weight = weight / 2 / max_w + 0.5
    weight_q = max_w * (2 * self.uniform_q(weight) - 1)
    return weight_q

quantization of activations (上图 fαAf_\alpha^A )

  • 对每层输出量化
    $ f^A_\alpha = quantize_k®$

quantization of gradients (上图 fγGf_\gamma^G )

  • 对梯度量化
    fγk(dr)=2max0(dr)[quantizek[dr2max0(dr)+12+N(k)]12]f^k_\gamma(dr)=2max_0(|dr|)[quantize_k[\frac{dr}{2max_0(|dr|)} + \frac{1}{2} + N(k)] - \frac{1}{2}]
    其中:$ dr $ 表示backward上游回传的梯度, kk 表示 gradient_bits, N(k)N(k) 表示随机均匀噪声N(k)=σ2k1,   σUniform(0.5,0.5)N(k) = \frac{\sigma}{2^k-1},\ \ \ \sigma \sim Uniform(-0.5, 0.5)
  • 由于模型端上inference阶段不需要梯度信息,而大多数模型也不会在端上训练,再加上低比特梯度训练会影响模型精度,所以对梯度的量化大多数情况下并不会使用

其他方面

  • 由于最后一层的输出分布与模型中输出的分布不同,所以为了保证精度,不对模型输出层output做量化(上图step 5, 6)
  • 由于模型第一层的输入与中间层输入分布不同,而且输入通道数较小,weight不量化代价小,所以 第一层的weight做量化
  • 使用多步融合,不保存中间结果会降低模型运行是所需内存