I want all the output of the pretrained VGG16 model as well as the new classes it is trained on












0















I have tried transfer learning using VGG16 but only getting a result for those classes which are trained.I want that the output consists of both the VGG16 classes+ my new trained classes. Is it possible?



I have attached my whole code.



`enter code here`import matplotlib.pyplot as plt
import PIL
import tensorflow as tf
import numpy as np
import os





import keras
from keras.models import Sequential, Model
from keras.layers.core import Dense, Dropout, Flatten, Reshape, Activation
from keras.layers import Embedding, Input, merge, ELU
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.optimizers import SGD, Adam, RMSprop
from keras.regularizers import l2
from keras.utils.np_utils import to_categorical
import sklearn.metrics as metrics
from PIL import Image, ImageDraw
from keras.applications import VGG16
from keras.applications.vgg16 import preprocess_input, decode_predictions
from keras.preprocessing.image import ImageDataGenerator


# # Helper Function




def load_images(image_paths):
# Load the images from disk.
images = [plt.imread(path) for path in image_paths]

# Convert to a numpy array and return it.
return np.asarray(images)





def path_join(dirname, filenames):
return [os.path.join(dirname, filename) for filename in filenames]


# In[5]:


train_dir = "/home/priyank/Jupyter_notebook/plant_leaves_train_set"
test_dir = "/home/priyank/Jupyter_notebook/val_data_plant"


# # Pre-Trained Model: VGG16
# Downloading the pretrained model of imagenet dataset.




model = VGG16(include_top=True, weights='imagenet')


# # Input Pipeline
# First we need to know the shape of the tensors expected as input by the pre-trained VGG16 model. In this case it is images of shape 224 x 224 x 3.



input_shape = model.layers[0].output_shape[1:3] # the input shape of the vgg16 model
input_shape


# # ImageDataGenerator
# It will pick the image one-by-one and transform all the data each time the image is loaded in the training set.





datagen_train = ImageDataGenerator(
rescale=1./255,
rotation_range=180,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
zoom_range=[0.9, 1.5],
horizontal_flip=True,
vertical_flip=True,
fill_mode='nearest')



datagen_test = ImageDataGenerator(rescale=1./255)


#
# The datagenerator will return the batches of the images. VGG16 model is too large so we can't create the batches too large otherwise we will run out of the RAM and GPU.




# Taking small batch size
batch_size = 20


#
# We can save the randomly transformed images during training, so as to inspect whether they have been overly distorted, so we have to adjust the parameters for the data-generator above.




if True:
save_to_dir = None
else:
save_to_dir='augmented_images/'



generator_train = datagen_train.flow_from_directory(directory=train_dir,
target_size=input_shape,
batch_size=batch_size,
shuffle=True,
save_to_dir=save_to_dir)





generator_test = datagen_test.flow_from_directory(directory=test_dir,
target_size=input_shape,
batch_size=batch_size,
shuffle=False)





steps_test = generator_test.n / batch_size
steps_test





image_paths_train = path_join(train_dir, generator_train.filenames)
image_paths_test = path_join(test_dir, generator_test.filenames)




cls_train = generator_train.classes
cls_test = generator_test.classes





class_names = list(generator_train.class_indices.keys())
class_names







num_classes = generator_train.num_classes
num_classes


# The dataset we have is imbalanced so the gradients for 9.01192 will remain higher adn the gradients of 0.8080 will reamin lower so that model can learn from higher gradient more than the lower gradient.
#



from sklearn.utils.class_weight import compute_class_weight
class_weight = compute_class_weight(class_weight='balanced',
classes=np.unique(cls_train),
y=cls_train)
class_weight


#
# Predicting the our data image with the already trained VGG16 model. Using a helper function which can resize the image so it can be the input to VGG16 model



def predict(image_path):
# Load and resize the image using PIL.
img = PIL.Image.open(image_path)
img_resized = img.resize(input_shape, PIL.Image.LANCZOS)

# Plot the image.
plt.imshow(img_resized)
plt.show()

# Convert the PIL image to a numpy-array with the proper shape.
img_array = np.expand_dims(np.array(img_resized), axis=0)

# Use the VGG16 model to make a prediction.
# This outputs an array with 1000 numbers corresponding to
# the classes of the ImageNet-dataset.
print(img_array.shape)
pred = model.predict(img_array)

# Decode the output of the VGG16 model.
print(pred)
print(pred.shape)
pred_decoded = decode_predictions(pred)[0]

