深圳网站公司排名,长沙搜搜网,浙江金华网站建设,小型便利店装修设计论文地址:https://arxiv.org/abs/1904.04971
代码地址#xff1a;https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/condconv 1.是什么#xff1f;
CondConv是一种条件参数卷积#xff0c;也称为动态卷积#xff0c;它是一种即插即用的模块https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet/condconv 1.是什么
CondConv是一种条件参数卷积也称为动态卷积它是一种即插即用的模块可以为每个样例学习一个特定的卷积核参数。通过替换标准卷积CondConv可以提升模型的尺寸与容量同时保持高效推理。CondConv的设计优越性在于它只需要做一次卷积而不像其他方法需要做n次卷积这样可以大大减少计算开销。CondConv可以对现有网络中的标准卷积进行替换同时适用于深度卷积与全连接层。实验结果表明CondConv可以显著提高模型的性能。
2.为什么
CNN在诸多计算机视觉任务中取得了前所未有的成功但其性能的提升更多源自模型尺寸与容量的提升以及更大的数据集。模型的尺寸提升进一步加剧了计算量的提升进一步加大优秀模型的部署难度。
现有CNN的一个基本假设对所有样例采用相同的卷积参数。这就导致为提升模型的容量就需要加大模型的参数、深度、通道数进一步导致模型的计算量加大、部署难度提升。由于上述假设以及终端部署需求当前高效网络往往具有较少的参数量。然而在某些计算机视觉应用中(如终端视频处理、自动驾驶)模型实时性要求高对参数量要求较低。
作者提出一种条件参数卷积用于解决上述问题它通过输入计算卷积核参数打破了传统的静态卷积特性。特别的作者将CondConv中的卷积核参数化为多个专家知识的线性组合(其中是通过梯度下降学习的加权系数)。为更有效的提升模型容量在网络设计过程中可以提升专家数量这比提升卷积核尺寸更为高效同时专家知识只需要进行一次组合这就可以在提升模型容量的同时保持高效推理。
3 怎么样
3.1网络结构 结构1,如下图,首先它采用更细粒度的集成方式每一个卷积层都拥有多套权重卷积层的输入分别经过不同的权重卷积之后组合输出,缺点是但这计算量依旧很大。 结构2,如图2,为了解决图1计算大问题,作者提出既然输入相同卷积是一种线性计算COMBINE也是一个线性计算比如加权求和,作者将多套权重加权组合之后只做一次卷积就能完成相当的效果计算量相比上图,大大降低。
3.2 原理
在常规卷积中其卷积核参数经训练确定且对所有输入样本“一视同仁”而在CondConv中卷积核参数参数通过对输入进行变换得到该过程可以描述为 这里x xx表示上一个layer的输出n nn表示这一层Condconv Layer有n nn个expertexpert就是该层的卷积核Wσ 表示激活函数表示一个样本依赖的加权参数。 所以一个CondConv层的卷积核参数的由来就是通过上述的线性组合公式。整个流程可以概括为依赖于输入x在卷积操作之前通过routing函数计算出每一个expert前面的系数 再通过线性组合得到CondConv层最终的kernal最后与输入x xx做卷积并进行activation。在这里routing weight的计算公式如下
对于输入x xx首先做GlobalAveragePooling随后右乘一个矩阵R该矩阵的目的是将维度映射到n个expert上面以实现后续的线性组合最后通过sigmoid将每一个维度上的权值规约到[0,1]区间。因此根据输入x xx的不同就会得到不同的routing weight向量进而CondConv层的kernal也各有差异。
3.3代码实现
import torch
import torch.nn.functional as F
import torch.nn as nn
from torch import Tensor
import functools
from torch.nn.modules.conv import _ConvNd
from torch.nn.modules.utils import _pair
from torch.nn.parameter import Parameterclass _routing(nn.Module):def __init__(self, in_channels, num_experts, dropout_rate):super(_routing, self).__init__()self.dropout nn.Dropout(dropout_rate)self.fc nn.Linear(in_channels, num_experts)def forward(self, x):x torch.flatten(x)x self.dropout(x)x self.fc(x)return F.sigmoid(x)class CondConv2D(_ConvNd):def __init__(self, in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1,biasTrue, padding_modezeros, num_experts3, dropout_rate0.2):# tuplekernel_size _pair(kernel_size)stride _pair(stride)padding _pair(padding)dilation _pair(dilation)super(CondConv2D, self).__init__(in_channels, out_channels, kernel_size, stride, padding, dilation,False, _pair(0), groups, bias, padding_mode)self._avg_pooling functools.partial(F.adaptive_avg_pool2d, output_size(1, 1))self._routing_fn _routing(in_channels, num_experts, dropout_rate)self.weight Parameter(torch.Tensor(num_experts, out_channels, in_channels // groups, *kernel_size))self.reset_parameters()def _conv_forward(self, input, weight):if self.padding_mode ! zeros:return F.conv2d(F.pad(input, self._padding_repeated_twice, modeself.padding_mode),weight, self.bias, self.stride,_pair(0), self.dilation, self.groups)return F.conv2d(input, weight, self.bias, self.stride,self.padding, self.dilation, self.groups)def forward(self, inputs):b, _, _, _ inputs.size()res []for input in inputs:input input.unsqueeze(0)pooled_inputs self._avg_pooling(input)routing_weights self._routing_fn(pooled_inputs)kernels torch.sum(routing_weights[: ,None, None, None, None] * self.weight, 0)out self._conv_forward(input, kernels)res.append(out)return torch.cat(res, dim0)
参考
动态卷积之CondConv和DynamicConv
CondConv用于有效推理的条件参数化卷积