Tensorflow:加载预训练的ResNet模型时出错

时间:2019-03-01 22:13:16

标签: python tensorflow

我想使用Tensorflow中经过预训练的ResNet模型。我下载了模型的coderesnet_v1.py)和checkpointresnet_v1_50.ckpt)文件here

我已经可以通过使用以下帖子解决错误ImportError: No module named 'nets':请参见heretsveti_iko答案。

现在我收到以下错误,并且不知道该怎么办:

NotFoundError (see above for traceback): Restoring from checkpoint failed. 
This is most likely due to a Variable name or other graph key that is missing from the checkpoint. 
Please ensure that you have not altered the graph expected based on the checkpoint. Original error:

    Tensor name "resnet_v1_50/block1/unit_1/bottleneck_v1/conv1/biases" 
not found in checkpoint files /home/resnet_v1_50.ckpt
         [[node save/RestoreV2 (defined at my_resnet.py:34)  = 
RestoreV2[dtypes=[DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT, ...,
DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT], _device="/job:localhost
/replica:0/task:0/device:CPU:0"](_arg_save/Const_0_0, save/RestoreV2
/tensor_names, save/RestoreV2/shape_and_slices)]]

这是我尝试加载模型的代码:

import numpy as np
import tensorflow as tf
import resnet_v1

# Restore variables of resnet model
slim = tf.contrib.slim

# Paths
network_dir = "home/resnet_v1_50.ckpt"

# Image dimensions
in_width, in_height, in_channels = 224, 224, 3

# Placeholder
X = tf.placeholder(tf.float32, [None, in_width, in_height, in_channels])

# Define network graph
logits, activations = resnet_v1.resnet_v1_50(X, is_training=False)
prediction = tf.argmax(logits, 1)

with tf.Session() as sess:
    variables_to_restore = slim.get_variables_to_restore()
    saver = tf.train.Saver(variables_to_restore)
    saver.restore(sess, network_dir) 

    # Restore variables
    variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)

    # Feed random image into resnet
    img = np.random.randn(1, in_width, in_height, in_channels)
    pred = sess.run(prediction, feed_dict={X:img})

有人可以告诉我,为什么它不起作用?我该如何更改代码才能使其运行?

1 个答案:

答案 0 :(得分:2)

也许您可以使用enter image description here中的ResNet50?

根据错误,如果您没有以任何方式更改图形,并且这是您的整个源代码,那么调试起来可能真的非常困难。

如果选择理智的tf.keras.applications方法,您可以像这样简单地做到这一点:

import tensorflow

in_width, in_height, in_channels = 224, 224, 3

pretrained_resnet = tensorflow.keras.applications.ResNet50(
    weights="imagenet",
    include_top=False,
    input_shape=(in_width, in_height, in_channels),
)

# You can freeze some layers if you want, depends on your task
# Make "top" (last 3 layers below) whatever fits your task as well

model = tensorflow.keras.models.Sequential(
    [
        pretrained_resnet,
        tensorflow.keras.layers.Flatten(),
        tensorflow.keras.layers.Dense(1024, activation="relu"),
        tensorflow.keras.layers.Dense(10, activation="softmax"),
    ]
)

print(model.summary())

现在将推荐使用此方法,尤其是考虑到即将推出的Tensorflow 2.0,理智和可读性。 顺便说一句。此模型与Tensorflow提供的模型相同,是从IIRC转移过来的。

您可以在链接的文档以及tf.keras.applications.resnet50等各种博客文章或其他网络资源中详细了解tf.keras.applications

我如何在Keras中

回答评论中的问题

  • How do I pass images to the network?:如果要进行预测(图像为model.predict(image)),请使用np.array。就这么简单。

  • How do I access weights?:嗯,这比较复杂...开个玩笑,每一层都有.get_weights()方法,该方法返回其权重和偏差,您可以使用{{1 }}。您也可以使用for layer in model.layers()一次获得所有权重。

总而言之,您将在比调试Tensorflow短的时间内学习Keras并比在Tensorflow中提高生产力。他们之所以有this one

顺便说一句。 Tensorflow默认情况下已提供Keras,因此,Tensorflow的Keras风味 是Tensorflow的一部分(无论听起来有多混乱)。这就是为什么我在示例中使用model.get_weights()的原因。

使用Tensorflow的集线器解决方案

似乎您可以按照30 seconds guide中的说明使用Hub加载和微调 Resnet50