deblurGAN-v2 去模糊深度學習算法。

https://blog.csdn.net/weixin_42784951/article/details/100168882

論文:https://arxiv.org/pdf/1908.03826.pdf
代碼:https://github.com/TAMU-VITA/DeblurGANv2

abstract
我們提出了一個名爲DeblurGAN-v2的端到端的生成對抗網絡,它對於去模糊產生了非常好的性能。DeblurGAN-v2基於conditional GAN(帶有兩個判別器)。我們將特徵金字塔網絡結構作爲DeblurGAN-v2生成器的核心構建塊。 它可以靈活地與各種backbone配合使用,在性能和效率之間取得平衡。如果使用複雜的backbone(如Inception-ResNet-v2)可以得到非常好的去模糊效果。同時,若使用輕量的backbone(e.g., MobileNet and its variants) ,DeblurGAN-v2比最接近的競爭對手快10到100倍,同時保持接近最先進的結果,這意味着可以選擇實時視頻去模糊。

Introduction
本文以DeblurGAN的成功爲基礎,旨在再次大力推動基於GAN的運動去模糊。 我們引入了一個新的框架DeblurGAN-v2來改進DeblurGAN,並且在質量效率範圍內實現高度靈活性。 我們的創新總結如下:

Framework Level : 我們構建了一個用於去模糊的新條件GAN框架。 對於生成器,我們將特徵金字塔網絡(FPN)(最初用於目標檢測)引入到圖像恢復任務中。 對於鑑別器,我們採用 relativistic discriminator ,並且使用最小均方損失在兩個尺度上分別進行評估。

Backbone Level : 在生成器部分選擇不同的 backbone 會有不同的去模糊效果。如果想得到最好的去模糊效果,我們使用複雜的 backbone : Inception-ResNet-v2 。 如果想得到更高的效率 ,我們使用清量的backbone : MobileNet, 並進一步創建他的變形:具有深度可分離卷積的 MobileNet-DSC。很明顯後面兩個具有更快的速度。

Experiment Level : 我們在三個流行的基準測試中展示了非常廣泛的實驗,以展示DeblurGANv2實現的最先進(或接近)性能(PSNR,SSIM和感知質量)。 在效率方面,DeblurGAN-v2與MobileNet-DSC的速度比DeblurGAN快21倍[21],比[33,45]快100多倍,模型尺寸僅爲4 MB,這意味着可能實現 時間視頻去模糊。 我們還對真實模糊圖像的去模糊質量進行了主觀研究。 最後,我們展示了我們的模型在一般圖像恢復中的潛力,因爲它具有額外的靈活性。

DeblurGAN-v2 Architecture
DeblurGAN-v2 結構如下圖所示,通過對生成器的訓練,可以從一張模糊圖像中恢復清晰圖像。


Feature Pyramid Deblurring

FPN框架最初用於目標檢測。它生成多個特徵映射層,這些特徵映射層編碼不同的語義幷包含更好的質量信息。 FPN包括自下而上和自上而下的路徑。 自下而上的路徑是用於特徵提取的卷積網絡,在從下往上的過程中空間分辨率被下采樣。但是可以提取和壓縮更多的語義特徵信息。另一方面,通過自上往下的路徑, FPN可以重建特徵信息。自下而上和自上而下通道之間的橫向連接補充了高分辨率細節並有助於定位物體。
我們的架構由一個FPN骨幹網組成,我們從中獲取五個不同尺度的最終特徵圖作爲輸出。這些特徵稍後被上採樣到輸入大小的1/4並連接成一個張量,其包含不同級別的語義信息。我們在網絡的最後添加一個上採樣層和一個卷積層來恢復清晰圖像和去僞影。我們引入了從輸入到輸出的跳躍連接,以便學習重點關注殘差。

