残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用

它叫ResNeXt WSL,有超过8亿个参数,用Instagram上面的9.4亿张图做了 (弱监督预训练) ,用ImageNet做了微调。
背景介绍:残差网络的发展

● ResNet (2015)

传统网络出现的问题:

深度学习中的基础网络的发展从ALexNet(5个卷积层)、VGG(19个卷积层)到GoogLeNet(22个卷积层),网络的结构在不断变深。这是因为更深的网络可以进行更加复杂的特征模式的提取,从而理论上更深的网络可以得到更好的结果。但是通过简单的叠加层的方式来增加网络深度,可能引来梯度消失/梯度爆炸的问题:

  • “梯度消失”:指的是即当梯度(小于1.0)在被反向传播到前面的层时,重复的相乘可能会使梯度变得无限小。
  • “梯度爆炸”:指的是即当梯度(大于1.0)在被反向传播到前面的层时,重复的相乘可能会使梯度变得非常大甚至无限大导致溢出。

因此随着网络深度的不断增加,常常会出现以下两个问题:

  • 长时间训练但是网络收敛变得非常困难甚至不收敛(这个问题很大程度已被标准初始化和中间标准化层解决)。
  • 网络性能会逐渐趋于饱和,甚至还会开始下降,可以观察到下图中56层的误差比20层的更多,故这种现象并不是由于过拟合造成的。这种现象称为深度网络的退化问题。

残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用_第1张图片

?contribution:

  • 将层变为学习关于层输入的残差函数,而不是学习未参考的函数。
  • bottleneck design

优点:

  • 相比传统的卷积神经网络如VGG复杂度降低,需要的参数下降
  • 可以做到更深,不会出现梯度弥散的问题。
  • 优化简单,分类准确度加深由于使用更深的网络
  • 解决深层次网络的退化问题

残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用_第2张图片
在输入与输出之间(称为堆积层)引入一个前向反馈的shortcut connection,这有点类似与电路中的“短路”,也是文中提到identity mapping(恒等映射y=x,也就是输入与输出是相等的映射关系。)ResNet通过引入残差网络结构(residual network),解决了退化问题。其主要思想是将堆叠的非线性层从,拟合原来的最优解映射输出H(X),变成去,拟合输出和输入的差F(X) = H(X) - X,X为输入,此时原最优解映射H(X)就可以改写成F(X) + X。而作者认为这两种表达的效果相同,但是优化的难度却并不相同,作者假设F(x)的优化会比H(x)简单的多。这一想法也是源于图像处理中的残差向量编码,通过一个reformulation,将一个问题分解成多个尺度直接的残差问题,能够很好的起到优化训练的效果。

残差映射跟原映射相比更容易被优化。比如把5映射到5.1,那么引入残差前是F’(5) = 5.1,引入残差后是H(5) = 5.1, H(5) = F(5) + 5, F(5) = 0.1。这里的F’和F都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如s输出从5.1变到5.2,映射F’的输出增加了1/51=2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。后者输出变化明显对权重的调整作用更大,所以效果更好。
残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用_第3张图片
这两种结构分别针对ResNet34(左图)和ResNet50/101/152(右图),一般称整个结构为一个”building block“。其中右图又称为**”bottleneck design”**(间隔1 * 1、3 * 3、1 * 1的三层网络,第一层用于降低维度,第三层用于升高维度),目的一目了然,就是为了降低参数的数目,第一个1x1的卷积把256维channel降到64维,然后在最后通过1x1卷积恢复,整体上用的参数数目:1x1x256x64 + 3x3x64x64 + 1x1x64x256 = 69632,而不使用bottleneck的话就是两个3x3x256的卷积,参数数目: 3x3x256x256x2 = 1179648,差了16.94倍。

残差网络的本质:

残差网络的等价结构:
残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用_第4张图片
残差网络单元其中可以分解成右图的形式,从图中可以看出,残差网络其实是由多种路径组合的一个网络,直白了说,残差网络其实是很多并行子网络的组合,整个残差网络其实相当于一个多人投票系统(Ensembling)。

● ResNeXt (2016)

动机

  • 传统的要提高模型的准确率,都是加深或加宽网络,但是随着超参数数量的增加(比如channels数,filter
    size等等),网络设计的难度和计算开销也会增加。

?contribution:

  • 增加基数 cardinality 比增加深度和宽度更有效。(在某一层并行transform的路径数提取为第三维度,称为”cardinality”。)
  • 用一种平行堆叠相同拓扑结构的blocks代替原来 ResNet 的三层卷积的block,在不明显增加参数量级的情况下提升了模型的准确率,同时由于拓扑结构相同,超参数也减少了,便于模型移植。

优点

  • 提高准确率
  • 减少超参数数量(得益于子模块的拓扑结构)

残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用_第5张图片

上图所示提出了深度网络的新维度,除了深度、宽度(Channel数)外,作者将在某一层并行transform的路径数提取为第三维度,称为”cardinality”。跟Inception单元不同的是,这些并行路径均共享同一拓扑结构,而非精心设计的卷积核并联。除了并行相同的路径外,也添加了层与层间的shortcut connection


● ResNeXt WSL(2019)

?contribution:

  • 预训练模型
如何使用:
import torch
model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x8d_wsl')
# or
# model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x16d_wsl')
# or
# model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x32d_wsl')
# or
#model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x48d_wsl')
model.eval()

ResNeXt WSL使用例子:

# Download an example image from the pytorch website
import urllib
url, filename = ("https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg")
try: urllib.URLopener().retrieve(url, filename)
except: urllib.request.urlretrieve(url, filename)
# sample execution (requires torchvision)
from PIL import Image
from torchvision import transforms
input_image = Image.open(filename)
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model

# move the input and model to GPU for speed if available
if torch.cuda.is_available():
    input_batch = input_batch.to('cuda')
    model.to('cuda')

with torch.no_grad():
    output = model(input_batch)
# Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes
print(output[0])
# The output has unnormalized scores. To get probabilities, you can run a softmax on it.
print(torch.nn.functional.softmax(output[0], dim=0))
只有一点需要注意:这次开源的模型,要求所有输入图像,都用相同的方式归一化 (Normalization)

ResNeXt主页、GitHub项目、ECCV论文
Colab Demo:https://colab.research.google.com/github/pytorch/pytorch.github.io/blob/master/assets/hub/facebookresearch_WSL-Images_resnext.ipynb、

你可能感兴趣的:(深度学习)