日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dynamic ReLU论文解读

發布時間:2024/4/11 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dynamic ReLU论文解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

其實一直在做論文閱讀心得方面的工作,只是一直沒有分享出來,這篇文章可以說是這個前沿論文解讀系列的第一篇文章,希望能堅持下來。

簡介

論文提出了動態線性修正單元(Dynamic Relu,下文簡稱 DY-ReLU),它能夠依據輸入動態調整對應分段函數,與 ReLU 及其靜態變種相比,僅僅需要增加一些可以忽略不計的參數就可以帶來大幅的性能提升,它可以無縫嵌入已有的主流模型中,在輕量級模型(如 MobileNetV2)上效果更加明顯。

  • 論文標題

    Dynamic ReLU

  • 論文地址

    http://arxiv.org/abs/2003.10027

  • 論文源碼

    https://github.com/Islanna/DynamicReLU

介紹

ReLU 在深度學習的發展中地位舉足輕重,它簡單而且高效,極大地提高了深度網絡的性能,被很多 CV 任務的經典網絡使用。不過 ReLU 及其變種(無參數的 leaky ReLU 和有參數的 PReLU)都是靜態的,也就是說他們最終的參數都是固定的。那么自然會引發一個問題,能否根據輸入的數據動態調整 ReLU 的參數呢?

針對上述問題,論文提出了 DY-ReLU,它是一個分段函數fθ(x)(x)f_{\boldsymbol{\theta}(\boldsymbol{x})}(\boldsymbol{x})fθ(x)?(x),其參數由超函數θ(x)\boldsymbol{\theta {(x)}}θ(x)根據xxx計算得到。如上圖所示,輸入xxx在進入激活函數前分成兩個流分別輸入θ(x)\boldsymbol{\theta {(x)}}θ(x)fθ(x)(x)f_{\boldsymbol{\theta}(\boldsymbol{x})}(\boldsymbol{x})fθ(x)?(x),前者用于獲得激活函數的參數,后者用于獲得激活函數的輸出值。超函數θ(x)\boldsymbol{\theta {(x)}}θ(x)能夠編碼輸入xxx的各個維度(對卷積網絡而言,這里指的就是通道,所以原文采用 c 來標記)的全局上下文信息來自適應激活函數fθ(x)(x)f_{\boldsymbol{\theta}(\boldsymbol{x})}(\boldsymbol{x})fθ(x)?(x)

該設計能夠在引入極少量的參數的情況下大大增強網絡的表示能力,本文對于空間和通道上不同的共享機制設計了三種 DY-ReLU,分別是 DY-ReLU-A、DY-ReLU-B 以及 DY-ReLU-C。

Dynamic ReLU

定義

原始的 ReLU 為y=max?{x,0}\boldsymbol{y}=\max \{\boldsymbol{x}, 0\}y=max{x,0},這是一個非常簡單的分段函數。對于輸入向量xxx的第ccc個通道的輸入xcx_cxc?,對應的激活函數可以記為yc=max?{xc,0}y_{c}=\max \left\{x_{c}, 0\right\}yc?=max{xc?,0}。進而,ReLU 可以統一表示為帶參分段線性函數yc=max?k{ackxc+bck}y_{c}=\max _{k}\left\{a_{c}^{k} x_{c}+b_{c}^{k}\right\}yc?=maxk?{ack?xc?+bck?},基于此提出下式動態 ReLU 來針對x={xc}\boldsymbol{x}=\left\{x_{c}\right\}x={xc?}自適應acka_c^kack?bckb_c^kbck?

yc=fθ(x)(xc)=max?1≤k≤K{ack(x)xc+bck(x)}y_{c}=f_{\boldsymbol{\theta}(\boldsymbol{x})}\left(x_{c}\right)=\max _{1 \leq k \leq K}\left\{a_{c}^{k}(\boldsymbol{x}) x_{c}+b_{c}^{k}(\boldsymbol{x})\right\}yc?=fθ(x)?(xc?)=1kKmax?{ack?(x)xc?+bck?(x)}

