我想将一些由另一个网络训练的权重转移到TensorFlow,权重存储在一个向量中,如下所示:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
通过使用numpy,我可以将它重塑为两个3乘3的过滤器,如下所示:
1 2 3 9 10 11 3 4 5 12 13 14 6 7 8 15 16 17
因此,我的过滤器的形状是(1,2,3,3)
.但是,在TensorFlow中,过滤器的形状为(3,3,2,1)
:
tf_weights = tf.Variable(tf.random_normal([3,3,2,1]))
在将tf_weights重塑为预期形状后,重量变得混乱,我无法获得预期的卷积结果.
具体来说,当图像或滤镜的形状是[数字,通道,大小,大小]时,我写了一个卷积函数,它给出了正确的答案,但它太慢了:
def convol(images,weights,biases,stride): """ Args: images:input images or features, 4-D tensor weights:weights, 4-D tensor biases:biases, 1-D tensor stride:stride, a float number Returns: conv_feature: convolved feature map """ image_num = images.shape[0] #the number of input images or feature maps channel = images.shape[1] #channels of an image,images's shape should be like [n,c,h,w] weight_num = weights.shape[0] #number of weights, weights' shape should be like [n,c,size,size] ksize = weights.shape[2] h = images.shape[2] w = images.shape[3] out_h = (h+np.floor(ksize/2)*2-ksize)/2+1 out_w = out_h conv_features = np.zeros([image_num,weight_num,out_h,out_w]) for i in range(image_num): image = images[i,...,...,...] for j in range(weight_num): sum_convol_feature = np.zeros([out_h,out_w]) for c in range(channel): #extract a single channel image channel_image = image[c,...,...] #pad the image padded_image = im_pad(channel_image,ksize/2) #transform this image to a vector im_col = im2col(padded_image,ksize,stride) weight = weights[j,c,...,...] weight_col = np.reshape(weight,[-1]) mul = np.dot(im_col,weight_col) convol_feature = np.reshape(mul,[out_h,out_w]) sum_convol_feature = sum_convol_feature + convol_feature conv_features[i,j,...,...] = sum_convol_feature + biases[j] return conv_features
相反,通过使用tensorflow的conv2d,如下所示:
img = np.zeros([1,3,224,224]) img = img - 1 img = np.rollaxis(img, 1, 4) weight_array = googleNet.layers[1].weights weight_array = np.reshape(weight_array,[64,3,7,7]) biases_array = googleNet.layers[1].biases tf_weight = tf.Variable(weight_array) tf_img = tf.Variable(img) tf_img = tf.cast(tf_img,tf.float32) tf_biases = tf.Variable(biases_array) conv_feature = tf.nn.bias_add(tf.nn.conv2d(tf_img,tf_weight,strides=[1,2,2,1],padding='SAME'),tf_biases) sess = tf.Session() sess.run(tf.initialize_all_variables()) feautre = sess.run(conv_feature)
我得到的功能图是错误的.
不要用np.reshape
.它可能搞乱你的价值观的顺序.
np.rollaxis
改为使用:
>>> a = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]) >>> a = a.reshape((1,2,3,3)) >>> a array([[[[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]]]) >>> b = np.rollaxis(a, 1, 4) >>> b.shape (1, 3, 3, 2) >>> b = np.rollaxis(b, 0, 4) >>> b.shape (3, 3, 2, 1)
请注意,尺寸为3的两个轴的顺序没有改变.如果我要对其进行标记,这两个rollaxis
操作引起的形状改变为(1,2,3 1,3 2) - >(1,3 1,3 2,2) - >(3 1,3 2,2 ,1).你的最终数组如下:
>>> b array([[[[ 1], [10]], [[ 2], [11]], [[ 3], [12]]], [[[ 4], [13]], [[ 5], [14]], [[ 6], [15]]], [[[ 7], [16]], [[ 8], [17]], [[ 9], [18]]]])