# Print the predictions.
for code, name, score in pred_decoded:
print("{0:>6.2%} : {1}".format(score, name))





predict(image_path='/home/priyank/Pictures/people.jpg')





predict(image_path=image_paths_train[0])


# The pre-trained VGG16 model was unable to classify images from the plant disease dataset. The reason is perhaps that the VGG16 model was trained on the so-called ImageNet dataset which may not have contained many images of plant diseases.
#
# The lower layers of a Convolutional Neural Network can recognize many different shapes or features in an image. It is the last few fully-connected layers that combine these featuers into classification of a whole image. So we can try and re-route the output of the last convolutional layer of the VGG16 model to a new fully-connected neural network that we create for doing classification




# summary of VGG16 model.
model.summary()


# We can see that the last convolutional layer is called 'block5_pool' so we use Keras to get a reference to that layer.




transfer_layer = model.get_layer('block5_pool')


#
#
# We refer to this layer as the Transfer Layer because its output will be re-routed to our new fully-connected neural network which will do the classification for the Knifey-Spoony dataset.
#
# The output of the transfer layer has the following shape:
#




transfer_layer.output


# we take the part of the VGG16 model from its input-layer to the output of the transfer-layer. We may call this the convolutional model, because it consists of all the convolutional layers from the VGG16 model.




conv_model = Model(inputs=model.input,
outputs=transfer_layer.output)





# Start a new Keras Sequential model.
new_model = Sequential()

# Add the convolutional part of the VGG16 model from above.
new_model.add(conv_model)

# Flatten the output of the VGG16 model because it is from a
# convolutional layer.
new_model.add(Flatten())

# Add a dense (aka. fully-connected) layer.
# This is for combining features that the VGG16 model has
# recognized in the image.
new_model.add(Dense(1024, activation='relu'))

# Add a dropout-layer which may prevent overfitting and
# improve generalization ability to unseen data e.g. the test-set.
new_model.add(Dropout(0.5))

# Add the final layer for the actual classification.
new_model.add(Dense(num_classes, activation='softmax'))





optimizer = Adam(lr=1e-5)





loss = 'categorical_crossentropy'




metrics = ['categorical_accuracy']


# Helper-function for printing whether a layer in the VGG16 model should be trained.




def print_layer_trainable():
for layer in conv_model.layers:
print("{0}:t{1}".format(layer.trainable, layer.name))


# In[32]:


print_layer_trainable()


#
#
# In Transfer Learning we are initially only interested in reusing the pre-trained VGG16 model as it is, so we will disable training for all its layers.
#




conv_model.trainable = False




for layer in conv_model.layers:
layer.trainable = False





print_layer_trainable()





new_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)




epochs = 15
steps_per_epoch = 100
# Steps per epochs are multiplied with the epoch here 100*20 = 2000 means 2000 random images will be selected.





history = new_model.fit_generator(generator=generator_train,
epochs=epochs,
steps_per_epoch=steps_per_epoch,
class_weight=class_weight,
validation_data=generator_test,
validation_steps=steps_test)





new_model.save("trained_new.h5")





predict(image_path = "/home/priyank/Jupyter_notebook/pp.jpg")


**IT is only predicting the 38 classes it is trained on I want, if the new image is not belongs to these 38 classes then the model should return the VGG16 class or no match found. please help **
Thanks in advance.










