Tensorflow:如何将numpy预训练权重分配给图形的子部分?

时间:2016-09-18 07:41:43

标签: numpy tensorflow

这是一件很简单的事情,我无法弄明白该怎么做。

我使用来自https://github.com/ethereon/caffe-tensorflow的github代码将预先训练好的VGG caffe模型转换为tensorflow并将其保存到vgg16.npy ......

然后我将网络加载到我的sess默认会话中,作为" net"使用:

images = tf.placeholder(tf.float32, [1, 224, 224, 3])
net = VGGNet_xavier({'data': images, 'label' : 1}) 
with tf.Session() as sess:
  net.load("vgg16.npy", sess) 

在net.load之后,我得到一张包含张量列表的图表。我可以使用net.layers [' conv1_1'] ...来获取每层的单个张量,以获得第一个VGG卷积层的权重和偏差等。

现在假设我制作另一个图形作为其第一层" h_conv1_b":

  W_conv1_b = weight_variable([3,3,3,64])
  b_conv1_b = bias_variable([64])
  h_conv1_b = tf.nn.relu(conv2d(im_batch, W_conv1_b) + b_conv1_b)

我的问题是 - 如何将net.layers [' conv1_1']中的预训练权重分配给h_conv1_b? (现在都是张量)

2 个答案:

答案 0 :(得分:18)

我建议您详细查看network.py中的https://github.com/ethereon/caffe-tensorflow,尤其是函数load()。它可以帮助您了解调用net.load(weight_path,session)时发生的情况。

仅供参考,可以使用在会话中执行的var.assign(np_array)将Tensorflow中的变量分配给numpy数组。以下是您问题的解决方案:

with tf.Session() as sess:    
  W_conv1_b = weight_variable([3,3,3,64])
  sess.run(W_conv1_b.assign(net.layers['conv1_1'].weights))
  b_conv1_b = bias_variable([64])
  sess.run(b_conv1_b.assign(net.layers['conv1_1'].biases))
  h_conv1_b = tf.nn.relu(conv2d(im_batch, W_conv1_b) + b_conv1_b)

我很可能会提醒您以下几点:

  1. var.assign(data)其中'数据'是一个numpy数组和' var'是一个tensorflow变量应该在您想要继续执行网络推理或培训的同一会话中执行。
  2. ' var'应该创建与'数据相同的形状'默认情况下。因此,如果您可以获得数据'在创建' var'之前,我建议您创建' var'通过方法var=tf.Variable(shape=data.shape)。否则,您需要创建' var'通过方法var=tf.Variable(validate_shape=False),这意味着变量形状是可行的。详细的解释可以在Tensorflow的API文档中找到。
  3. 我扩展了相同的repo caffe-tensorflow以支持kaffe中的theano,我可以从Theano中的caffe加载转换后的模型。因此,我是这个回购代码的合理专家。如果您有任何进一步的问题,请随时与我联系。

答案 1 :(得分:3)

您可以使用tf.Variable来自第一个网络的eval - 方法获取变量值,并使用load方法将该值加载到第二个网络的变量中(也是{ {1}})。