在TensorFlow中微调Inception模型

时间:2016-10-12 10:41:29

标签: tensorflow

我想在我自己的数据集上使用预先训练的Inception模型,我也想微调Inception模型本身的变量。

我已从以下链接下载了TensorFlow预训练的Inception模型:

http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz

我按如下方式加载Inception模型:

graph = tf.Graph()
with graph.as_default():
    with tf.gfile.FastGFile('classify_image_graph_def.pb', 'rb') as file:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(file.read())
        tf.import_graph_def(graph_def, name='')

(关于API的旁注:如果我能写graph = tf.load_graph('inception.pb')而不是这六个嵌套和复杂的行,那将是很好的。)

然后我在Inception模型中的softmax分类器之前获得对最后一层的张量的引用:

last_layer = graph.get_tensor_by_name('pool_3:0')

现在我想在图中附加一个新的softmax分类器,这样我就可以训练新的softmax分类器并训练一些或所有变量在Inception模型中。这是我理解的微调,而不是转移学习,只有新的softmax分类器在我自己的数据集上训练。

然后我使用PrettyTensor附加新的softmax分类器(注意y_true是占位符变量):

with pt.defaults_scope(activation_fn=tf.nn.relu):
    y_pred, loss = pt.wrap(last_layer).\
        flatten().\
        softmax_classifier(class_count=10, labels=y_true)

但是这会给出一个很长的错误消息,其中最后一部分是:

ValueError: Tensor("flatten/reshape/Const:0", shape=(2,), dtype=int32) must be from the same graph as Tensor("pool_3:0", shape=(1, 1, 1, 2048), dtype=float32).

所以我显然不允许像这样组合两个图。

我还尝试使用reshape()代替flatten(),如下所示(请注意,Inception模型的最后一层有2048个功能):

with pt.defaults_scope(activation_fn=tf.nn.relu):
    y_pred, loss = pt.wrap(last_layer).\
        reshape([-1, 2048]).\
        softmax_classifier(class_count=10, labels=y_true)

但这会产生几乎相同的错误:

ValueError: Tensor("reshape/Const:0", shape=(2,), dtype=int32) must be from the same graph as Tensor("pool_3:0", shape=(1, 1, 1, 2048), dtype=float32).

我也尝试将其包装在graph.as_default()中,如此:

with graph.as_default():
    with pt.defaults_scope(activation_fn=tf.nn.relu):
        y_pred, loss = pt.wrap(last_layer).\
            reshape([-1, 2048]).\
            softmax_classifier(class_count=10, labels=y_true)

但这会产生类似的错误:

ValueError: Tensor("ArgMax_1:0", shape=(?,), dtype=int64) must be from the same graph as Tensor("cross_entropy/ArgMax:0", shape=(1,), dtype=int64).

我如何微调Inception模型?我想添加一个新的softmax分类器,我想微调Inception模型本身的部分或全部变量。

谢谢!

编辑:

我对这个问题有部分解决方案。

错误消息是因为我没有将所有代码放在with graph.as_default():块中。将所有代码放在该块中可以修复错误消息,现在我可以使用PrettyTensor将新的softmax层附加到Inception模型,如上所述。

然而,Inception模型显然是一个“冻结”图形,这意味着所有变量在保存之前都已转换为常量。

所以现在我的问题是,我是否能以某种方式'解冻'Inception模型的图形,所以我可以继续训练其图形的部分或全部变量?我该怎么做?

或者我应该使用新的MetaGraph功能?

https://www.tensorflow.org/versions/r0.11/how_tos/meta_graph/index.html

在哪里可以为Inception模型下载预先训练过的MetaGraph?

2 个答案:

答案 0 :(得分:1)

我也有完全相同的问题。首先,你可以根据这个细调整个网络:https://github.com/tensorflow/models/tree/master/inception#adjusting-memory-demands 我想出了如何在我自己的数据集上实现这个代码。问题是我想微调整个网络,然后用最新的conv层和softmax替换最后2个初始模块。但是,我认为如果我进行整个微调,那么我需要恢复权重直到第8个初始模块并仅训练新层,但这不能仅通过tensorflow的恢复功能发生。另一个好方法是:https://www.tensorflow.org/versions/r0.9/how_tos/image_retraining/index.html 您可以从.pb文件中获取预训练网络,但这仅适用于根据tensorflow进行传输学习。我想到的唯一解决方案就是对整个网络进行微调,然后将其导出到.pb文件,以便将微调的权重直到我想要的层,但我无法实现。一般来说,张量流不清楚我们怎么能这样做。我也会在git上发一个问题。如果有人确切知道我们能做什么,请回答。

答案 1 :(得分:1)

我使用tf-slim来微调初始模型。您可以在https://github.com/tensorflow/models/tree/master/research/slim找到图书馆。他们提供了一个演练,描述了自定义数据集上的微调初始网络。该库还具有模型定义流行分类模型以及权重文件。