#coding:utf-8
import numpy as np
import sys
def Padding(origin_matrix,kenel,stride=(3,3)):
img_h, img_w, n_channels = origin_matrix.shape
feature_num, k_h, k_w, k_n_channels = kenel.shape
if n_channels!= k_n_channels:
print('error')
sys.exit()
if len(origin_matrix.shape)!=len(kenel.shape)-1:
print ('error')
sys.exit()
stride_h,stride_w = stride
des_h = int(np.ceil(img_h/float(stride_h)))
des_w = int(np.ceil(img_w/float(stride_w)))
padding_h = (des_h -1)*stride_h +k_h-img_h
padding_w = (des_w -1)*stride_w +k_w-img_w
print(padding_h, padding_w)
#print(origin_matrix.shape)
if padding_h>=0 and padding_w>=0:
top_padding = padding_h // 2
bottom_padding = padding_h - top_padding
left_padding = padding_w // 2
right_padding = padding_w - left_padding
return np.pad(origin_matrix,((top_padding,bottom_padding),(left_padding,right_padding),(0,0)),mode='constant',constant_values=((0,0),(0,0),(0,0)))
if padding_h>=0 and padding_w<0:
top_padding = padding_h // 2
bottom_padding = padding_h - top_padding
padding_w = -padding_w
left_padding = 0
right_padding = padding_w - left_padding
origin_matrix =np.pad(origin_matrix,((top_padding,bottom_padding),(0,0),(0,0)),mode='constant',constant_values=((0,0),(0,0),(0,0)))
return origin_matrix[:,left_padding:img_w-right_padding,:]
if padding_h<0 and padding_w>=0:
padding_h = -padding_h
top_padding = 0
bottom_padding = padding_h - top_padding
left_padding = padding_w // 2
right_padding = padding_w - left_padding
origin_matrix =np.pad(origin_matrix,((0,0),(left_padding,right_padding),(0,0)),mode='constant',constant_values=((0,0),(0,0),(0,0)))
return origin_matrix[top_padding:img_h-bottom_padding,:,:]
if padding_h<0 and padding_w<0:
padding_h = -padding_h
padding_w = -padding_w
top_padding = 0
bottom_padding = padding_h-top_padding
left_padding = 0
right_padding = padding_w-left_padding
return origin_matrix[top_padding:img_h-bottom_padding,left_padding:img_w-right_padding,:]
def Convolution2D(origin_matrix=None,kenel=None,kernel_b=None,stride=(3,3),padding='same'):
img_h,img_w,n_channels = origin_matrix.shape
feature_num, k_h, k_w, k_n_channels = kenel.shape
if n_channels!= k_n_channels:
print('n_channels_error')
sys.exit()
if len(origin_matrix.shape)!=len(kenel.shape)-1:
print ('length_error')
sys.exit()
stride_h,stride_w = stride
des_h = int(np.ceil((img_h-k_h+1)/float(stride_h)))
des_w = int(np.ceil((img_w-k_w+1)/float(stride_w)))
### height = (img_h-k_h) // stride_h + 1
### width = (img_w-k_w) // stride_w + 1
if padding=='same':
origin_matrix = Padding(origin_matrix,kenel,stride)
print(origin_matrix.shape)
img_h, img_w, n_channels = origin_matrix.shape
des_h = int(np.ceil((img_h - k_h + 1) / float(stride_h)))
des_w = int(np.ceil((img_w - k_w + 1) / float(stride_w)))
des_conv = np.zeros(shape=(des_h,des_w,feature_num))
#print(origin_matrix.shape)
#print(des_conv.shape)
if kernel_b is None:
for h in np.arange(des_h):
for w in np.arange(des_w):
h_shift, w_shift = h * stride_h, w * stride_w
tmp = origin_matrix[h_shift:h_shift + k_h, w_shift:w_shift + k_w, :]
for each_feature in np.arange(feature_num):
des_conv[h, w, each_feature] = np.sum(tmp * kenel[each_feature]) ##可添加激
else:
for h in np.arange(des_h):
for w in np.arange(des_w):
h_shift, w_shift = h * stride_h, w * stride_w
tmp = origin_matrix[h_shift:h_shift + k_h, w_shift:w_shift + k_w, :]
for each_feature in np.arange(feature_num):
des_conv[h, w, each_feature] = np.sum(tmp * kenel[each_feature]) + kernel_b[each_feature] ##可添加激活
return des_conv
if __name__ == '__main__':
img_h, img_w, n = 13, 13, 1
k_h, k_w, k_n = 4, 4, 1
s_h, s_w =3, 4
kernel = np.random.randint(0, 10, (1, k_h, k_w, n))
data = np.random.randint(0,10,(img_h,img_w,n))
data = np.asarray(data,dtype='float32')
#print(data)
kernel = np.asarray(kernel,dtype='float32')
#print(kernel)
stride = (s_h, s_w)
result = Convolution2D(data, kernel, kernel_b=None, stride=stride, padding='same')
print(result)
import tensorflow as tf
data = np.expand_dims(data,axis=0)
kernel = np.transpose(kernel,(1,2,3,0))
const_input = tf.constant(data, tf.float32)
const_weights = tf.constant(kernel, tf.float32)
y2 = tf.nn.conv2d(data, kernel, strides=[1, s_h, s_w, 1], padding="SAME")
sess = tf.Session()
print(sess.run(y2).squeeze(axis=0))
print(result.shape)
print(sess.run(y2).shape)