對應代碼分析:

    def forward(self, x):
        
        ### 提取特徵層
        map0, map1, map2, map3, map4 = self.fpn(x)
        
        ###對不同的特徵上採樣
        map4 = nn.functional.upsample(self.head4(map4), scale_factor=8, mode="nearest")
        map3 = nn.functional.upsample(self.head3(map3), scale_factor=4, mode="nearest")
        map2 = nn.functional.upsample(self.head2(map2), scale_factor=2, mode="nearest")
        map1 = nn.functional.upsample(self.head1(map1), scale_factor=1, mode="nearest")
        
        並接map1- map4
        smoothed = self.smooth(torch.cat([map4, map3, map2, map1], dim=1))
        
        smoothed = nn.functional.upsample(smoothed, scale_factor=2, mode="nearest")
        smoothed = self.smooth2(smoothed + map0)
        smoothed = nn.functional.upsample(smoothed, scale_factor=2, mode="nearest")

        final = self.final(smoothed)
        
        得到輸出結果
        res = torch.tanh(final) + x

        return torch.clamp(res, min = -1,max = 1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
首先提取圖片不同尺度的的特徵映射:


map0, map1, map2, map3, map4 = self.fpn(x)
1
其中self.fpn(x)對應函數如下:

    def forward(self, x):

        # Bottom-up pathway, from ResNet
        enc0 = self.enc0(x)

        enc1 = self.enc1(enc0) # 256

        enc2 = self.enc2(enc1) # 512

        enc3 = self.enc3(enc2) # 1024

        enc4 = self.enc4(enc3) # 2048

        # Lateral connections

        lateral4 = self.pad(self.lateral4(enc4))
        lateral3 = self.pad(self.lateral3(enc3))
        lateral2 = self.lateral2(enc2)
        lateral1 = self.pad(self.lateral1(enc1))
        lateral0 = self.lateral0(enc0)

        # Top-down pathway
        pad = (1, 2, 1, 2)  # pad last dim by 1 on each side
        pad1 = (0, 1, 0, 1)
        map4 = lateral4
        map3 = self.td1(lateral3 + nn.functional.upsample(map4, scale_factor=2, mode="nearest"))
        map2 = self.td2(F.pad(lateral2, pad, "reflect") + nn.functional.upsample(map3, scale_factor=2, mode="nearest"))
        map1 = self.td3(lateral1 + nn.functional.upsample(map2, scale_factor=2, mode="nearest"))
        return F.pad(lateral0, pad1, "reflect"), map1, map2, map3, map4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
其中 self.enc0 ------ self.enc4 爲首先對特徵進行卷積,然後進行池化,然後的到不同的特徵,如圖:

self.enc0 = self.inception.conv2d_1a
        self.enc1 = nn.Sequential(
            self.inception.conv2d_2a,
            self.inception.conv2d_2b,
            self.inception.maxpool_3a,
        ) # 64
        self.enc2 = nn.Sequential(
            self.inception.conv2d_3b,
            self.inception.conv2d_4a,
            self.inception.maxpool_5a,
        )  # 192
        self.enc3 = nn.Sequential(
            self.inception.mixed_5b,
            self.inception.repeat,
            self.inception.mixed_6a,
        )   # 1088
        self.enc4 = nn.Sequential(
            self.inception.repeat_1,
            self.inception.mixed_7a,
        )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FPN網絡原理:
我們知道低層的特徵語義信息比較少,但是目標位置準確;高層的特徵語義信息比較豐富,但是目標位置比較粗略。另外雖然也有些算法採用多尺度特徵融合的方式,但是一般是採用融合後的特徵做預測, FPN不一樣的地方在於預測是在不同特徵層獨立進行的。 如上面介紹的那樣, FPN結構經過不同次數的卷積等處理就可以得到不同的特徵層信息。

FPN結構對比:

 a、 圖像金字塔,即將圖像做成不同的scale,然後不同scale的圖像生成對應的不同scale的特徵。這種方法的缺點在於增加了時間成本。有些算法會在測試時候採用圖像金字塔。
 b、 像SPP net,Fast RCNN,Faster RCNN是採用這種方式,即僅採用網絡最後一層的特徵。
 c、 像SSD(Single Shot Detector)採用這種多尺度特徵融合的方式,沒有上採樣過程,即從網絡不同層抽取不同尺度的特徵做預測,這種方式不會增加額外的計算量。作者認爲SSD算法中沒有用到足夠低層的特徵(在SSD中,最低層的特徵是VGG網絡的conv4_3),而在作者看來足夠低層的特徵對於檢測小物體是很有幫助的
 d、FPN結構 頂層特徵通過上採樣和低層特徵做融合,而且每層都是獨立預測的。
如下圖所示:

上圖(a)中的方法即爲常規的生成一張圖片的多維度特徵組合的經典方法。即對某一輸入圖片我們通過壓縮或放大從而形成不同維度的圖片作爲模型輸入,使用同一模型對這些不同維度的圖片分別處理後,最終再將這些分別得到的特徵(feature maps)組合起來就得到了我們想要的可反映多維度信息的特徵集。此種方法缺點在於需要對同一圖片在更改維度後輸入處理多次,因此對計算機的算力及內存大小都有較高要求。

圖(b)中的方法則只拿單一維度的圖片做爲輸入,然後經CNN模型處理後,拿最終一層的feature maps作爲最終的特徵集。顯然此種方法只能得到單一維度的信息。優點是計算簡單,對計算機算力及內存大小都無過高需求。此方法爲大多數R-CNN系列目標檢測方法所用像R-CNN/Fast-RCNN/Faster-RCNN等。因此最終這些模型對小維度的目標檢測性能不是很好。

圖©中的方法同樣是拿單一維度的圖片做爲輸入,不過最終選取用於接下來分類或檢測任務時的特徵組合時,此方法不只選用了最後一層的high level feature maps,同樣也會選用稍靠下的反映圖片low level 信息的feature maps。然後將這些不同層次(反映不同level的圖片信息)的特徵簡單合併起來(一般爲concat處理),用於最終的特徵組合輸出。此方法可見於SSD當中。不過SSD在選取層特徵時都選用了較高層次的網絡。比如在它以VGG16作爲主幹網絡的檢測模型裏面所選用的最低的Convolution的層爲Conv4,這樣一些具有更低級別信息的層特徵像Conv2/Conv3就被它給漏掉了,於是它對更小維度的目標檢測效果就不大好。

圖(d)中的方法同圖©中的方法有些類似,也是拿單一維度的圖片作爲輸入,然後它會選取所有層的特徵來處理然後再聯合起來做爲最終的特徵輸出組合。(作者在論文中拿Resnet爲實例時並沒選用Conv1層,那是爲了算力及內存上的考慮,畢竟Conv1層的size還是比較大的,所包含的特徵跟直接的圖片像素信息也過於接近)。另外還對這些反映不同級別圖片信息的各層自上向下進行了再處理以能更好地組合從而形成較好的特徵表達(詳細過程會在下面章節中進一步介紹)。而此方法正是我們本文中要講的FPN CNN特徵提取方法。

FPN結構原理:

作者的算法大致結構如下圖: 一個自底向上的線路,一個自頂向下的線路,橫向連接(lateral connection)。圖中放大的區域就是橫向連接,這裏1*1的卷積核的主要作用是減少卷積核的個數,也就是減少了feature map的個數,並不改變feature map的尺寸大小。


自底向上其實就是網絡的前向過程。在前向過程中,feature map的大小在經過某些層後會改變,而在經過其他一些層的時候不會改變,作者將不改變feature map大小的層歸爲一個stage,因此每次抽取的特徵都是每個stage的最後一個層輸出,這樣就能構成特徵金字塔。
自頂向下的過程採用上採樣(upsampling)進行,而橫向連接則是將上採樣的結果和自底向上生成的相同大小的feature map進行融合(merge)。在融合之後還會再採用3*3的卷積覈對每個融合結果進行卷積,目的是消除上採樣的混疊效應(aliasing effect)。並假設生成的feature map結果是P2,P3,P4,P5,和原來自底向上的卷積結果C2,C3,C4,C5一一對應。
https://blog.csdn.net/weixin_42784951/article/details/100168882

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章