<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          基于Pytorch的動(dòng)態(tài)卷積復(fù)現(xiàn)

          共 5150字,需瀏覽 11分鐘

           ·

          2020-09-17 15:59

          ↑ 點(diǎn)擊藍(lán)字?關(guān)注極市平臺(tái)

          作者丨史開(kāi)杰
          來(lái)源丨?GiantPandaCV
          編輯丨極市平臺(tái)

          極市導(dǎo)讀

          ?

          本文重點(diǎn)介紹了Pytorch中卷積的實(shí)現(xiàn),并為實(shí)現(xiàn)過(guò)程中可能出現(xiàn)的問(wèn)題給出解決方案。文末列出了相關(guān)代碼,讀者可對(duì)照代碼進(jìn)行實(shí)踐。

          Dynamic Convolution: Attention over Convolution Kernels

          paper地址:
          arxiv.org/pdf/1912.0345
          代碼實(shí)現(xiàn)地址:
          https://github.com/kaijieshi7/Dynamic-convolution-Pytorch

          其中包含一維,二維,三維的動(dòng)態(tài)卷積;分別可以用于實(shí)現(xiàn)eeg的處理,正常圖像的處理,醫(yī)療圖像中三維腦部的處理等等。

          一句話描述下文的內(nèi)容:??的大小視為分組卷積里面的組的大小進(jìn)行動(dòng)態(tài)卷積。如??,那么就轉(zhuǎn)化成??,??的分組卷積。

          簡(jiǎn)單回顧

          這篇文章主要是改進(jìn)傳統(tǒng)卷積,讓每層的卷積參數(shù)在推理的時(shí)候也是隨著輸入可變的,而不是傳統(tǒng)卷積中對(duì)任何輸入都是固定不變的參數(shù)。由于本文主要說(shuō)明的是代碼如何實(shí)現(xiàn),所以推薦給大家一個(gè)講解論文的鏈接:
          https://zhuanlan.zhihu.com/p/142381725
          推理的時(shí)候:紅色框住的參數(shù)是固定的,黃色框住的參數(shù)是隨著輸入的數(shù)據(jù)不斷變化的。
          對(duì)于卷積過(guò)程中生成的一個(gè)特征圖??,先對(duì)特征圖做幾次運(yùn)算,生成??個(gè)和為??的參數(shù)??,然后對(duì)??個(gè)卷積核參數(shù)進(jìn)行線性求和,這樣推理的時(shí)候卷積核是隨著輸入的變化而變化的。(可以看看其他的講解文章,本文主要理解怎么寫(xiě)代碼)
          下面是attention代碼的簡(jiǎn)易版本,輸出的是[??,??]大小的加權(quán)參數(shù)。??對(duì)應(yīng)著要被求和的卷積核數(shù)量。
          class attention2d(nn.Module):
          def __init__(self, in_planes, K,):
          super(attention2d, self).__init__()
          self.avgpool = nn.AdaptiveAvgPool2d(1)
          self.fc1 = nn.Conv2d(in_planes, K, 1,)
          self.fc2 = nn.Conv2d(K, K, 1,)

          def forward(self, x):
          x = self.avgpool(x)
          x = self.fc1(x)
          x = F.relu(x)
          x = self.fc2(x).view(x.size(0), -1)
          return F.softmax(x, 1)
          下面是文章中??個(gè)卷積核求和的公式。
          其中??是輸入,??是輸出;可以看到??進(jìn)行了兩次運(yùn)算,一次用于求注意力的參數(shù)(用于生成動(dòng)態(tài)的卷積核),一次用于被卷積。
          但是,寫(xiě)代碼的時(shí)候如果直接將??個(gè)卷積核求和,會(huì)出現(xiàn)問(wèn)題。接下來(lái)我們先回顧一下Pytorch里面的卷積參數(shù),然后描述一下可能會(huì)出現(xiàn)的問(wèn)題,再講解如何通過(guò)分組卷積去解決問(wèn)題。

          Pytorch卷積的實(shí)現(xiàn)

          我會(huì)從維度的視角回顧一下Pytorch里面的卷積的實(shí)現(xiàn)(大家也可以手寫(xiě)一下,幾個(gè)重點(diǎn):輸入維度、輸出維度、正常卷積核參數(shù)維度、分組卷積維度、動(dòng)態(tài)卷積維度、attention模塊輸出維度)。
          輸入:輸入數(shù)據(jù)維度大小為[?,??,??,??]。
          輸出:輸出維度為[??,??,??,??]。
          卷積核:正常卷積核參數(shù)維度為[??,??,??,??]。(在Pytorch中,2d卷積核參數(shù)應(yīng)該是固定這種維度的)
          這里我們可以注意到,正常卷積核參數(shù)的維度是不存在??的。因?yàn)閷?duì)于正常的卷積來(lái)說(shuō),不同的輸入數(shù)據(jù),使用的是相同的卷積核,卷積核的數(shù)量與一次前向運(yùn)算所輸入的??大小無(wú)關(guān)(相同層的卷積核參數(shù)只需要一份)。

          能會(huì)出現(xiàn)的問(wèn)題

          這里描述一下實(shí)現(xiàn)動(dòng)態(tài)卷積代碼的過(guò)程中可能因?yàn)??大于1而出現(xiàn)的問(wèn)題。
          對(duì)于圖中attention模塊最后softmax輸出的??個(gè)數(shù),他們的維度為[??,??,??,??],可以直接.view成[??,??],緊接著??作用于??卷積核參數(shù)上(形成動(dòng)態(tài)卷積)。
          問(wèn)題所在:正常卷積,一次輸入多個(gè)數(shù)據(jù),他們的卷積核參數(shù)是一樣的,所以只需要一份網(wǎng)絡(luò)參數(shù)即可;但是對(duì)于動(dòng)態(tài)卷積而言,每個(gè)輸入數(shù)據(jù)用的都是不同的卷積核,所以需要??份網(wǎng)絡(luò)參數(shù),不符合Pytorch里面的卷積參數(shù)格式,會(huì)出錯(cuò)。
          看下維度運(yùn)算[??,??]*[??,??,??,??,??],生成的動(dòng)態(tài)卷積核是[??,??,??,??,??],不符合Pytorch里面的規(guī)定,不能直接參與運(yùn)算(大家可以按照這個(gè)思路寫(xiě)個(gè)代碼看看,體會(huì)一下,光看可能感覺(jué)不出來(lái)問(wèn)題),最簡(jiǎn)單的解決辦法就是??等于1,不會(huì)出現(xiàn)錯(cuò)誤,但是慢啊!
          總之,??大于1會(huì)導(dǎo)致中間卷積核參數(shù)不符合規(guī)定。

          分組卷積以及如何通過(guò)分組卷積實(shí)現(xiàn)??大于1的動(dòng)態(tài)卷積

          一句話描述分組卷積:對(duì)于多通道的輸入,將他們分成幾部分各自進(jìn)行卷積,結(jié)果concate。
          組卷積過(guò)程用廢話描述:對(duì)于輸入的數(shù)據(jù)[??,??,??,??],假設(shè)??為??,那么分組卷積就是將他分為兩個(gè)??為??的數(shù)據(jù)(也可以用其他方法分),那么維度就是[??, 5x2?,??,??],換個(gè)維度換下視角,[??,??,??,??],那么??為2的組卷積可以看成??的正常卷積。(如果還是有點(diǎn)不了解分組卷積,可以閱讀其他文章仔細(xì)了解一下。)
          巧妙的轉(zhuǎn)換:上面將??翻倍即可將分組卷積轉(zhuǎn)化成正常卷積,那么反向思考一下,將??變?yōu)?,是不是可以將正常卷積變成分組卷積?
          我們將??大小看成分組卷積中??的數(shù)量,令??所在維度直接變?yōu)???。?!直接將輸入數(shù)據(jù)從[??,??,??,??]變成[1,??,??,??],就可以用分組卷積解決問(wèn)題了?。?!
          詳細(xì)描述實(shí)現(xiàn)過(guò)程:將輸入數(shù)據(jù)的維度看成[1, ?,??,??](分組卷積的節(jié)奏);卷積權(quán)重參數(shù)初始化為[??,??,??,??,??],attention模塊生成的維度為[??,??],直接進(jìn)行正常的矩陣乘法[??,??]*[??,??*?*??*??]生成動(dòng)態(tài)卷積的參數(shù),生成的動(dòng)態(tài)卷積權(quán)重維度為[??,??,??,??,??],將其看成分組卷積的權(quán)重[??,??,??,??](過(guò)程中包含reshape)。這樣的處理就完成了,輸入數(shù)據(jù)[??,??,??,??],動(dòng)態(tài)卷積核[??,??,??,??],直接是??的分組卷積,問(wèn)題解決。
          具體代碼如下:
          class Dynamic_conv2d(nn.Module):
          def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, K=4,):
          super(Dynamic_conv2d, self).__init__()
          assert in_planes%groups==0
          self.in_planes = in_planes
          self.out_planes = out_planes
          self.kernel_size = kernel_size
          self.stride = stride
          self.padding = padding
          self.dilation = dilation
          self.groups = groups
          self.bias = bias
          self.K = K
          self.attention = attention2d(in_planes, K, )

          self.weight = nn.Parameter(torch.Tensor(K, out_planes, in_planes//groups, kernel_size, kernel_size), requires_grad=True)
          if bias:
          self.bias = nn.Parameter(torch.Tensor(K, out_planes))
          else:
          self.bias = None


          def forward(self, x):#將batch視作維度變量,進(jìn)行組卷積,因?yàn)榻M卷積的權(quán)重是不同的,動(dòng)態(tài)卷積的權(quán)重也是不同的
          softmax_attention = self.attention(x)
          batch_size, in_planes, height, width = x.size()
          x = x.view(1, -1, height, width)# 變化成一個(gè)維度進(jìn)行組卷積
          weight = self.weight.view(self.K, -1)

          # 動(dòng)態(tài)卷積的權(quán)重的生成, 生成的是batch_size個(gè)卷積參數(shù)(每個(gè)參數(shù)不同)
          aggregate_weight = torch.mm(softmax_attention, weight).view(-1, self.in_planes, self.kernel_size, self.kernel_size)
          if self.bias is not None:
          aggregate_bias = torch.mm(softmax_attention, self.bias).view(-1)
          output = F.conv2d(x, weight=aggregate_weight, bias=aggregate_bias, stride=self.stride, padding=self.padding,
          dilation=self.dilation, groups=self.groups*batch_size)
          else:
          output = F.conv2d(x, weight=aggregate_weight, bias=None, stride=self.stride, padding=self.padding,
          dilation=self.dilation, groups=self.groups * batch_size)

          output = output.view(batch_size, self.out_planes, output.size(-2), output.size(-1))
          return output
          完整的代碼在github.com/kaijieshi7/D,大家覺(jué)得有幫助的話,求點(diǎn)個(gè)星星。
          紙上得來(lái)終覺(jué)淺,絕知此事要躬行。試下代碼,方能體會(huì)其中妙處。


          推薦閱讀


          添加極市小助手微信(ID : cvmart2),備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測(cè)-深圳),即可申請(qǐng)加入極市目標(biāo)檢測(cè)/圖像分割/工業(yè)檢測(cè)/人臉/醫(yī)學(xué)影像/3D/SLAM/自動(dòng)駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群:月大咖直播分享、真實(shí)項(xiàng)目需求對(duì)接、求職內(nèi)推、算法競(jìng)賽、干貨資訊匯總、與?10000+來(lái)自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺(jué)開(kāi)發(fā)者互動(dòng)交流~

          △長(zhǎng)按添加極市小助手

          △長(zhǎng)按關(guān)注極市平臺(tái),獲取最新CV干貨

          覺(jué)得有用麻煩給個(gè)在看啦~??


          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  加勒比操逼 | 大鸡巴操逼高潮视频 | 在线黄| 亚天堂中文 | 欧美日韩一区二区三区四区论理片 |