share|improve this question



























    0















    I have tried transfer learning using VGG16 but only getting a result for those classes which are trained.I want that the output consists of both the VGG16 classes+ my new trained classes. Is it possible?



    I have attached my whole code.



    `enter code here`import matplotlib.pyplot as plt
    import PIL
    import tensorflow as tf
    import numpy as np
    import os





    import keras
    from keras.models import Sequential, Model
    from keras.layers.core import Dense, Dropout, Flatten, Reshape, Activation
    from keras.layers import Embedding, Input, merge, ELU
    from keras.layers.convolutional import Conv2D, MaxPooling2D
    from keras.optimizers import SGD, Adam, RMSprop
    from keras.regularizers import l2
    from keras.utils.np_utils import to_categorical
    import sklearn.metrics as metrics
    from PIL import Image, ImageDraw
    from keras.applications import VGG16
    from keras.applications.vgg16 import preprocess_input, decode_predictions
    from keras.preprocessing.image import ImageDataGenerator


    # # Helper Function




    def load_images(image_paths):
    # Load the images from disk.
    images = [plt.imread(path) for path in image_paths]

    # Convert to a numpy array and return it.
    return np.asarray(images)





    def path_join(dirname, filenames):
    return [os.path.join(dirname, filename) for filename in filenames]


    # In[5]:


    train_dir = "/home/priyank/Jupyter_notebook/plant_leaves_train_set"
    test_dir = "/home/priyank/Jupyter_notebook/val_data_plant"


    # # Pre-Trained Model: VGG16
    # Downloading the pretrained model of imagenet dataset.




    model = VGG16(include_top=True, weights='imagenet')


    # # Input Pipeline
    # First we need to know the shape of the tensors expected as input by the pre-trained VGG16 model. In this case it is images of shape 224 x 224 x 3.



    input_shape = model.layers[0].output_shape[1:3] # the input shape of the vgg16 model
    input_shape


    # # ImageDataGenerator
    # It will pick the image one-by-one and transform all the data each time the image is loaded in the training set.





    datagen_train = ImageDataGenerator(
    rescale=1./255,
    rotation_range=180,
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.1,
    zoom_range=[0.9, 1.5],
    horizontal_flip=True,
    vertical_flip=True,
    fill_mode='nearest')



    datagen_test = ImageDataGenerator(rescale=1./255)


    #
    # The datagenerator will return the batches of the images. VGG16 model is too large so we can't create the batches too large otherwise we will run out of the RAM and GPU.




    # Taking small batch size
    batch_size = 20


    #
    # We can save the randomly transformed images during training, so as to inspect whether they have been overly distorted, so we have to adjust the parameters for the data-generator above.




    if True:
    save_to_dir = None
    else:
    save_to_dir='augmented_images/'



    generator_train = datagen_train.flow_from_directory(directory=train_dir,
    target_size=input_shape,
    batch_size=batch_size,
    shuffle=True,
    save_to_dir=save_to_dir)





    generator_test = datagen_test.flow_from_directory(directory=test_dir,
    target_size=input_shape,
    batch_size=batch_size,
    shuffle=False)





    steps_test = generator_test.n / batch_size
    steps_test





    image_paths_train = path_join(train_dir, generator_train.filenames)
    image_paths_test = path_join(test_dir, generator_test.filenames)




    cls_train = generator_train.classes
    cls_test = generator_test.classes





    class_names = list(generator_train.class_indices.keys())
    class_names







    num_classes = generator_train.num_classes
    num_classes


    # The dataset we have is imbalanced so the gradients for 9.01192 will remain higher adn the gradients of 0.8080 will reamin lower so that model can learn from higher gradient more than the lower gradient.
    #



    from sklearn.utils.class_weight import compute_class_weight
    class_weight = compute_class_weight(class_weight='balanced',
    classes=np.unique(cls_train),
    y=cls_train)
    class_weight


    #
    # Predicting the our data image with the already trained VGG16 model. Using a helper function which can resize the image so it can be the input to VGG16 model



    def predict(image_path):
    # Load and resize the image using PIL.
    img = PIL.Image.open(image_path)
    img_resized = img.resize(input_shape, PIL.Image.LANCZOS)

    # Plot the image.
    plt.imshow(img_resized)
    plt.show()

    # Convert the PIL image to a numpy-array with the proper shape.
    img_array = np.expand_dims(np.array(img_resized), axis=0)

    # Use the VGG16 model to make a prediction.
    # This outputs an array with 1000 numbers corresponding to
    # the classes of the ImageNet-dataset.
    print(img_array.shape)
    pred = model.predict(img_array)

    # Decode the output of the VGG16 model.
    print(pred)
    print(pred.shape)
    pred_decoded = decode_predictions(pred)[0]

    # Print the predictions.
    for code, name, score in pred_decoded:
    print("{0:>6.2%} : {1}".format(score, name))





    predict(image_path='/home/priyank/Pictures/people.jpg')





    predict(image_path=image_paths_train[0])


    # The pre-trained VGG16 model was unable to classify images from the plant disease dataset. The reason is perhaps that the VGG16 model was trained on the so-called ImageNet dataset which may not have contained many images of plant diseases.
    #
    # The lower layers of a Convolutional Neural Network can recognize many different shapes or features in an image. It is the last few fully-connected layers that combine these featuers into classification of a whole image. So we can try and re-route the output of the last convolutional layer of the VGG16 model to a new fully-connected neural network that we create for doing classification




    # summary of VGG16 model.
    model.summary()


    # We can see that the last convolutional layer is called 'block5_pool' so we use Keras to get a reference to that layer.




    transfer_layer = model.get_layer('block5_pool')


    #
    #
    # We refer to this layer as the Transfer Layer because its output will be re-routed to our new fully-connected neural network which will do the classification for the Knifey-Spoony dataset.
    #
    # The output of the transfer layer has the following shape:
    #




    transfer_layer.output


    # we take the part of the VGG16 model from its input-layer to the output of the transfer-layer. We may call this the convolutional model, because it consists of all the convolutional layers from the VGG16 model.




    conv_model = Model(inputs=model.input,
    outputs=transfer_layer.output)





    # Start a new Keras Sequential model.
    new_model = Sequential()

    # Add the convolutional part of the VGG16 model from above.
    new_model.add(conv_model)

    # Flatten the output of the VGG16 model because it is from a
    # convolutional layer.
    new_model.add(Flatten())

    # Add a dense (aka. fully-connected) layer.
    # This is for combining features that the VGG16 model has
    # recognized in the image.
    new_model.add(Dense(1024, activation='relu'))

    # Add a dropout-layer which may prevent overfitting and
    # improve generalization ability to unseen data e.g. the test-set.
    new_model.add(Dropout(0.5))

    # Add the final layer for the actual classification.
    new_model.add(Dense(num_classes, activation='softmax'))





    optimizer = Adam(lr=1e-5)





    loss = 'categorical_crossentropy'




    metrics = ['categorical_accuracy']


    # Helper-function for printing whether a layer in the VGG16 model should be trained.




    def print_layer_trainable():
    for layer in conv_model.layers:
    print("{0}:t{1}".format(layer.trainable, layer.name))


    # In[32]:


    print_layer_trainable()


    #
    #
    # In Transfer Learning we are initially only interested in reusing the pre-trained VGG16 model as it is, so we will disable training for all its layers.
    #




    conv_model.trainable = False




    for layer in conv_model.layers:
    layer.trainable = False





    print_layer_trainable()





    new_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)




    epochs = 15
    steps_per_epoch = 100
    # Steps per epochs are multiplied with the epoch here 100*20 = 2000 means 2000 random images will be selected.





    history = new_model.fit_generator(generator=generator_train,
    epochs=epochs,
    steps_per_epoch=steps_per_epoch,
    class_weight=class_weight,
    validation_data=generator_test,
    validation_steps=steps_test)





    new_model.save("trained_new.h5")





    predict(image_path = "/home/priyank/Jupyter_notebook/pp.jpg")


    **IT is only predicting the 38 classes it is trained on I want, if the new image is not belongs to these 38 classes then the model should return the VGG16 class or no match found. please help **
    Thanks in advance.










    share|improve this question

























      0












      0








      0








      I have tried transfer learning using VGG16 but only getting a result for those classes which are trained.I want that the output consists of both the VGG16 classes+ my new trained classes. Is it possible?



      I have attached my whole code.



      `enter code here`import matplotlib.pyplot as plt
      import PIL
      import tensorflow as tf
      import numpy as np
      import os





      import keras
      from keras.models import Sequential, Model
      from keras.layers.core import Dense, Dropout, Flatten, Reshape, Activation
      from keras.layers import Embedding, Input, merge, ELU
      from keras.layers.convolutional import Conv2D, MaxPooling2D
      from keras.optimizers import SGD, Adam, RMSprop
      from keras.regularizers import l2
      from keras.utils.np_utils import to_categorical
      import sklearn.metrics as metrics
      from PIL import Image, ImageDraw
      from keras.applications import VGG16
      from keras.applications.vgg16 import preprocess_input, decode_predictions
      from keras.preprocessing.image import ImageDataGenerator


      # # Helper Function




      def load_images(image_paths):
      # Load the images from disk.
      images = [plt.imread(path) for path in image_paths]

      # Convert to a numpy array and return it.
      return np.asarray(images)





      def path_join(dirname, filenames):
      return [os.path.join(dirname, filename) for filename in filenames]


      # In[5]:


      train_dir = "/home/priyank/Jupyter_notebook/plant_leaves_train_set"
      test_dir = "/home/priyank/Jupyter_notebook/val_data_plant"


      # # Pre-Trained Model: VGG16
      # Downloading the pretrained model of imagenet dataset.




      model = VGG16(include_top=True, weights='imagenet')


      # # Input Pipeline
      # First we need to know the shape of the tensors expected as input by the pre-trained VGG16 model. In this case it is images of shape 224 x 224 x 3.



      input_shape = model.layers[0].output_shape[1:3] # the input shape of the vgg16 model
      input_shape


      # # ImageDataGenerator
      # It will pick the image one-by-one and transform all the data each time the image is loaded in the training set.





      datagen_train = ImageDataGenerator(
      rescale=1./255,
      rotation_range=180,
      width_shift_range=0.1,
      height_shift_range=0.1,
      shear_range=0.1,
      zoom_range=[0.9, 1.5],
      horizontal_flip=True,
      vertical_flip=True,
      fill_mode='nearest')



      datagen_test = ImageDataGenerator(rescale=1./255)


      #
      # The datagenerator will return the batches of the images. VGG16 model is too large so we can't create the batches too large otherwise we will run out of the RAM and GPU.




      # Taking small batch size
      batch_size = 20


      #
      # We can save the randomly transformed images during training, so as to inspect whether they have been overly distorted, so we have to adjust the parameters for the data-generator above.




      if True:
      save_to_dir = None
      else:
      save_to_dir='augmented_images/'



      generator_train = datagen_train.flow_from_directory(directory=train_dir,
      target_size=input_shape,
      batch_size=batch_size,
      shuffle=True,
      save_to_dir=save_to_dir)





      generator_test = datagen_test.flow_from_directory(directory=test_dir,
      target_size=input_shape,
      batch_size=batch_size,
      shuffle=False)





      steps_test = generator_test.n / batch_size
      steps_test





      image_paths_train = path_join(train_dir, generator_train.filenames)
      image_paths_test = path_join(test_dir, generator_test.filenames)




      cls_train = generator_train.classes
      cls_test = generator_test.classes





      class_names = list(generator_train.class_indices.keys())
      class_names







      num_classes = generator_train.num_classes
      num_classes


      # The dataset we have is imbalanced so the gradients for 9.01192 will remain higher adn the gradients of 0.8080 will reamin lower so that model can learn from higher gradient more than the lower gradient.
      #



      from sklearn.utils.class_weight import compute_class_weight
      class_weight = compute_class_weight(class_weight='balanced',
      classes=np.unique(cls_train),
      y=cls_train)
      class_weight


      #
      # Predicting the our data image with the already trained VGG16 model. Using a helper function which can resize the image so it can be the input to VGG16 model



      def predict(image_path):
      # Load and resize the image using PIL.
      img = PIL.Image.open(image_path)
      img_resized = img.resize(input_shape, PIL.Image.LANCZOS)

      # Plot the image.
      plt.imshow(img_resized)
      plt.show()

      # Convert the PIL image to a numpy-array with the proper shape.
      img_array = np.expand_dims(np.array(img_resized), axis=0)

      # Use the VGG16 model to make a prediction.
      # This outputs an array with 1000 numbers corresponding to
      # the classes of the ImageNet-dataset.
      print(img_array.shape)
      pred = model.predict(img_array)

      # Decode the output of the VGG16 model.
      print(pred)
      print(pred.shape)
      pred_decoded = decode_predictions(pred)[0]

      # Print the predictions.
      for code, name, score in pred_decoded:
      print("{0:>6.2%} : {1}".format(score, name))





      predict(image_path='/home/priyank/Pictures/people.jpg')





      predict(image_path=image_paths_train[0])


      # The pre-trained VGG16 model was unable to classify images from the plant disease dataset. The reason is perhaps that the VGG16 model was trained on the so-called ImageNet dataset which may not have contained many images of plant diseases.
      #
      # The lower layers of a Convolutional Neural Network can recognize many different shapes or features in an image. It is the last few fully-connected layers that combine these featuers into classification of a whole image. So we can try and re-route the output of the last convolutional layer of the VGG16 model to a new fully-connected neural network that we create for doing classification




      # summary of VGG16 model.
      model.summary()


      # We can see that the last convolutional layer is called 'block5_pool' so we use Keras to get a reference to that layer.




      transfer_layer = model.get_layer('block5_pool')


      #
      #
      # We refer to this layer as the Transfer Layer because its output will be re-routed to our new fully-connected neural network which will do the classification for the Knifey-Spoony dataset.
      #
      # The output of the transfer layer has the following shape:
      #




      transfer_layer.output


      # we take the part of the VGG16 model from its input-layer to the output of the transfer-layer. We may call this the convolutional model, because it consists of all the convolutional layers from the VGG16 model.




      conv_model = Model(inputs=model.input,
      outputs=transfer_layer.output)





      # Start a new Keras Sequential model.
      new_model = Sequential()

      # Add the convolutional part of the VGG16 model from above.
      new_model.add(conv_model)

      # Flatten the output of the VGG16 model because it is from a
      # convolutional layer.
      new_model.add(Flatten())

      # Add a dense (aka. fully-connected) layer.
      # This is for combining features that the VGG16 model has
      # recognized in the image.
      new_model.add(Dense(1024, activation='relu'))

      # Add a dropout-layer which may prevent overfitting and
      # improve generalization ability to unseen data e.g. the test-set.
      new_model.add(Dropout(0.5))

      # Add the final layer for the actual classification.
      new_model.add(Dense(num_classes, activation='softmax'))





      optimizer = Adam(lr=1e-5)





      loss = 'categorical_crossentropy'




      metrics = ['categorical_accuracy']


      # Helper-function for printing whether a layer in the VGG16 model should be trained.




      def print_layer_trainable():
      for layer in conv_model.layers:
      print("{0}:t{1}".format(layer.trainable, layer.name))


      # In[32]:


      print_layer_trainable()


      #
      #
      # In Transfer Learning we are initially only interested in reusing the pre-trained VGG16 model as it is, so we will disable training for all its layers.
      #




      conv_model.trainable = False




      for layer in conv_model.layers:
      layer.trainable = False





      print_layer_trainable()





      new_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)




      epochs = 15
      steps_per_epoch = 100
      # Steps per epochs are multiplied with the epoch here 100*20 = 2000 means 2000 random images will be selected.





      history = new_model.fit_generator(generator=generator_train,
      epochs=epochs,
      steps_per_epoch=steps_per_epoch,
      class_weight=class_weight,
      validation_data=generator_test,
      validation_steps=steps_test)





      new_model.save("trained_new.h5")





      predict(image_path = "/home/priyank/Jupyter_notebook/pp.jpg")


      **IT is only predicting the 38 classes it is trained on I want, if the new image is not belongs to these 38 classes then the model should return the VGG16 class or no match found. please help **
      Thanks in advance.










      share|improve this question














      I have tried transfer learning using VGG16 but only getting a result for those classes which are trained.I want that the output consists of both the VGG16 classes+ my new trained classes. Is it possible?



      I have attached my whole code.



      `enter code here`import matplotlib.pyplot as plt
      import PIL
      import tensorflow as tf
      import numpy as np
      import os





      import keras
      from keras.models import Sequential, Model
      from keras.layers.core import Dense, Dropout, Flatten, Reshape, Activation
      from keras.layers import Embedding, Input, merge, ELU
      from keras.layers.convolutional import Conv2D, MaxPooling2D
      from keras.optimizers import SGD, Adam, RMSprop
      from keras.regularizers import l2
      from keras.utils.np_utils import to_categorical
      import sklearn.metrics as metrics
      from PIL import Image, ImageDraw
      from keras.applications import VGG16
      from keras.applications.vgg16 import preprocess_input, decode_predictions
      from keras.preprocessing.image import ImageDataGenerator


      # # Helper Function




      def load_images(image_paths):
      # Load the images from disk.
      images = [plt.imread(path) for path in image_paths]

      # Convert to a numpy array and return it.
      return np.asarray(images)





      def path_join(dirname, filenames):
      return [os.path.join(dirname, filename) for filename in filenames]


      # In[5]:


      train_dir = "/home/priyank/Jupyter_notebook/plant_leaves_train_set"
      test_dir = "/home/priyank/Jupyter_notebook/val_data_plant"


      # # Pre-Trained Model: VGG16
      # Downloading the pretrained model of imagenet dataset.




      model = VGG16(include_top=True, weights='imagenet')


      # # Input Pipeline
      # First we need to know the shape of the tensors expected as input by the pre-trained VGG16 model. In this case it is images of shape 224 x 224 x 3.



      input_shape = model.layers[0].output_shape[1:3] # the input shape of the vgg16 model
      input_shape


      # # ImageDataGenerator
      # It will pick the image one-by-one and transform all the data each time the image is loaded in the training set.





      datagen_train = ImageDataGenerator(
      rescale=1./255,
      rotation_range=180,
      width_shift_range=0.1,
      height_shift_range=0.1,
      shear_range=0.1,
      zoom_range=[0.9, 1.5],
      horizontal_flip=True,
      vertical_flip=True,
      fill_mode='nearest')



      datagen_test = ImageDataGenerator(rescale=1./255)


      #
      # The datagenerator will return the batches of the images. VGG16 model is too large so we can't create the batches too large otherwise we will run out of the RAM and GPU.




      # Taking small batch size
      batch_size = 20


      #
      # We can save the randomly transformed images during training, so as to inspect whether they have been overly distorted, so we have to adjust the parameters for the data-generator above.




      if True:
      save_to_dir = None
      else:
      save_to_dir='augmented_images/'



      generator_train = datagen_train.flow_from_directory(directory=train_dir,
      target_size=input_shape,
      batch_size=batch_size,
      shuffle=True,
      save_to_dir=save_to_dir)





      generator_test = datagen_test.flow_from_directory(directory=test_dir,
      target_size=input_shape,
      batch_size=batch_size,
      shuffle=False)





      steps_test = generator_test.n / batch_size
      steps_test





      image_paths_train = path_join(train_dir, generator_train.filenames)
      image_paths_test = path_join(test_dir, generator_test.filenames)




      cls_train = generator_train.classes
      cls_test = generator_test.classes





      class_names = list(generator_train.class_indices.keys())
      class_names







      num_classes = generator_train.num_classes
      num_classes


      # The dataset we have is imbalanced so the gradients for 9.01192 will remain higher adn the gradients of 0.8080 will reamin lower so that model can learn from higher gradient more than the lower gradient.
      #



      from sklearn.utils.class_weight import compute_class_weight
      class_weight = compute_class_weight(class_weight='balanced',
      classes=np.unique(cls_train),
      y=cls_train)
      class_weight


      #
      # Predicting the our data image with the already trained VGG16 model. Using a helper function which can resize the image so it can be the input to VGG16 model



      def predict(image_path):
      # Load and resize the image using PIL.
      img = PIL.Image.open(image_path)
      img_resized = img.resize(input_shape, PIL.Image.LANCZOS)

      # Plot the image.
      plt.imshow(img_resized)
      plt.show()

      # Convert the PIL image to a numpy-array with the proper shape.
      img_array = np.expand_dims(np.array(img_resized), axis=0)

      # Use the VGG16 model to make a prediction.
      # This outputs an array with 1000 numbers corresponding to
      # the classes of the ImageNet-dataset.
      print(img_array.shape)
      pred = model.predict(img_array)

      # Decode the output of the VGG16 model.
      print(pred)
      print(pred.shape)
      pred_decoded = decode_predictions(pred)[0]

      # Print the predictions.
      for code, name, score in pred_decoded:
      print("{0:>6.2%} : {1}".format(score, name))





      predict(image_path='/home/priyank/Pictures/people.jpg')





      predict(image_path=image_paths_train[0])


      # The pre-trained VGG16 model was unable to classify images from the plant disease dataset. The reason is perhaps that the VGG16 model was trained on the so-called ImageNet dataset which may not have contained many images of plant diseases.
      #
      # The lower layers of a Convolutional Neural Network can recognize many different shapes or features in an image. It is the last few fully-connected layers that combine these featuers into classification of a whole image. So we can try and re-route the output of the last convolutional layer of the VGG16 model to a new fully-connected neural network that we create for doing classification




      # summary of VGG16 model.
      model.summary()


      # We can see that the last convolutional layer is called 'block5_pool' so we use Keras to get a reference to that layer.




      transfer_layer = model.get_layer('block5_pool')


      #
      #
      # We refer to this layer as the Transfer Layer because its output will be re-routed to our new fully-connected neural network which will do the classification for the Knifey-Spoony dataset.
      #
      # The output of the transfer layer has the following shape:
      #




      transfer_layer.output


      # we take the part of the VGG16 model from its input-layer to the output of the transfer-layer. We may call this the convolutional model, because it consists of all the convolutional layers from the VGG16 model.




      conv_model = Model(inputs=model.input,
      outputs=transfer_layer.output)





      # Start a new Keras Sequential model.
      new_model = Sequential()

      # Add the convolutional part of the VGG16 model from above.
      new_model.add(conv_model)

      # Flatten the output of the VGG16 model because it is from a
      # convolutional layer.
      new_model.add(Flatten())

      # Add a dense (aka. fully-connected) layer.
      # This is for combining features that the VGG16 model has
      # recognized in the image.
      new_model.add(Dense(1024, activation='relu'))

      # Add a dropout-layer which may prevent overfitting and
      # improve generalization ability to unseen data e.g. the test-set.
      new_model.add(Dropout(0.5))

      # Add the final layer for the actual classification.
      new_model.add(Dense(num_classes, activation='softmax'))





      optimizer = Adam(lr=1e-5)





      loss = 'categorical_crossentropy'




      metrics = ['categorical_accuracy']


      # Helper-function for printing whether a layer in the VGG16 model should be trained.




      def print_layer_trainable():
      for layer in conv_model.layers:
      print("{0}:t{1}".format(layer.trainable, layer.name))


      # In[32]:


      print_layer_trainable()


      #
      #
      # In Transfer Learning we are initially only interested in reusing the pre-trained VGG16 model as it is, so we will disable training for all its layers.
      #




      conv_model.trainable = False




      for layer in conv_model.layers:
      layer.trainable = False





      print_layer_trainable()





      new_model.compile(optimizer=optimizer, loss=loss, metrics=metrics)




      epochs = 15
      steps_per_epoch = 100
      # Steps per epochs are multiplied with the epoch here 100*20 = 2000 means 2000 random images will be selected.





      history = new_model.fit_generator(generator=generator_train,
      epochs=epochs,
      steps_per_epoch=steps_per_epoch,
      class_weight=class_weight,
      validation_data=generator_test,
      validation_steps=steps_test)





      new_model.save("trained_new.h5")





      predict(image_path = "/home/priyank/Jupyter_notebook/pp.jpg")


      **IT is only predicting the 38 classes it is trained on I want, if the new image is not belongs to these 38 classes then the model should return the VGG16 class or no match found. please help **
      Thanks in advance.







      keras deep-learning prediction keras-layer transfer-learning






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 '18 at 10:02









      Priyank ThakurPriyank Thakur

      15




      15
























          1 Answer
          1






          active

          oldest

          votes


















          0














          use functional api instead of Sequential,
          offical guide is here: https://keras.io/getting-started/functional-api-guide/



          You can find a multi input & multi output model example there. What you want is very similar but uses only one input instead of multiple.






          share|improve this answer
























          • ok, I will give it a try.

            – Priyank Thakur
            Nov 22 '18 at 7:14











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409535%2fi-want-all-the-output-of-the-pretrained-vgg16-model-as-well-as-the-new-classes-i%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          use functional api instead of Sequential,
          offical guide is here: https://keras.io/getting-started/functional-api-guide/



          You can find a multi input & multi output model example there. What you want is very similar but uses only one input instead of multiple.






          share|improve this answer
























          • ok, I will give it a try.

            – Priyank Thakur
            Nov 22 '18 at 7:14
















          0














          use functional api instead of Sequential,
          offical guide is here: https://keras.io/getting-started/functional-api-guide/



          You can find a multi input & multi output model example there. What you want is very similar but uses only one input instead of multiple.






          share|improve this answer
























          • ok, I will give it a try.

            – Priyank Thakur
            Nov 22 '18 at 7:14














          0












          0








          0







          use functional api instead of Sequential,
          offical guide is here: https://keras.io/getting-started/functional-api-guide/



          You can find a multi input & multi output model example there. What you want is very similar but uses only one input instead of multiple.






          share|improve this answer













          use functional api instead of Sequential,
          offical guide is here: https://keras.io/getting-started/functional-api-guide/



          You can find a multi input & multi output model example there. What you want is very similar but uses only one input instead of multiple.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 '18 at 12:16









          Mete Han KahramanMete Han Kahraman

          41017




          41017













          • ok, I will give it a try.

            – Priyank Thakur
            Nov 22 '18 at 7:14



















          • ok, I will give it a try.

            – Priyank Thakur
            Nov 22 '18 at 7:14

















          ok, I will give it a try.

          – Priyank Thakur
          Nov 22 '18 at 7:14





          ok, I will give it a try.

          – Priyank Thakur
          Nov 22 '18 at 7:14




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409535%2fi-want-all-the-output-of-the-pretrained-vgg16-model-as-well-as-the-new-classes-i%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

          ComboBox Display Member on multiple fields

          Is it possible to collect Nectar points via Trainline?