title: extracting Bottleneck features using pretrained Inceptionv3 - differences between Keras' implementation and Native Tensorflow implementation
body: <p>(Apologies for the long post)</p>
  
  <p>All,</p>
  
  <p>I want to use the bottleneck features from a pretrained Inceptionv3 model to predict classification for my input images. Before training a model and predicting classification, I tried 3 different approaches for extracting the bottleneck features.</p>
  
  <p>My 3 approaches yielded different bottleneck features (not just in values but even the size was different). </p>
  
  <ol>
  <li><p>Size of my bottleneck features from Approach 1 and 2: (number of input images) x 3 x 3 x 2048</p>
  
  <p>Size of my bottleneck features from Approach 3: (number of input images) x 2048</p>
  
  <p>Why are the sizes different between the Keras based Inceptionv3 model and the native Tensorflow model? My guess is that when I say include_top=False in Keras, I'm not extracting the 'pool_3/_reshape:0' layer. Is this correct? If yes, how do I extract the 'pool_3/_reshape:0' layer in Keras? If my guess is incorrect, what 'am I missing?</p></li>
  <li><p>I compared the bottleneck feature values from Approach 1 and 2 and they were significantly different. I think I'm feeding it the same input images because I resize and rescale my images before I even read it as input for my script. I have no options for my ImageDataGenerator in Approach 1 and according to the documentation for that function all the default values do not change my input image. I have set shuffle to false so I assumed that predict_generator and predict are reading images in the same order. What 'am I missing?</p></li>
  </ol>
  
  <hr>
  
  <p>Please note:</p>
  
  <p>My inputs images are in RGB format (so number of channels = 3) and I resized all of them to 150x150. I used the preprocess_input function in <a href="https://github.com/fchollet/keras/blob/master/keras/applications/inception_v3.py" rel="noreferrer">inceptionv3.py</a> to preprocess all my images. </p>
  
  <pre><code>def preprocess_input(image):
      image /= 255.
      image -= 0.5
      image *= 2.
      return image
  </code></pre>
  
  <hr>
  
  <h2>Approach 1: Used Keras with tensorflow as backend, an ImageDataGenerator to read my data and model.predict_generator to compute bottleneck features</h2>
  
  <p>I followed the <a href="https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html" rel="noreferrer">example</a> (Section <em>Using the bottleneck features of a pre-trained network: 90% accuracy in a minute</em>) from Keras' blog. Instead of VGG model listed there I used Inceptionv3. Below is the snippet of code I used</p>
  
  <p>(code not shown here but what i did before the code below) : read all input images, resize to 150x150x3, rescale according to the preprocessing_input function mentioned above, save the resized and rescaled images</p>
  
  <pre><code>train_datagen = ImageDataGenerator() 
  train_generator = train_datagen.flow_from_directory(my_input_dir, target_size=(150,150),shuffle=False, batch_size=16)
  
  # get bottleneck features
  # use pre-trained model and exclude top layer - which is used for classification
  pretrained_model = InceptionV3(include_top=False, weights='imagenet', input_shape=(150,150,3))
  bottleneck_features_train_v1 = pretrained_model.predict_generator(train_generator,len(train_generator.filenames)//16)
  </code></pre>
  
  <h2>Approach 2: Used Keras with tensorflow as backend, my own reader and model.predict to compute bottleneck features</h2>
  
  <p>Only difference between this approach and earlier one is that I used my own reader to read the input images.
  (code not shown here but what i did before the code below) : read all input images, resize to 150x150x3, rescale according to the preprocessing_input function mentioned above, save the resized and rescaled images</p>
  
  <pre><code># inputImages is a numpy array of size &lt;number of input images x 150 x 150 x 3&gt;
  inputImages = readAllJPEGsInFolderAndMergeAsRGB(my_input_dir)
  
  # get bottleneck features
  # use pre-trained model and exclude top layer - which is used for classification
  pretrained_model = InceptionV3(include_top=False, weights='imagenet', input_shape=(img_width, img_height, 3))
  bottleneck_features_train_v2 = pretrained_model.predict(trainData.images,batch_size=16)
  </code></pre>
  
  <h2>Approach 3: Used tensorflow (NO KERAS) compute bottleneck features</h2>
  
  <p>I followed <a href="https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/image_retraining/retrain.py" rel="noreferrer">retrain.py</a> to extract bottleneck features for my input images. Please note that that the weights from that script can be obtained from (<a href="http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz" rel="noreferrer">http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz</a>)</p>
  
  <p>As mentioned in that example, I used the bottleneck_tensor_name = 'pool_3/_reshape:0' as the layer to extract and compute bottleneck features. Similar to the first 2 approaches, I used resized and rescaled images as input to the script and I called this feature list bottleneck_features_train_v3</p>
  
  <p>Thank you so much </p>