各种卷积变形——转置卷积

转置卷积

转置卷积又称做反卷积,出自《A guide to convolution arithmetic for deeplearning》论文。可以起到上采样以及可视化作用。

1.转置卷积的操作

相关笔记整理如下图。

2.转置卷积的实现代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

def show_matrix(m, color, cmap, title=None):
    rows, cols = len(m), len(m[0])
    fig, ax = plt.subplots(figsize=(cols, rows))
    ax.set_yticks(list(range(rows)))
    ax.set_xticks(list(range(cols)))
    ax.xaxis.tick_top()
    if title is not None:
        ax.set_title('{} {}'.format(title, m.shape), y=-0.5 / rows)
    plt.imshow(m, cmap=cmap, vmin=0, vmax=1)
    for r in range(rows):
        for c in range(cols):
            text = '{:>3}'.format(int(m[r][c]))
            ax.text(c - 0.2, r + 0.15, text, color=color, fontsize=15)
    plt.show()

def show_inputs(m, title='Inputs'):
    show_matrix(m, 'b',cm.GnBu_r , title)

def show_kernel(m, title='Kernel'):
    show_matrix(m, 'r',cm.RdPu_r ,title)

def show_output(m, title='Output'):
    show_matrix(m, 'g',cm. PuRd_r, title)

def convolve(m, k):
    m_rows, m_cols = len(m), len(m[0])  # matrix rows, cols
    k_rows, k_cols = len(k), len(k[0])  # kernel rows, cols

    rows = m_rows - k_rows + 1  # result matrix rows
    cols = m_rows - k_rows + 1  # result matrix cols

    v = np.zeros((rows, cols), dtype=m.dtype)  # result matrix

    for r in range(rows):
        for c in range(cols):
            v[r][c] = np.sum(m[r:r + k_rows, c:c + k_cols] * k)  # sum of the element-wise multiplication
    return v
inputs = np.random.randint(1, 9, size=(4, 4))# print(inputs)
show_inputs(inputs)
show_inputs(np.random.randint(100, 255, size=(4, 4)))
kernel = np.random.randint(1, 5, size=(3, 3))# print(kernel)
show_kernel(kernel)

output = convolve(inputs, kernel)    #传统卷积  # print(output)
show_output(output)

def convolution_matrix(m, k):
    m_rows, m_cols = len(m), len(m[0])  # matrix rows, cols
    k_rows, k_cols = len(k), len(k[0])  # kernel rows, cols
    # output matrix rows and cols
    rows = m_rows - k_rows + 1
    cols = m_rows - k_rows + 1
    # convolution matrix
    v = np.zeros((rows * cols, m_rows, m_cols))
    for r in range(rows):
        for c in range(cols):
            i = r * cols + c
            v[i][r:r + k_rows, c:c + k_cols] = k
    v = v.reshape((rows * cols), -1)
    return v, rows, cols

def column_vector(m):                                # 展平
    return m.flatten().reshape(-1, 1)

C, rows, cols = convolution_matrix(inputs, kernel)   #重排卷积
show_kernel(C, 'Convolution Matrix')
x = column_vector(inputs)
show_inputs(x)
output = C @ x
show_output(output)
output = output.reshape(rows, cols)                 #调整shape
show_output(output)

show_kernel(C.T, 'Transposed Convolution Matrix')    #转置卷积
x2 = np.random.randint(1, 5, size=(4, 1))
show_inputs(x2)
output2 = (C.T @ x2)
show_output(output2)
output2 = output2.reshape(4, 4)
show_output(output2)
posted on 2021-06-22 19:39  Lf&x&my  阅读(302)  评论(0)    收藏  举报