反卷积与反卷积核的初始化问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30638831/article/details/83187224

导论:

https://blog.csdn.net/qq_30638831/article/details/81532892

https://cv-tricks.com/image-segmentation/transpose-convolution-in-tensorflow/

https://zhuanlan.zhihu.com/p/38964806

tf.nn.conv2d_transpose(

                     conv,   卷积后的结果  ,假设为 (16,375,250,64)

                     权重的初始化,   使用线性插值,请参考后面,  [3,3,3,64] [kernel,kernel,输出特征个数,输入特征个数],

                      输出的初始化,    [16,750,500,3]   [batch,height,width,chanel]   chanel必须与输出特征个数相等

                       strides=[1,2,2,1],padding='SAME'

)  

conts = tf.nn.conv2d_transpose(pool,kernel2,output_shape,strides=[1,2,2,1],padding='SAME')

插值的目的:  把图像更精确的语义分割与得到原像素

差值等大小的filter:


from math import ceil
import numpy as np

import tensorflow as tf


def __get_deconv_filter(f_shape):
    """
    Compute bilinear filter and return it
    """
    filt_width = f_shape[0]  #计算kernel的宽
    filt_height = f_shape[1] #计算kernel的长
    half_width = ceil(filt_width /2.0)
    center = (2 * half_width - 1 - half_width % 2) / (2.0 * half_width) # 计算某点的权值  对这个点进行插值
    bilinear = np.zeros([filt_width, filt_height])
    for x in range(filt_width):
        for y in range(filt_height):
            value = (1 - abs(x / half_width - center)) * (1 - abs(y / half_width - center))
            bilinear[x, y] = value
    weights = np.zeros(f_shape)
    for i in range(f_shape[2]):
        weights[:, :, i, i] = bilinear
        print(weights[:, :, i, i])



    init = tf.constant_initializer(value=weights,
                                   dtype=tf.float32)
    return tf.get_variable(name="up_filter", initializer=init,
                           shape=weights.shape)
a = __get_deconv_filter([3, 3, 3, 3])

差值翻倍的kernel:

def get_kernel_size(factor):
    """
    Find the kernel size given the desired factor of upsampling.
    """
    #获取kernel的大小
    return 2 * factor - factor % 2


def upsample_filt(size):
    """
    Make a 2D bilinear kernel suitable for upsampling of the given (h, w) size.
    """
    factor = (size + 1) // 2
    if size % 2 == 1:
        center = factor - 1
    else:
        center = factor - 0.5
    og = np.ogrid[:size, :size]
    return (1 - abs(og[0] - center) / factor) * \
           (1 - abs(og[1] - center) / factor)





def bilinear_upsample_weights(factor, number_of_classes):
    """
    Create weights matrix for transposed convolution with bilinear filter
    initialization.
    """

    filter_size = get_kernel_size(factor)

    weights = np.zeros((filter_size,
                        filter_size,
                        3,
                        4), dtype=np.float32)

    upsample_kernel = upsample_filt(filter_size)

    for i in range(3):
        weights[:, :, i, i] = upsample_kernel

    return weights


print(bilinear_upsample_weights(2,21).shape)
import tensorflow as tf
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

from math import ceil

'''
    一张图片的反卷积
'''

im = Image.open('timg.jpg')
images = np.asarray(im)
print(images.shape)

images = np.reshape(images,[1,750,500,3])

img = tf.Variable(images,dtype=tf.float32)
# kernel = tf.get_variable(name='a',shape=[3, 3, 3, 3], dtype=tf.float32,
#                                   initializer=tf.contrib.layers.xavier_initializer())

# 卷积核
kernel = tf.get_variable(name='a',shape=[3, 3, 3, 64], dtype=tf.float32,
                                  initializer=tf.contrib.layers.xavier_initializer())



def __get_deconv_filter(f_shape):
    """
    Compute bilinear filter and return it
    """
    filt_width = f_shape[0]  #计算kernel的宽
    filt_height = f_shape[1] #计算kernel的长
    half_width = ceil(filt_width /2.0)
    center = (2 * half_width - 1 - half_width % 2) / (2.0 * half_width) # 计算某点的权值  对这个点进行插值
    bilinear = np.zeros([filt_width, filt_height])
    for x in range(filt_width):
        for y in range(filt_height):
            value = (1 - abs(x / half_width - center)) * (1 - abs(y / half_width - center))
            bilinear[x, y] = value
    weights = np.zeros(f_shape)
    for i in range(f_shape[2]):
        weights[:, :, i, i] = bilinear
        print(weights[:, :, i, i])



    init = tf.constant_initializer(value=weights,
                                   dtype=tf.float32)
    return  init



# 反卷积核
kernel2 = tf.get_variable(name='a1',shape=[3, 3, 3, 64], dtype=tf.float32,
                                  initializer=__get_deconv_filter([3,3,3,64]))

#tf.nn.conv2d(input=input_op, filter=weights, strides=[1, dh, dw, 1], padding="SAME")

# 卷积
conv1 = tf.nn.conv2d(input=img, filter=kernel,strides=[1, 1, 1, 1], padding="SAME")
# print(conv1)
# 池化
pool = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

shape_ = pool.get_shape().as_list()
print(shape_) #[1, 375, 250, 64]
output_shape = [shape_[0], shape_[1] * 2, shape_[2] * 2, 3]

print('pool:',pool.get_shape())
# 反卷积操作
conts = tf.nn.conv2d_transpose(pool,kernel2,output_shape,strides=[1,2,2,1],padding='SAME')

# print(conv1.get_shape())

a = tf.transpose(conts, [0, 3, 1, 2])

b = tf.transpose(tf.squeeze(a) , [1,2,0])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    # conv1_convert = sess.run(tf.transpose(conts, [0, 3, 1, 2]))



    # fig6, ax6 = plt.subplots(nrows=3, ncols=8, figsize=(8, 8))
    # plt.title('Pool2 32x7x7')
    # for i in range(8):
    #     for j in range(8):
    #         ax6[i][j].imshow(conv1_convert[0][(i + 1) * j])

    # plt.show()

    plt.imshow(sess.run(b))

    plt.show()

猜你喜欢

转载自blog.csdn.net/qq_30638831/article/details/83187224