jrabary
jrabary

Reputation: 2441

InceptionV3 and transfer learning with tensorflow

I would like to do a transfer learning from the given inceptionV3 in tensorflow example. Following the classify image example and the operator and tensor names given here https://github.com/AKSHAYUBHAT/VisualSearchServer/blob/master/notebooks/notebook_network.ipynb I can create my graph. But when, I put a batch of images of size (100, 299, 299, 3) in the pre-computed inception graph, I get the following shape error at the pool_3 layer :

ValueError: Cannot reshape a tensor with 204800 elements to shape [1, 2048] (2048 elements)

It seems that this inceptionV3 graph doesn't accept image batch as input. am I wrong ?

Upvotes: 4

Views: 2211

Answers (4)

Yanmao Man
Yanmao Man

Reputation: 1

etarion made a very good point. However, we don't have to reshape it ourselves; instead, we could change the value of shape that reshape takes as input. I.e.,

input_tensor_name = 'import/input:0'
shape_tensor_name = 'import/InceptionV3/Predictions/Shape:0'
output_tensor_name= 'import/InceptionV3/Predictions/Reshape_1:0'

output_tensor = tf.import_graph_def(
    graph.as_graph_def(),
    input_map={input_tensor_name: image_batch,
               shape_tensor_name: [batch_size, num_class]},
    return_elements=[output_tensor_name])

These tensor names are based on inception_v3_2016_08_28_frozen.pb.

Upvotes: 0

Ivan Jacobs
Ivan Jacobs

Reputation: 178

Something like this should do it:

    with g.as_default():
     inputs = tf.placeholder(tf.float32, shape=[batch_size, 299, 299, 3],
                                name='input')

        with slim.arg_scope(inception.inception_v3_arg_scope()):

            logits, end_points = inception.inception_v3( inputs, 
            num_classes=FLAGS.num_classes, is_training=False)
            variables_to_restore = lim.get_variables_to_restore(exclude=exclude)
        sess = tf.Session()

        saver = tf_saver.Saver(variables_to_restore)

Then you should be able to call the operation:

        sess.run("pool_3:0",feed_dict={'ResizeBilinear:0':images})

Upvotes: 0

etarion
etarion

Reputation: 17169

Actually it works for transfer learning if you extract the right thing. There is no problem feeding a batch of images in the shape of [N, 299, 299, 3] as ResizeBilinear:0 and then using the pool_3:0 tensor. It's the reshaping afterwards that breaks, but you can reshape yourself (you'll have your own layers afterwards anyway). If you wanted to use the original classifier with a batch, you could add your own reshaping on top of pool_3:0 and then add the softmax layer, reusing the weights/biases tensors of the original softmax.

TLDR: With double_img being a stack of two images with shape (2, 299, 299, 3) this works:

pooled_2 = sess.graph.get_tensor_by_name("pool_3:0").eval(session=sess, feed_dict={'ResizeBilinear:0':double_img})
pooled_2.shape
# => (2, 1, 1, 2048)

Upvotes: 4

dga
dga

Reputation: 21927

You're not wrong. This seems like a very reasonable feature request, so I've opened a ticket for it on github. Follow that for updates.

Upvotes: 2

Related Questions