深度學習中的上採樣技術及其實現

一、反捲積(轉置卷積)

反捲積通常用於將低維特徵映射成高維輸入,與卷積操作的作用相反。一般反捲積只能還原圖片的大小,不能將圖片還原爲原來的圖片。反捲積操作的時候有兩種情況,分爲步長爲1和步長大於1。

1. stride = 1
  1. stride=1時,反捲積操作時在特徵圖周圍填充0,至於添加多少padding,就要看原圖和特徵圖的大小關係。比如原圖大小爲4 * 4 ,卷積核大小爲3 * 3,步長爲1,卷積後的特徵圖大小爲:2 * 2,那麼現在要將這個尺寸的特徵圖反捲積成4 * 4 大小,那麼先填充padding=2的0,也即添加兩圈。然後用3 * 3 卷積核進行卷積,得到了5 * 5 大小的圖片。如圖所示:

卷積操作:
在這裏插入圖片描述
反捲積操作:
在這裏插入圖片描述

2.stride > 1
  1. 當步長大於1時,先在周圍添加0, 然後按照步長等於1時的操作進行,如下圖所示的操作:
    在這裏插入圖片描述
  2. 步長大於2時的反捲積操作:

在這裏插入圖片描述

3. 反捲積操作實現

在這裏插入圖片描述

from torchvision.transforms import ToTensor, ToPILImage
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
# 顯示原始圖像
orginal_img = Image.open("yellow/dog.jpg")
plt.subplot(1, 3, 1)
plt.axis('off')
plt.title("orginal pic")
plt.imshow(orginal_img)

# 顯示卷積後的圖像
img = ToTensor()(orginal_img)
conv = nn.Conv2d(3, 3, 3, 1)
y = conv(img.unsqueeze(0))
conv_img = ToPILImage("RGB")(y.squeeze(0))
plt.subplot(1, 3, 2)
plt.axis('off')
plt.title("conv pic")
plt.imshow(conv_img)

#顯示反捲積後的圖像
transconv = nn.ConvTranspose2d(3, 3, 3, 1)
trans_img = transconv(y)
trans_img = ToPILImage("RGB")(trans_img.squeeze(0))
plt.subplot(1, 3, 3)
plt.axis('off')
plt.title("transconv pic")
plt.imshow(trans_img)
plt.show()

上述代碼只是簡單的展示了反捲積如何實現,它與卷積的實現方法很相似。

二、反池化

1. 反池化操作

反池化過程主要介紹兩種池化:最大池化的反池化和平均池化的反池化。
其中最大池化在反池化時要記錄最大值所在的位置,然後其餘位置用0補充,平均池化一般用鄰近元素作填充。如下圖所示:
在這裏插入圖片描述

3. 反池化操作的實現

在這裏插入圖片描述

from torchvision.transforms import ToTensor, ToPILImage
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
# 顯示原始圖像
orginal_img = Image.open("yellow/dog.jpg")
plt.subplot(1, 3, 1)
plt.axis('off')
plt.title("orginal pic")
plt.imshow(orginal_img)

# 卷積層
img = ToTensor()(orginal_img)
conv = nn.Conv2d(3, 3, 3, 1)
y = conv(img.unsqueeze(0))

# 池化層,顯示池化後的圖片
"""
參數return_indices:表示返回最大值所在的位置,最大池化在進行反池化操作哦時要記錄最大值所在的位置。
"""
pool = nn.MaxPool2d(2, 2, return_indices=True)
pool_y, index = pool(y)
pool_img = ToPILImage("RGB")(pool_y.squeeze())
plt.subplot(1, 3, 2)
plt.axis('off')
plt.title("pool pic")
plt.imshow(pool_img)

# 反池化操作並顯示反池化後的圖片
unpool = nn.MaxUnpool2d(2, 2)
y = unpool(pool_y, index)

# 對比池化操作輸出的值和反池化操作輸出值的大小
print("池化後的值:", pool_y)
print("反池化後的值:", y)
unpool_img = ToPILImage("RGB")(y.squeeze())
plt.subplot(1, 3, 3)
plt.axis('off')
plt.title("unpool pic")
plt.imshow(unpool_img)
plt.show()
池化的作用:
  1. 減小特徵圖大小
  2. 降低過擬合,降低過擬合是減小輸出大小的結果,它同樣也減少了後續層中的參數的數量。
  3. 池化操作很暴力的丟棄了一些圖片的特徵,可以用大步長的卷積代替池化操作,這樣就可以保證圖片特徵不丟失。

三、普通上採樣

(1)最鄰近插值

最鄰近插值算法的原理:在原圖像中找到最鄰近的一個點,然後把這個點的像素值插入到目標圖像中,最近臨插值算法優點是算法簡單易於實現,但是缺點是由於相鄰像素點的像素值相同,容易出現色塊現象。

(2)雙線性插值
  1. 雙線性插值原理解釋

首先在Q11Q21、Q12Q22方向上進行兩次線性插值,得到R1、R2;然後在R1R2方向再做一次線性插值得到P點,這就是雙線性插值。
在這裏插入圖片描述

雙線性插值原理動圖:
圖片來源:https://www.cnblogs.com/SpiritAmos/p/11991528.html
在這裏插入圖片描述

(3) 最鄰近插值和雙線性插值的實現:

在這裏插入圖片描述

from torchvision.transforms import ToTensor, ToPILImage
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
import torch.nn.functional as F
orginal_img = Image.open("yellow/dog.jpg")
plt.subplot(1, 3, 1)
plt.axis('off')
plt.title("orginal pic")
plt.imshow(orginal_img)

img = ToTensor()(orginal_img)
conv = nn.Conv2d(3, 3, 3, 1)
y = conv(img.unsqueeze(0))
trans_conv = nn.ConvTranspose2d(3, 3, 3, 1)
y = trans_conv(y)
# pool = nn.MaxPool2d(2, 2)
# pool_y = pool(y)

# 最鄰近插值,參數scale_factor 表示放大或縮小倍數
"""
以下兩種寫法都可以用F.interpolate()函數代替
upsample = nn.UpsamplingNearest2d(scale_factor=2)
upsample = nn.Upsample(scale_factor=2, mode='nearest') 
"""
z1 = F.interpolate(y, scale_factor=2, mode='nearest')
near_conv_img = ToPILImage("RGB")(z1.squeeze(0))
plt.subplot(1, 3, 2)
plt.axis('off')
plt.title("nearest")
plt.imshow(near_conv_img)

# 雙線性插值,雙線性插值中參數align_corners是對齊角的意思
"""
以下兩種寫法都可以用F.interpolate()函數代替
upsample = nn.UpsamplingBilinear2d(scale_factor=2)
upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) 
"""
z2 = F.interpolate(y, scale_factor=2, mode='bilinear', align_corners=True)
linear_conv_img = ToPILImage("RGB")(z2.squeeze(0))
plt.subplot(1, 3, 3)
plt.axis('off')
plt.title("bilinear")
plt.imshow(linear_conv_img)
plt.show()
發佈了32 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章