首页 文章

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

提问于
浏览
11

这是一个简单的事情,我无法弄清楚该怎么做 .

我使用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 回答

  • 14

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

  • 3

    我建议你从https://github.com/ethereon/caffe-tensorflow详细查看network.py,尤其是函数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)
    

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

    • var.assign(data)其中'data'是一个numpy数组,而'var'是一个tensorflow变量应该在你想要继续执行网络推理或训练的同一个会话中执行 .

    • 默认情况下,'var'应创建为与'data'相同的形状 . 因此,如果您在创建'var'之前可以获得'data',我建议您通过方法 var=tf.Variable(shape=data.shape) 创建'var' . 否则,您需要通过方法 var=tf.Variable(validate_shape=False) 创建'var',这意味着变量形状是可行的 . 详细的解释可以在Tensorflow的API文档中找到 .

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

相关问题