系數(ack,bck)\left(a_{c}^{k}, b_{c}^{k}\right)(ack?,bck?)由超函數θ(x)\boldsymbol{\theta (x)}θ(x)計算得到,具體如下,其中KKK為函數的數目,CCC為通道數目。且參數(ack,bck)\left(a_{c}^{k}, b_{c}^{k}\right)(ack?,bck?)不僅僅與xcx_cxc?有關,還和xj≠cx_{j \neq c}xj?=c?有關。

[a11,…,aC1,…,a1K,…,aCK,b11,…,bC1,…,b1K,…,bCK]T=θ(x)\left[a_{1}^{1}, \ldots, a_{C}^{1}, \ldots, a_{1}^{K}, \ldots, a_{C}^{K}, b_{1}^{1}, \ldots, b_{C}^{1}, \ldots, b_{1}^{K}, \ldots, b_{C}^{K}\right]^{T}=\boldsymbol{\theta}(\boldsymbol{x})[a11?,,aC1?,,a1K?,,aCK?,b11?,,bC1?,,b1K?,,bCK?]T=θ(x)

實現

DY-ReLU 的核心超函數θ(x)\boldsymbol{\theta {(x)}}θ(x)的實現采用 SE 模塊(SENet 提出的)實現,對于維度為C×H×WC \times H \times WC×H×W的張量輸入,首先通過一個全局池化層壓縮空間信息,然后經過兩個中間夾著一個 ReLU 的全連接層,最后一個標準化層用于標準化輸出的范圍在(?1,1)(-1,1)(?1,1)之間(采用 sigmoid
函數)。該模塊最終輸出2KC2KC2KC個元素,分別是a1:C1:Ka_{1: C}^{1: K}a1:C1:K?b1:C1:Kb_{1: C}^{1: K}b1:C1:K?的殘差,記為Δa1:C1:K\Delta a_{1: C}^{1: K}Δa1:C1:K?Δb1:C1:K\Delta b_{1: C}^{1: K}Δb1:C1:K?,最后的輸出為初始值和殘差的加權和,計算式如下。

ack(x)=αk+λaΔack(x),bck(x)=βk+λbΔbck(x)a_{c}^{k}(\boldsymbol{x})=\alpha^{k}+\lambda_{a} \Delta a_{c}^{k}(\boldsymbol{x}), b_{c}^{k}(\boldsymbol{x})=\beta^{k}+\lambda_{b} \Delta b_{c}^{k}(\boldsymbol{x})ack?(x)=αk+λa?Δack?(x),bck?(x)=βk+λb?Δbck?(x)

其中,αk\alpha^kαkβk\beta^kβk分別為acka_c^kack?bckb_c^kbck?的初始值,λa\lambda_aλa?λb\lambda_bλb?為殘差范圍控制標量,也就是加的權。αk\alpha^kαkβk\beta^kβk以及λa\lambda_aλa?λb\lambda_bλb?都是超參數。若K=2K=2K=2,有α1=1,α2=β1=β2=0\alpha^{1}=1, \alpha^{2}=\beta^{1}=\beta^{2}=0α1=1,α2=β1=β2=0,這就是原始 ReLU。默認的λa\lambda_aλa?λb\lambda_bλb?分別為 1.0 和 0.5。

對于學習到不同的參數,DY-ReLU 會有不同的形式,它可以等價于 ReLU、Leaky ReLU 和 PReLU,也可以等價于 SE 模塊或者 Maxout 算子,至于具體的形式依據輸入而改變,是一種非常靈活的動態激活函數。

變種設計

主要提出三種不同的 DY-ReLU 設計,分別是 DY-ReLU-A、DY-ReLU-B 以及 DY-ReLU-C。DY-ReLU-A 空間和通道均共享,只會輸出2K2K2K個參數,計算簡單,表達能力較弱;DY-ReLU-B 僅空間上共享,輸出2KC2KC2KC個參數;DY-ReLU-C 空間和通道均不共享,參數量極大。

實驗結果

經過對比實驗得出 DY-ReLU-B 更適合圖像分類,DY-ReLU-C 更適合關鍵點檢測任務,在幾個典型網絡上改用論文提出的 DY-ReLU,效果如下圖,不難發現,在輕量級網絡上突破較大。

