转置卷积
 目前为止,在卷积神经网络层中,通常会减少下采样输入图像的空间维度(高和宽)。然而如果输入和输出图像的空间维度相同,在以像素级分类的语义分割中将会很方便:输出像素所处的通道维可以保有输入像素在同一位置上的分类结果。
 为了实现这一点,可以使用另一种类型的卷积神经网络层,它可以增加上采样中间层特征图的空间维度,用于逆转下采样导致的空间尺寸减少。
1.基本操作

 假设有一个 n h × n w n_h\times n_w nh×nw的输入张量和一个 k h × k w k_h\times k_w kh×kw的卷积核,一步幅为1滑动卷积核窗口,每行 n w n_w nw次,每列 n h n_h nh次,共产生 n h n w n_hn_w nhnw个结果,每个中间结果都是 ( n h + k h ) − 1 × ( n w + k w − 1 ) (n_h+k_h)-1\times(n_w+k_w-1) (nh+kh)−1×(nw+kw−1)的张量,初始化为0。
 输入张量中的每个元素乘以卷积核,得到一个 
     
      
       
        
        
          k 
         
        
          h 
         
        
       
         × 
        
        
        
          k 
         
        
          w 
         
        
       
      
        k_h\times k_w 
       
      
    kh×kw张量,替换中间张量的一部分。最后所有中间结果相加得到最终结果。
  
      
       
        
        
          Y 
         
        
          [ 
         
        
          i 
         
        
          : 
         
        
          i 
         
        
          + 
         
        
          h 
         
        
          , 
         
        
          j 
         
        
          : 
         
        
          j 
         
        
          + 
         
        
          w 
         
        
          ] 
         
        
          + 
         
        
          = 
         
        
          X 
         
        
          [ 
         
        
          i 
         
        
          , 
         
        
          j 
         
        
          ] 
         
        
          ⋅ 
         
        
          K 
         
        
       
         Y[i:i+h,j:j+w] += X[i,j]\cdot K 
        
       
     Y[i:i+h,j:j+w]+=X[i,j]⋅K
为什么称为转置?
 对于卷积 Y = X @ W Y =X@ W Y=X@W,可以对 W W W构造一个 V V V,使得卷积等价于矩阵乘法 Y ′ = V X ′ Y' = VX' Y′=VX′,这里 Y ′ , X ′ Y',X' Y′,X′是 Y , X Y,X Y,X对应的向量版本。
 也就是说如果 Y ′ Y' Y′长为 n n n, X ′ X' X′长为 m m m,则 V V V的形状为 n × m n\times m n×m,转置之后 V T V^T VT的形状变为 m × n m\times n m×n,则X和Y的形状也交换了。
 那么转置卷积等价于 Y ′ = V T X ′ Y'=V^T X' Y′=VTX′,如果卷积将输入从 ( h , w ) (h,w) (h,w)变成了 ( h ′ , w ′ ) (h',w') (h′,w′),同样超参数的转置卷积则从 ( h ′ , w ′ ) (h',w') (h′,w′)变成 ( h , w ) (h,w) (h,w)
import torch
from torch import nn
from d2l import torch as d2l
def trans_conv(X, K):
    h, w = K.shape
    Y = torch.zeros((X.shape[0] + h - 1, X.shape[1] + w - 1))
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            Y[i: i + h, j: j + w] += X[i, j] * K
    return Y
X = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
print(trans_conv(X, K))
X, K = X.reshape(1, 1, 2, 2), K.reshape(1, 1, 2, 2)
# nn库自带的转置卷积函数,超参数很明显
tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, bias=False)
tconv.weight.data = K
print(tconv(X))
2.填充、步幅和多通道
2.1 填充
 与常规卷积不同,在转置卷积中,填充被应用于的输出(常规卷积将填充应用于输入)。 例如,当将高和宽两侧的填充数指定为1时,转置卷积的输出中将删除第一和最后的行与列。
'''填充、步幅和多通道'''
# 填充是对输出进行填充
tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, padding=1, bias=False)
tconv.weight.data = K
print('填充:',tconv(X))

 输出反而变小了
