UpSampling2D、Conv2DTranspose

18706 ワード

#coding:utf-8
import numpy as np
####keras            upsampling
def UpSampling2D(input_array,strides=(2,2)):
    h,w,n_channels = input_array.shape
    new_h,new_w = h*strides[0],w*strides[1]
    output_array=np.zeros((new_h,new_w,n_channels),dtype='float32')
    for i in range(new_h):
        for j in range(new_w):
            y=int(i/float(strides[0]))
            x=int(j/float(strides[1]))
            output_array[i,j,:]=input_array[y,x,:]
    return output_array
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"   # see issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = ""
import numpy as np
from Convolution1 import Convolution2D
# if padding == 'valid':
#     dim_size = dim_size * stride_size + max(kernel_size - stride_size, 0)
# elif padding == 'full':
#     dim_size = dim_size * stride_size - (stride_size + kernel_size - 2)
# elif padding == 'same':
#     dim_size = dim_size * stride_size
###(stride-1)*(img.shape-1)+img.shape

input_data=[ [[1,0,1,1],
              [0,2,1,1],
              [1,1,0,1],
              [1, 1, 0, 1]],
             [[2,0,2,1],
              [0,1,0,1],
              [1,0,0,1],
              [1, 1, 0, 1]],
             [[1,1,1,1],
              [2,2,0,1],
              [1,1,1,1],
              [1, 1, 0, 1]],
             [[1,1,2,1],
              [1,0,1,1],
              [0,2,2,1],
              [1, 1, 0, 1]]]
weights_data=[ [[[ 1, 0, 1],
                 [-1, 1, 0],
                 [ 0,-1, 0]],
                [[-1, 0, 1],
                 [ 0, 0, 1],
                 [ 1, 1, 1]],
                [[ 0, 1, 1],
                 [ 2, 0, 1],
                 [ 1, 2, 1]
                 ],
                [[ 1, 1, 1],
                 [ 0, 2, 1],
                 [ 1, 0, 1]
                 ]],
               [[[ 1, 0, 2],
                 [-2, 1, 1],
                 [ 1,-1, 0]
                 ],
                [[-1, 0, 1],
                 [-1, 2, 1],
                 [ 1, 1, 1]
                 ],
                [[ 0, 0, 0],
                 [ 2, 2, 1],
                 [ 1,-1, 1]
                 ],
                [[ 2, 1, 1],
                 [ 0,-1, 1],
                 [ 1, 1, 1]
                 ]] ]

a = np.asarray(input_data)
b = np.asarray(weights_data)
print('input_data',a.shape)
print('weight_data',b.shape)
def ConvTranspose2D(input_array,kernels,strides = (2,2),padding = 'same'):
    s_h,s_w = strides
    h,w,n = input_array.shape
    filters_num,k_h,k_w,n_channels = kernels.shape
    new_h,new_w = (s_h-1)*(h+1)+h,(s_w-1)*(w+1)+w
    tmp_array = np.zeros(shape=(new_h,new_w,n))
    y_range = range(s_h-1,new_h,s_h)
    x_range = range(s_w-1,new_w,s_w)
    for j in y_range:
        for i in x_range:
            tmp_array[j,i,:] = input_array[j//s_h,i//s_w,:]
    if padding == 'same':
        padding_h = new_h-1+k_h-new_h
        padding_w = new_w-1+k_w-new_w
        top_padding = padding_h // 2
        bottom_padding = padding_h - top_padding
        left_padding = padding_w // 2
        right_padding = padding_w - left_padding
        # print(origin_matrix.shape)
        tmp_array = np.pad(tmp_array, ((top_padding, bottom_padding), (left_padding, right_padding), (0, 0)),
                      mode='constant', constant_values=((0, 0), (0, 0), (0, 0)))
        print(tmp_array.shape)
        result = Convolution2D(tmp_array,kernels,kernel_b=None,stride=(1,1),padding= 'valid')
        print(result.shape)
        print(result[:h*2,:w*2,0])
import tensorflow as tf

def tf_conv2d_transpose(input,weights):
    #input_shape=[n,height,width,channel]
    input_shape = input.get_shape().as_list()
    #weights shape=[height,width,out_c,in_c]
    weights_shape=weights.get_shape().as_list()
    output_shape=[input_shape[0], input_shape[1]*2 , input_shape[2]*2 , weights_shape[2]]
    print("output_shape:",output_shape)
    deconv=tf.nn.conv2d_transpose(input,weights,output_shape=output_shape, strides=[1, 2, 2, 1], padding='SAME')
    return deconv
def main(input_data,weights_data):
    weights_np=np.asarray(weights_data,np.float32) #           180°
    weights_np=np.rot90(weights_np,2,(2,3))
    const_input = tf.constant(input_data , tf.float32)
    const_weights = tf.constant(weights_np , tf.float32 )
    input = tf.Variable(const_input,name="input") #[c,h,w]------>[h,w,c]
    input=tf.transpose(input,perm=(1,2,0)) #[h,w,c]------>[n,h,w,c]
    input=tf.expand_dims(input,0) #weights shape=[out_c,in_c,h,w]
    weights = tf.Variable(const_weights,name="weights") #[out_c,in_c,h,w]------>[h,w,out_c,in_c]
    weights=tf.transpose(weights,perm=(2,3,0,1)) #  tensorflow    
    deconv=tf_conv2d_transpose(input,weights)
    init=tf.global_variables_initializer()
    sess=tf.Session()
    sess.run(init)
    deconv_val = sess.run(deconv)
    hwc=deconv_val
    hwc = np.squeeze(hwc,0)
    print(hwc[:,:,0])


if __name__ == '__main__':

    input_data1 = np.asarray(input_data,dtype='float32').transpose((1,2,0))
    weights_data1 = np.asarray(weights_data,dtype='float32').transpose((0,2,3,1))
    input_data = np.asarray(input_data, dtype='float32')
    weights_data = np.asarray(weights_data, dtype='float32')
    #print(input_data.shape)
    #print(weights_data.shape)

    ConvTranspose2D(input_data1,weights_data1)
    main(input_data,weights_data)