源碼解析

下面是 DY-ReLU-B 的 Pytorch 實現。

import torch import torch.nn as nnclass DyReLU(nn.Module):def __init__(self, channels, reduction=4, k=2, conv_type='2d'):super(DyReLU, self).__init__()self.channels = channelsself.k = kself.conv_type = conv_typeassert self.conv_type in ['1d', '2d']self.fc1 = nn.Linear(channels, channels // reduction)self.relu = nn.ReLU(inplace=True)self.fc2 = nn.Linear(channels // reduction, 2*k)self.sigmoid = nn.Sigmoid()self.register_buffer('lambdas', torch.Tensor([1.]*k + [0.5]*k).float())self.register_buffer('init_v', torch.Tensor([1.] + [0.]*(2*k - 1)).float())def get_relu_coefs(self, x):theta = torch.mean(x, axis=-1)if self.conv_type == '2d':theta = torch.mean(theta, axis=-1)theta = self.fc1(theta)theta = self.relu(theta)theta = self.fc2(theta)theta = 2 * self.sigmoid(theta) - 1return thetadef forward(self, x):raise NotImplementedErrorclass DyReLUB(DyReLU):def __init__(self, channels, reduction=4, k=2, conv_type='2d'):super(DyReLUB, self).__init__(channels, reduction, k, conv_type)self.fc2 = nn.Linear(channels // reduction, 2*k*channels)def forward(self, x):assert x.shape[1] == self.channelstheta = self.get_relu_coefs(x)relu_coefs = theta.view(-1, self.channels, 2*self.k) * self.lambdas + self.init_vif self.conv_type == '1d':# BxCxL -> LxBxCx1x_perm = x.permute(2, 0, 1).unsqueeze(-1)output = x_perm * relu_coefs[:, :, :self.k] + relu_coefs[:, :, self.k:]# LxBxCx2 -> BxCxLresult = torch.max(output, dim=-1)[0].permute(1, 2, 0)elif self.conv_type == '2d':# BxCxHxW -> HxWxBxCx1x_perm = x.permute(2, 3, 0, 1).unsqueeze(-1)output = x_perm * relu_coefs[:, :, :self.k] + relu_coefs[:, :, self.k:]# HxWxBxCx2 -> BxCxHxWresult = torch.max(output, dim=-1)[0].permute(2, 3, 0, 1)return result

這個結構和上文我所說的 SE 模塊是大體對應的,目前支持一維和二維卷積,要想使用只需要像下面這樣替換激活層即可(DY-ReLU 需要指定輸入通道數目和卷積類型)。

import torch.nn as nn from dyrelu import DyReluBclass Model(nn.Module):def __init__(self):super(Model, self).__init__()self.conv1 = nn.Conv2d(3, 10, 5)self.relu = DyReLUB(10, conv_type='2d')def forward(self, x):x = self.conv1(x)x = self.relu(x)return x

有空的話我會在 MobileNet 和 ResNet 上具體實驗,看看實際效果是否如論文所述。

最近時間比較多,久違的填個坑,之前一直說要實驗一下DyReLU的效果的,在Caltech256上進行對比實驗,采用ResNet50和將部分ReLU換為DyReLU的ResNet5-dyrelu,在其他超參等配置完全一致的情況下,訓練集表現和驗證集表現如下圖。(模型容量分別為370MB和414MB,略大了一些)

如上圖所示,加了DyReLU的模型訓練更加平穩,收斂更快,損失降得更低。

總結

論文提出了 DY-ReLU,能夠根據輸入動態地調整激活函數,與 ReLU 及其變種對比,僅需額外的少量計算即可帶來大幅的性能提升,能無縫嵌入到當前的主流模型中,是一個漲點利器。本質上,DY-ReLU 就是各種 ReLU 的數學歸納和拓展,這對后來激活函數的研究有指導意義。在ResNet50上進行對比實驗的代碼,開源于Github。

總結

以上是生活随笔為你收集整理的Dynamic ReLU论文解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。