2.2 步幅

tconv = nn.ConvTranspose2d(1, 1, kernel_size=2, stride=2, bias=False)
tconv.weight.data = K
print('步幅为2:',tconv(X))
2.3 多输入输出通道
 与常规卷积类似的,假设输入有 c i c_i ci个通道,且转置卷积为每个输入通道分配了一个 k h × k w k_h\times k_w kh×kw的卷积张量,指定多个输出通道时,每个输出通道将有一个 c i × k h × k w c_i\times k_h\times k_w ci×kh×kw的卷积核
 如果我们将X带入卷积层f来输出 Y = f ( x ) Y=f(x) Y=f(x),并创建一个与f具有相同的超参数、但输出通道数量是X中通道数的转置卷积层 g g g,那么 g ( Y ) g(Y) g(Y)的形状将与 X X X相同:
'''多输入输出通道'''
X = torch.rand(size=(1, 10, 16, 16))
conv = nn.Conv2d(10, 20, kernel_size=5, padding=2, stride=3)
tconv = nn.ConvTranspose2d(20, 10, kernel_size=5, padding=2, stride=3)
tconv(conv(X)).shape == X.shape # True
3.与矩阵乘法的联系
13.10. 转置卷积 — 动手学深度学习 2.0.0 documentation (d2l.ai)
之前有写过了,大概就是卷积操作可以使用矩阵乘法实现。
4.关于填充、步幅的补充
 
 输入矩阵填充,核矩阵上下左右翻转后做正常卷积(填充0、步幅1)


 s=2时,行和列之间插入一行或已列
 p=0.则填充k-1=2-1=1。
形状换算
 输入高(宽)为n,核k,填充p,步幅s,那么对于转置卷积:
  
      
       
        
         
         
           n 
          
         
           ′ 
          
         
        
          = 
         
        
          s 
         
        
          n 
         
        
          + 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          p 
         
        
          − 
         
        
          s 
         
        
       
         n'=sn +k-2p-s 
        
       
     n′=sn+k−2p−s
  如果想让高宽成倍增加,那么 
     
      
       
       
         k 
        
       
         = 
        
       
         2 
        
       
         p 
        
       
         + 
        
       
         s 
        
       
      
        k=2p+s 
       
      
    k=2p+s
 回忆一下,对于卷积:
  
      
       
        
         
         
           n 
          
         
           ′ 
          
         
        
          = 
         
        
          ⌊ 
         
        
          ( 
         
        
          n 
         
        
          − 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          p 
         
        
          + 
         
        
          s 
         
        
          ) 
         
        
          / 
         
        
          s 
         
        
          ⌋ 
         
        
          → 
         
        
          n 
         
        
          ≥ 
         
        
          s 
         
         
         
           n 
          
         
           ′ 
          
         
        
          + 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          p 
         
        
          − 
         
        
          s 
         
        
       
         n'=\lfloor(n-k-2p+s)/s\rfloor \rightarrow n\ge sn'+k-2p-s 
        
       
     n′=⌊(n−k−2p+s)/s⌋→n≥sn′+k−2p−s
  转置卷积不是反卷积,反卷积是指卷积的逆运算:
  
      
       
        
        
          i 
         
        
          f 
         
        
            
         
        
          Y 
         
        
          = 
         
        
          c 
         
        
          o 
         
        
          n 
         
        
          v 
         
        
          ( 
         
        
          X 
         
        
          , 
         
        
          K 
         
        
          ) 
         
        
          , 
         
        
          t 
         
        
          h 
         
        
          e 
         
        
          n 
         
        
            
         
        
          X 
         
        
          = 
         
        
          d 
         
        
          e 
         
        
          c 
         
        
          o 
         
        
          n 
         
        
          v 
         
        
          ( 
         
        
          Y 
         
        
          , 
         
        
          K 
         
        
          ) 
         
        
       
         if\ Y=conv(X,K), then\ X=deconv(Y,K) 
        
       
     if Y=conv(X,K),then X=deconv(Y,K)
  转置卷积本质上依旧是卷积,只是矩阵形式上的变化相反。


















