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

Lin*_*k L 12 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) 
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

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

小智 18

我建议你在详细了解network.pyhttps://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)
Run Code Online (Sandbox Code Playgroud)

我很乐意提醒您以下几点:

  1. var.assign(data)其中'data'是一个numpy数组而'var'是一个tensorflow变量应该在你想要继续执行你的网络推理或训练的同一个会话中执行.
  2. 默认情况下,'var'应创建为与'data'相同的形状.因此,如果您可以在创建'var'之前获取'data',我建议您通过该方法创建'var' load().否则,您需要通过方法创建'var' net.load(weight_path, session),这意味着变量形状是可行的.详细的解释可以在Tensorflow的API文档中找到.

我扩展了相同的repo caffe-tensorflow以支持kaffe中的theano,我可以从Theano中的caffe加载转换后的模型.因此,我是这个回购代码的合理专家.如果您有任何进一步的问题,请随时与我联系.


dm0*_*m0_ 3

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