tensorflow 中反卷积操作(transpose conv)详解

题主花了很多时间去理解 tensorflow 中 transpose_conv 的计算方法,终于找到了一篇写得比较基础的博文link,文中用 python 实现了 tensorflow 中 transpose_conv 的功能,但是存在一点点不足,code仅仅适合 stride=2,kernel=3的场合,现修改其代码,使其适应于 stride = 2,但kernel 可以为任意值的场合。

#根据输入map([h,w])和卷积核([k,k]),计算卷积后的feature map
import numpy as np
def compute_conv(fm,kernel):
    [h,w]=fm.shape 
    [k,_]=kernel.shape 
    #定义边界填充0后的map
    padding_fm=np.zeros([h+k-1,w+k-1],np.float32)

    #保存计算结果
    rs=np.zeros([h,w],np.float32) 
    #将输入在指定该区域赋值,即除了4个边界后,剩下的区域
    padding_fm[(k-1)//2:h+(k-1)//2,(k-1)//2:w+(k-1)//2]=fm 
    padding_fm_w = padding_fm.shape[0]
    #对每个点为中心的区域遍历
    for i in range(padding_fm_w -k):
        for j in range(padding_fm_w -k): 
            #取出当前点为中心的k*k区域
            roi=padding_fm[i:i+k,j:j+k]
            #计算当前点的卷积,对k*k个点点乘后求和
            rs[i][j]=np.sum(roi*kernel)

    return rs

#填充0
def fill_zeros(input):
    [c,h,w]=input.shape
    rs=np.zeros([c,h*2+1,w*2+1],np.float32)

    for i in range(c):
        for j in range(h):
            for k in range(w): 
                rs[i,2*j+1,2*k+1]=input[i,j,k] 
    return rs

def my_deconv(input,weights):
    #weights shape=[out_c,in_c,h,w]
    [out_c,in_c,h,w]=weights.shape   
    out_h=h*2
    out_w=w*2
    rs=[]
    for i in range(out_c):
        w=weights[i]
        tmp=np.zeros([out_h,out_w],np.float32)
        for j in range(in_c):
            conv=compute_conv(input[j],w[j])
            #注意裁剪,最后一行和最后一列去掉
            tmp=tmp+conv[0:out_h,0:out_w]
        rs.append(tmp)

    return rs 


def main():  
    input=np.asarray(input_data,np.float32)
    input= fill_zeros(input)
    weights=np.asarray(weights_data,np.float32)
    deconv=my_deconv(input,weights)

    print(np.asarray(deconv))

if __name__=='__main__':
    main()

注意:zero_padding的总宽度是 k_size-1,左边padding的宽度是 (k_size-1)//2, 右边padding 的宽度是 k_size-1- (k_size-1)//2。即左右 padding 的数量在 k 为偶数时不相同 link .

猜你喜欢

转载自blog.csdn.net/baidu_33939056/article/details/79570853