溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn)

發(fā)布時(shí)間:2021-12-04 18:33:49 來源:億速云 閱讀:180 作者:柒染 欄目:大數(shù)據(jù)

今天就跟大家聊聊有關(guān)如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。


簡單回顧

這里主要是改進(jìn)傳統(tǒng)卷積,讓每層的卷積參數(shù)在推理的時(shí)候也是隨著輸入可變的,而不是傳統(tǒng)卷積中對任何輸入都是固定不變的參數(shù)。

如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn)  
推理的時(shí)候:紅色框住的參數(shù)是固定的,黃色框住的參數(shù)是隨著輸入的數(shù)據(jù)不斷變化的。

對于卷積過程中生成的一個特征圖 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ,先對特征圖做幾次運(yùn)算,生成 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 個和為 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 的參數(shù) 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ,然后對 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 個卷積核參數(shù)進(jìn)行線性求和,這樣推理的時(shí)候卷積核是隨著輸入的變化而變化的。(可以看看其他的講解文章,本文主要理解怎么寫代碼)

下面是attention代碼的簡易版本,輸出的是[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]大小的加權(quán)參數(shù)。 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 對應(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)

下面是文章中 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 個卷積核求和的公式。

如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn)

其中 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 是輸入, 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 是輸出;可以看到 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 進(jìn)行了兩次運(yùn)算,一次用于求注意力的參數(shù)(用于生成動態(tài)的卷積核),一次用于被卷積。

但是,寫代碼的時(shí)候如果直接將 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 個卷積核求和,會出現(xiàn)問題。接下來我們先回顧一下Pytorch里面的卷積參數(shù),然后描述一下可能會出現(xiàn)的問題,再講解如何通過分組卷積去解決問題。

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

我會從維度的視角回顧一下Pytorch里面的卷積的實(shí)現(xiàn)(大家也可以手寫一下,幾個重點(diǎn):輸入維度、輸出維度、正常卷積核參數(shù)維度、分組卷積維度、動態(tài)卷積維度、attention模塊輸出維度)。

輸入:輸入數(shù)據(jù)維度大小為[如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]。

輸出:輸出維度為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]。

卷積核:正常卷積核參數(shù)維度為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]。(在Pytorch中,2d卷積核參數(shù)應(yīng)該是固定這種維度的)

這里我們可以注意到,正常卷積核參數(shù)的維度是不存在 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 的。因?yàn)閷τ谡5木矸e來說,不同的輸入數(shù)據(jù),使用的是相同的卷積核,卷積核的數(shù)量與一次前向運(yùn)算所輸入的 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 大小無關(guān)(相同層的卷積核參數(shù)只需要一份)。

可能會出現(xiàn)的問題

這里描述一下實(shí)現(xiàn)動態(tài)卷積代碼的過程中可能因?yàn)?nbsp;如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 大于1而出現(xiàn)的問題。

對于圖中attention模塊最后softmax輸出的 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 個數(shù),他們的維度為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],可以直接.view成[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],緊接著 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 作用于 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 卷積核參數(shù)上(形成動態(tài)卷積)。

問題所在:正常卷積,一次輸入多個數(shù)據(jù),他們的卷積核參數(shù)是一樣的,所以只需要一份網(wǎng)絡(luò)參數(shù)即可;但是對于動態(tài)卷積而言,每個輸入數(shù)據(jù)用的都是不同的卷積核,所以需要 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 份網(wǎng)絡(luò)參數(shù),不符合Pytorch里面的卷積參數(shù)格式,會出錯。

看下維度運(yùn)算[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]*[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],生成的動態(tài)卷積核是[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],不符合Pytorch里面的規(guī)定,不能直接參與運(yùn)算(大家可以按照這個思路寫個代碼看看,體會一下,光看可能感覺不出來問題),最簡單的解決辦法就是 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 等于1,不會出現(xiàn)錯誤,但是慢?。。?!

總之, 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 大于1會導(dǎo)致中間卷積核參數(shù)不符合規(guī)定。

分組卷積以及如何通過分組卷積實(shí)現(xiàn) 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 大于1的動態(tài)卷積

一句話描述分組卷積:對于多通道的輸入,將他們分成幾部分各自進(jìn)行卷積,結(jié)果concate。

組卷積過程用廢話描述:對于輸入的數(shù)據(jù)[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],假設(shè) 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 為 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ,那么分組卷積就是將他分為兩個 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 為 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 的數(shù)據(jù)(也可以用其他方法分),那么維度就是[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 5x2 , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],換個維度換下視角,[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],那么 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 為2的組卷積可以看成 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 的正常卷積。(如果還是有點(diǎn)不了解分組卷積,可以閱讀其他文章仔細(xì)了解一下。)

巧妙的轉(zhuǎn)換:上面將 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 翻倍即可將分組卷積轉(zhuǎn)化成正常卷積,那么反向思考一下,將 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 變?yōu)?,是不是可以將正常卷積變成分組卷積?

我們將 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 大小看成分組卷積中 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 的數(shù)量,令 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) 所在維度直接變?yōu)?nbsp;如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) !?。≈苯訉⑤斎霐?shù)據(jù)從[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]變成[1, 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],就可以用分組卷積解決問題了?。?!

詳細(xì)描述實(shí)現(xiàn)過程:將輸入數(shù)據(jù)的維度看成[1, 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ](分組卷積的節(jié)奏);卷積權(quán)重參數(shù)初始化為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],attention模塊生成的維度為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],直接進(jìn)行正常的矩陣乘法[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]*[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) *如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) * 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) * 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ]生成動態(tài)卷積的參數(shù),生成的動態(tài)卷積權(quán)重維度為[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],將其看成分組卷積的權(quán)重[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ](過程中包含reshape)。這樣的處理就完成了,輸入數(shù)據(jù)[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],動態(tài)卷積核[ 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) , 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn) ],直接是 如何解析基于Pytorch的動態(tài)卷積復(fù)現(xià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)重是不同的,動態(tài)卷積的權(quán)重也是不同的
       softmax_attention = self.attention(x)
       batch_size, in_planes, height, width = x.size()
       x = x.view(1, -1, height, width)# 變化成一個維度進(jìn)行組卷積
       weight = self.weight.view(self.K, -1)

       # 動態(tài)卷積的權(quán)重的生成, 生成的是batch_size個卷積參數(shù)(每個參數(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

看完上述內(nèi)容,你們對如何解析基于Pytorch的動態(tài)卷積復(fù)現(xiàn)有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI