我想将一些由另一个网络训练的权重转移到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)
我得到的功能图是错误的 .
2 回答
不要使用
np.reshape
. 它可能mess up the order of your values .请改用np.rollaxis:
请注意,尺寸为3的两个轴的顺序没有改变 . 如果我要标记它们,那么两个
rollaxis
操作会导致形状变为(1,2,31,32) - >(1,31,32,2) - >(31,32,2,1) . 你的最终数组如下:样本张量操作
我不知道这是否有帮助 . 考虑Reshape,Gather,Dynamic_partition和Split操作,并根据您的需要进行调整 . 下面是这些操作的说明,可以适应您的情况 . 我从我的git repo中复制了这个 . 我相信如果你在ipython中运行这些例子,你可以弄清楚你真正想要的是什么,并获得更好的洞察力 .
重塑,收集,动态分区和拆分
收集操作(tf.gather())
生成数组并测试收集操作 . 请注意这种快速原型制作方法:
使用:根据指数从params收集切片 .
indices必须是任何维度的整数张量(通常为0-D或1-D) . 最好通过一个例子来说明:
看一下这个简单的例子:
初始化简单数组
测试收集操作
在[11]中:
注意:输入大小和输出大小必须相同 . ---否则会出错 . 检查这个的简单方法是通过简单的乘法确保输入可以分成重塑参数 .
Dynamic_cell_partitions
tf.split()
确保使用最新的tensorflow版本 . 否则在旧版本中,此实现将给出错误
这在文档中指定如下:
tf.split(value,num_or_size_splits,axis = 0,num = None,name ='split') .
它将张量分割为子张量 . 最好通过一个例子来说明:
希望这可以帮助!