transfer learning of Inception v3 returns the same predictions - tensorflow

I have tried to customize inception to classify. I used the cat, dog, human and other to classify cat, dog, human ( collection of family photos) and other (mostly natural scenes) I have about 2000 dog, 1000 cat, 7000 human and 3000 images split 80:20 among the train and validate. The essence of model is as below. When I train the training accuracy is close to 97% and validation accuracy is ~90%.
import os
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.applications.inception_v3 import InceptionV3
local_weights_file = 'C:/users/sethr/education/Healthcare/imagedetect/modelimageadvance /inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
pre_trained_model = InceptionV3(input_shape = (150, 150,3), include_top = False, weights = `enter code here`local_weights_file)
for layer in pre_trained_model.layers:
layer.trainable = False
# pre_trained_model.summary()
last_layer = pre_trained_model.get_layer('mixed7')
#print('last layer output shape: ', last_layer.output_shape)
last_output = last_layer.output
# Flatten the output layer to 1 dimension
x = tf.keras.layers.Flatten()(last_output)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = tf.keras.layers.Dense(512, activation='relu')(x)
x = tf.keras.layers.Dense(256, activation='relu')(x)
# Add a dropout rate of 0.2
x = tf.keras.layers.Dropout(0.2)(x)
# Add a final sigmoid layer for classification
x = tf.keras.layers.Dense(4, activation='softmax')(x)
model = Model(pre_trained_model.input, x)
model.compile(optimizer = RMSprop(lr=0.0001), loss = 'categorical_crossentropy', metrics = ['accuracy'])
history = model.fit(train_generator,validation_data = validation_generator,steps_per_epoch = 20,epochs = 20,validation_steps = 25,verbose = 2)
model.save("dcho.rp5")
___________________
import numpy as np
import cv2
import glob
from keras.preprocessing import image
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
labels= ["cat","dog","human","other"]
path='C:/Users/sethr/education/Healthcare/imagedetect/images/*.jpg'
for fim in glob.glob(path):
# predicting images
img=image.load_img(fim, target_size=(150, 150))
x=image.img_to_array(img)
x=np.expand_dims(x, axis=0)
images = np.vstack([x])
plt.figure()
plt.imshow(img)
plt.show()
classes = model.predict(images,batch_size=10)
________________________________________________________
_______________________________________________________
# All images will be rescaled by 1./255.
train_datagen = ImageDataGenerator( rescale = 1.0/255. )
test_datagen = ImageDataGenerator( rescale = 1.0/255. )
# --------------------
# Flow training images in batches of 20 using train_datagen generator
# --------------------
train_generator = train_datagen.flow_from_directory(train_dir,
batch_size=20,
shuffle='True',
class_mode='categorical',
target_size=(150, 150))
# --------------------
# Flow validation images in batches of 20 using test_datagen generator
# --------------------
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size = (150, 150),
batch_size=20,
class_mode='categorical',
shuffle='True',
)
_______________________________________________________________
The problem is it is returning always human as prediction.. I played around with Adam, Adjusted learning rate but still the prediction remains the same. Any insight.

The issue is you have not done the rescaling part when you predicting images.
You are doing rescaling only for training and validation
train_datagen = ImageDataGenerator( rescale = 1.0/255. )
test_datagen = ImageDataGenerator( rescale = 1.0/255. )
# Note - this test_datagen used for validation
In order to get correct predictions, we should do the same preprocessing steps as we did for training and validation. So you need to rescale the image.
You can rescale the image by using this code
x = x* 1.0/255.0
So the correct predicting image part is shown below.
for fim in glob.glob(path):
# predicting images
img=image.load_img(fim, target_size=(150, 150))
x=image.img_to_array(img)
x=np.expand_dims(x, axis=0)
# Add this line
x = x* 1.0/255.0
images = np.vstack([x])
plt.figure()
plt.imshow(img)
plt.show()
classes = model.predict(images,batch_size=10)

Related

Why is the Accuracy Different in my PC From Kaggle When Using the Same Code

I am writing a watermark detection algorithm, and I've tried a code from Kaggle which fine-tunes a ResNet, but when I run the same code in Jupyter notebook, I get 50% accuracy when the sample code in Kaggle has around 97% accuracy. I don't have a GPU installed on my PC, and I changed the batch size to 32. Do you know why I get 40% lower accuracy?
My Code:
import tensorflow as tf
import numpy as numpy
import os
from pathlib import Path
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import RMSprop
from PIL import Image
basedir = "/home/mahsa/Kaggle/archive/wm-nowm"
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
traindir = os.path.join(basedir,'train') # root for training
validdir = os.path.join(basedir,'valid') # root for testing
traingenerator = ImageDataGenerator(rescale=1./255)
validgenerator = ImageDataGenerator(rescale=1./255)
train_data = traingenerator.flow_from_directory(traindir,target_size=(150,150),batch_size=100,class_mode="binary")
valid_data = validgenerator.flow_from_directory(validdir,target_size=(150,150),batch_size=100,class_mode="binary")
existing = tf.keras.applications.InceptionResNetV2 (input_shape=(150, 150, 3),include_top=False, pooling='max', weights='imagenet')
#for layer in existing.layers:
# layer.trainable = False
#existing.summary()
last = existing.get_layer("mixed_7a")
last_output = last.output
# Flatten the output layer to 1 dimension
x = tf.keras.layers.Flatten()(last_output)
x = tf.keras.layers.Dropout(0.25)(x)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = tf.keras.layers.Dense(128, activation='relu')(x)
x = tf.keras.layers.Dense(64, activation='relu')(x)
# Add a final sigmoid layer for classification
x = tf.keras.layers.Dense (1, activation='sigmoid')(x)
model = tf.keras.Model( existing.input, x)
model.compile(optimizer=RMSprop(lr=0.001),
loss='binary_crossentropy',
metrics = ['accuracy'])
history = model.fit(train_data,
validation_data=valid_data,
steps_per_epoch=150,
epochs=60,
validation_steps=50,
verbose=2)
I found out that the problem was batch_size, I increased the batch_size to 100, it took about 1.5 day to train the model but I got 99% accuracy.

How to feed grayscale images into a pretrained neural network models?

Noob here . I have been working with grayscale images for mitosis classification Here's a sample image I'm working with . I have employed VGGnet for achieving this. I've some doubts about how my grayscale image should be fed into the neural network. I've read the documentation of VGGnet about being trained on colored images on Imagenet.
I read the images using cv2.imread() and by squeezing into an array. I found its shape to be (227,227,3). Shouldn't it be (227,227,1) when I'm handling with grayscale images ? Model accuracy was also found to be only 50% . I'm wondering if it's something wrong with the dataset itself or VGGnet isn't suitable for this purpose. Or should I use some other method to read these images to get grayscale images?
I have tried the solutions listed in similar questions . Am I reading the images in the right way?
I'm sharing my code here.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Display Image data
from PIL import Image
import cv2
from google.colab import drive
drive.mount('/content/drive')
mitotic_image = Image.open('/content/drive/MyDrive/Medical/actualmito1/trainactmito01.jpg')
nonmitotic_image=Image.open('/content/drive/MyDrive/Medical/actualnonmito1/trainactnonmito01.jpg')
# subplotting image data
fig = plt.figure(figsize=(15,9))
ax1 = fig.add_subplot(1, 2, 1)
img_plot = plt.imshow(nonmitotic_image, cmap = plt.cm.bone)
ax1.set_title("Non-Mitotic Image")
ax2 = fig.add_subplot(1, 2, 2)
img_plot = plt.imshow(mitotic_image, cmap = plt.cm.bone)
ax2.set_title("Mitotic Image")
plt.show()
import os
yes = os.listdir("/content/drive/MyDrive/Medical/actualmito1")
no = os.listdir("/content/drive/MyDrive/Medical/actualnonmito1")
data = np.concatenate([yes, no])
target_yes = np.full(len(yes), 1)
target_no = np.full(len(no), 0)
# Image Target
data_target = np.concatenate([target_yes, target_no])
# Generate Image Data
img = cv2.imread("/content/drive/MyDrive/Medical/actualmito1/trainactmito01.jpg")
mitosis = cv2.resize(img,(32,32))
plt.imshow(mitosis)
X_data = []
yes = os.listdir("/content/drive/MyDrive/Medical/actualmito1")
for file in yes:
img = cv2.imread("/content/drive/MyDrive/Medical/actualmito1/" + file)
# resizing image data to 32x32
img = cv2.resize(img, (224,224))
X_data.append(img) # This will store list of all image data in an array
no = os.listdir("/content/drive/MyDrive/Medical/actualnonmito1")
for file in no:
img = cv2.imread("/content/drive/MyDrive/Medical/actualnonmito1/" + file)
# resizing image data to 32x32
img = cv2.resize(img, (224,224))
X_data.append(img) # This will store list of all image data in an array
X = np.squeeze(X_data)
X.shape
# Image Pixel Normalization
X = X.astype('float32')
X /= 255
X.shape
# Train & Test Data
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, data_target, test_size = 0.1,
random_state = 3)
x_train2, x_val, y_train2, y_val = train_test_split(x_train, y_train, test_size = 0.15,
random_state = 3)
# VGG16 - Transfer Learning
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Conv2D, GlobalAveragePooling2D, Flatten, ZeroPadding2D,
Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import VGG16
def build_model():
#use Imagenet = pre-trained models weights called knowledge transfer
# image_shape = 32x32x3
vgg16_model = VGG16(weights = 'imagenet', include_top = False, input_shape=(224,224,3))
# Input Layer
model = Sequential()
# paadding = 'same' = ZeroPadding
model.add(Conv2D(filters=3, kernel_size=(3,3), padding='same', input_shape = (224,224,3)))
# add transfer learning model
model.add(vgg16_model)
# Average Pooling Layer
model.add(GlobalAveragePooling2D())
model.add(BatchNormalization())
model.add(Dropout(0.5))
# Fully Connected Layer
model.add(Dense(units = 512, activation='relu'))
model.add(Dropout(0.5))
# Output Layer
model.add(Dense(units = 1, activation='sigmoid'))
model.compile(optimizer = 'Adam', loss = 'binary_crossentropy', metrics = ['Accuracy'])
return model
model = build_model()
model.summary()
from tensorflow.keras import callbacks
filepath = "/content/drive/MyDrive/BestModelMRI3.hdf5"
checkpoint = callbacks.ModelCheckpoint(filepath, monitor = 'val_loss', save_best_only = True,
mode = 'min',verbose = 1)
import datetime
import keras
import os
logdir = os.path.join("/content/drive/MyDrive/MRI_logs",
datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
tensorboard_callback = keras.callbacks.TensorBoard(logdir)
history = model.fit(x_train2, y_train2, epochs = 200, batch_size = 32, shuffle = True,
validation_data = (x_val, y_val), callbacks = [checkpoint, tensorboard_callback],verbose= 1)
model.load_weights("/content/drive/MyDrive/BestModelMRI3.hdf5")
model.evaluate(x_test, y_test)
predictions = model.predict(x_test)
yhat = np.round(predictions)
from sklearn.metrics import confusion_matrix, classification_report
confusion_matrix(y_test, yhat)
sns.heatmap(confusion_matrix(y_test, yhat), annot = True, cmap = 'RdPu')
print(classification_report(y_test, yhat))
VGG model was trained on RGB images. CV2 reads in images as BGR. so add code
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
to convert BGR to RGB. Also VGG requires the pixels to be in the range -1 to +1 so scale with
X=X/127.5 -1

Keras use trained InceptionV3 model + CIFAR10 got error about Batch Size

I am new to Machine Learning and Keras etc.
Trying to use trained model to increase accuracy, in my case I followed Jerry Kurata on Pluralsight to use InceptionV3 and only modify the last layer to train for recognizing birds.
The dataset I have is from Keras built-in CIFAR10 and here is the official tutorial
Here is the error message:
F tensorflow/stream_executor/cuda/cuda_dnn.cc:516] Check failed:
cudnnSetTensorNdDescriptor(handle_.get(), elem_type, nd, dims.data(),
strides.data()) == CUDNN_STATUS_SUCCESS (3 vs. 0)batch_descriptor:
{count: 32 feature_map_count: 288 spatial: %d 0%d 0 value_min:
0.000000 value_max: 0.000000 layout: BatchDepthYX} Aborted (core dumped)
I saw 1 possible cause from here
The image samples in CIFAR10 (32*32) is too small which cause this
issue
But I cannot figure out how to fix it.
Here is my code:
import matplotlib.pyplot as plt
import keras
from keras import backend as K
with K.tf.device("/device:GPU:0"):
config = K.tf.ConfigProto(intra_op_parallelism_threads=4,
inter_op_parallelism_threads=4, allow_soft_placement=True,
device_count = {'CPU' : 1, 'GPU' : 1})
session = K.tf.Session(config=config)
K.set_session(session)
from keras.callbacks import EarlyStopping
from keras.applications.inception_v3 import InceptionV3, preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras.datasets import cifar10
# "/device:GPU:0"
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
def create_generator():
return ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
zca_epsilon=1e-06, # epsilon for ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
# randomly shift images horizontally (fraction of total width)
width_shift_range=0.1,
# randomly shift images vertically (fraction of total height)
height_shift_range=0.1,
shear_range=0., # set range for random shear
zoom_range=0., # set range for random zoom
channel_shift_range=0., # set range for random channel shifts
# set mode for filling points outside the input boundaries
fill_mode='nearest',
cval=0., # value used for fill_mode = "constant"
horizontal_flip=True, # randomly flip images
vertical_flip=False, # randomly flip images
# set rescaling factor (applied before any other transformation)
rescale=None,
# set function that will be applied on each input
preprocessing_function=None,
# image data format, either "channels_first" or "channels_last"
data_format=None,
# fraction of images reserved for validation (strictly between 0 and 1)
validation_split=0.0)
Training_Epochs = 1
Batch_Size = 32
Number_FC_Neurons = 1024
Num_Classes = 10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, Num_Classes)
y_test = keras.utils.to_categorical(y_test, Num_Classes)
# load cifar10 data here https://keras.io/datasets/
datagen = create_generator()
datagen.fit(x_train)
Inceptionv3_model = InceptionV3(weights='imagenet', include_top=False)
print('Inception v3 model without last FC loaded')
x = Inceptionv3_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(Number_FC_Neurons, activation='relu')(x)
predictions = Dense(Num_Classes, activation='softmax')(x)
model = Model(inputs=Inceptionv3_model.input, outputs=predictions)
# print(model.summary())
print('\nFine tuning existing model')
Layers_To_Freeze = 172
for layer in model.layers[:Layers_To_Freeze]:
layer.trainable = False
for layer in model.layers[Layers_To_Freeze:]:
layer.trainable = True
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy'])
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
cbk_early_stopping = EarlyStopping(monitor='val_acc', mode='max')
print(len(x_train))
history_transfer_learning = model.fit_generator(
datagen.flow(x_train, y_train, batch_size=Batch_Size),
epochs=Training_Epochs,
validation_data=(x_test, y_test),
workers=4,
steps_per_epoch=len(x_train)//Batch_Size,
callbacks=[cbk_early_stopping]
)
model.save('incepv3_transfer_cifar10.h5', overwrite=True, include_optimizer=True)
# Score trained model.
scores = model.evaluate(x_test, 12, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])
Your error as you said is the input size difference. The pre trained Imagenet model takes a bigger size of image than the Cifar-10 (32, 32).
You need to specify the input_shape of the model before hand like this.
Inceptionv3_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(32, 32, 3))
For more explanation you can check this tutorial.

Getting very low accuracy while fine tuning Inception v3 pre trained model

I am using Inception v3 model for identification of disease present in a Chest XRay image. For training I am using NIH Chest XRay Dataset. I have 14 different classes of diseases present in the dataset and also I have reduced the original image resolution to reduce the dataset size on disk. As I don't have a GPU I am using Google Colab to train my model and I am taking only 300 images per classs for all minority classes and 400 images for 'No Finding' class (Majority class). Please point out the bugs in my code if any and please suggest me some other approaches so that I can achieve better accuracy.
import numpy as np
import tensorflow as tf
import random as rn
import os
os.environ['PYTHONHASHSEED'] = '0'
np.random.seed(42)
rn.seed(12345)
session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
from keras import backend as K
tf.set_random_seed(1234)
sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras.preprocessing.image import ImageDataGenerator
# from keras import backend as K
from keras.callbacks import ModelCheckpoint
from keras.callbacks import TensorBoard
from keras.layers.core import Flatten, Dense, Dropout, Reshape, Lambda
from keras.layers.normalization import BatchNormalization
from sklearn.preprocessing import LabelEncoder
from keras.utils.np_utils import to_categorical
from sklearn.metrics import log_loss
from sklearn.model_selection import train_test_split
# import os.path
'''F1 score calculation class'''
# import numpy as np
# from keras.callbacks import Callback
# from sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score
# class Metrics(Callback):
# def on_train_begin(self, logs={}):
# self.val_f1s = []
# self.val_recalls = []
# self.val_precisions = []
# def on_epoch_end(self, epoch, logs={}):
# val_predict = (np.asarray(self.model.predict(self.model.validation_data[0]))).round()
# val_targ = self.model.validation_data[1]
# _val_f1 = f1_score(val_targ, val_predict)
# _val_recall = recall_score(val_targ, val_predict)
# _val_precision = precision_score(val_targ, val_predict)
# self.val_f1s.append(_val_f1)
# self.val_recalls.append(_val_recall)
# self.val_precisions.append(_val_precision)
# print(" — val_f1: %f — val_precision: %f — val_recall %f" % (_val_f1, _val_precision, _val_recall))
# return
# metrics = Metrics()
# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)
# dimensions of our images.
#Inception input size
img_width, img_height = 299, 299
top_layers_checkpoint_path = 'cp.top.best.hdf5'
fine_tuned_checkpoint_path = 'cp.fine_tuned.best.hdf5'
new_extended_inception_weights = 'final_weights.hdf5'
train_data_dir = 'drive/My Drive/Colab Notebooks/Sample-300-XRay-Dataset/train'
validation_data_dir = 'drive/My Drive/Colab Notebooks/Sample-300-XRay-Dataset/test'
nb_train_samples = 3528
nb_validation_samples = 896
top_epochs = 50
fit_epochs = 50
batch_size = 24
# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
x = BatchNormalization()(x)
#x =Dropout(0.2)(x)
x = Dense(512, activation='relu')(x)
x = BatchNormalization()(x)
#x= Dropout(0.3)(x)
# and a logistic layer -- we have 15 classes
predictions = Dense(15, activation='softmax')(x)
# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)
if os.path.exists(top_layers_checkpoint_path):
model.load_weights(top_layers_checkpoint_path)
print ("Checkpoint '" + top_layers_checkpoint_path + "' loaded.")
# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False
# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
#Save the model after every epoch.
mc_top = ModelCheckpoint(top_layers_checkpoint_path, monitor='val_acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
#Save the TensorBoard logs.
tb = TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=True)
# train the model on the new data for a few epochs
#model.fit_generator(...)
model.fit_generator(
train_generator,
samples_per_epoch=nb_train_samples // batch_size,
epochs=top_epochs,
validation_data=validation_generator,
nb_val_samples=nb_validation_samples // batch_size,
callbacks=[mc_top, tb])
# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.
# let's visualize layer names and layer indices to see how many layers
# we should freeze:
# for i, layer in enumerate(base_model.layers):
# print(i, layer.name)
#Save the model after every epoch.
mc_fit = ModelCheckpoint(fine_tuned_checkpoint_path, monitor='val_acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
if os.path.exists(fine_tuned_checkpoint_path):
model.load_weights(fine_tuned_checkpoint_path)
print ("Checkpoint '" + fine_tuned_checkpoint_path + "' loaded.")
# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 172 layers and unfreeze the rest:
for layer in model.layers[:172]:
layer.trainable = False
for layer in model.layers[172:]:
layer.trainable = True
# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
from keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy'])
# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
#model.fit_generator(...)
model.fit_generator(
train_generator,
samples_per_epoch=nb_train_samples // batch_size,
epochs=fit_epochs,
validation_data=validation_generator,
nb_val_samples=nb_validation_samples // batch_size,
callbacks=[mc_fit, tb])
model.save_weights(new_extended_inception_weights)

Keras model predict fails

im a bit of a noob in ML. ive been trying to get a model retrained on the flowers dataset to work on keras-js withous success. whenever i try to run predict on the model i get "Error: predict() must take an object where the keys are the named inputs of the model: input_1." pls help here is my code
test.py
import sys
import json
import numpy as np
from collections import defaultdict
# It's very important to put this import before keras,
# as explained here: Loading tensorflow before scipy.misc seems to cause imread to fail #1541
# https://github.com/tensorflow/tensorflow/issues/1541
import scipy.misc
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras import backend as K
from keras.utils import np_utils
import dataset
import net
np.random.seed(1337)
spe = 500
n = 299
batch_size = 128
nb_epoch = 1
nb_phase_two_epoch = 1
data_directory, test_directory, model_file_prefix = sys.argv[1:]
print "loading dataset"
X, y, tags = dataset.dataset(data_directory, n)
nb_classes = len(tags)
sample_count = len(y)
train_size = sample_count * 4 // 5
X_train = X[:train_size]
y_train = y[:train_size]
Y_train = np_utils.to_categorical(y_train, nb_classes)
X_test = X[train_size:]
y_test = y[train_size:]
Y_test = np_utils.to_categorical(y_test, nb_classes)
datagen = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=0,
width_shift_range=0.125,
height_shift_range=0.125,
horizontal_flip=True,
vertical_flip=False,
fill_mode='nearest')
#datagen.fit(X_train)
train_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
data_directory,
target_size=(299,299),
batch_size=16,
class_mode='categorical'
)
validation_generator = train_datagen.flow_from_directory(
data_directory,
target_size=(299,299),
batch_size=16,
class_mode='categorical'
)
def evaluate(model, vis_filename=None):
Y_pred = model.predict(X_test, batch_size=batch_size)
y_pred = np.argmax(Y_pred, axis=1)
accuracy = float(np.sum(y_test==y_pred)) / len(y_test)
print "accuracy:", accuracy
confusion = np.zeros((nb_classes, nb_classes), dtype=np.int32)
for (predicted_index, actual_index, image) in zip(y_pred, y_test, X_test):
confusion[predicted_index, actual_index] += 1
print "rows are predicted classes, columns are actual classes"
for predicted_index, predicted_tag in enumerate(tags):
print predicted_tag[:7],
for actual_index, actual_tag in enumerate(tags):
print "\t%d" % confusion[predicted_index, actual_index],
print
if vis_filename is not None:
bucket_size = 10
image_size = n // 4 # right now that's 56
vis_image_size = nb_classes * image_size * bucket_size
vis_image = 255 * np.ones((vis_image_size, vis_image_size, 3), dtype='uint8')
example_counts = defaultdict(int)
for (predicted_tag, actual_tag, normalized_image) in zip(y_pred, y_test, X_test):
example_count = example_counts[(predicted_tag, actual_tag)]
if example_count >= bucket_size**2:
continue
image = dataset.reverse_preprocess_input(normalized_image)
image = image.transpose((1, 2, 0))
image = scipy.misc.imresize(image, (image_size, image_size)).astype(np.uint8)
tilepos_x = bucket_size * predicted_tag
tilepos_y = bucket_size * actual_tag
tilepos_x += example_count % bucket_size
tilepos_y += example_count // bucket_size
pos_x, pos_y = tilepos_x * image_size, tilepos_y * image_size
vis_image[pos_y:pos_y+image_size, pos_x:pos_x+image_size, :] = image
example_counts[(predicted_tag, actual_tag)] += 1
vis_image[::image_size * bucket_size, :] = 0
vis_image[:, ::image_size * bucket_size] = 0
scipy.misc.imsave(vis_filename, vis_image)
print "loading original inception model"
model = net.build_model(nb_classes)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=["accuracy"])
# train the model on the new data for a few epochs
print "training the newly added dense layers"
print "samples per eph ",spe#X_train.shape[0]
model.fit_generator(train_generator,
samples_per_epoch=spe,
nb_epoch=nb_epoch,
validation_data=validation_generator,
nb_val_samples=spe,
)
net.save(model, tags, model_file_prefix)
# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.
# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 172 layers and unfreeze the rest:
for layer in model.layers[:172]:
layer.trainable = False
for layer in model.layers[172:]:
layer.trainable = True
# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=["accuracy"])
# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
print "fine-tuning top 2 inception blocks alongside the top dense layers"
for i in range(1,11):
print "mega-epoch %d/10" % i
model.fit_generator(train_generator,
samples_per_epoch=spe,
nb_epoch=nb_phase_two_epoch,
validation_data=validation_generator,
nb_val_samples=spe,
)
#evaluate(model, str(i).zfill(3)+".png")
# evaluate(model, "000.jpg")
net.save(model, tags, model_file_prefix)
when run with keras-js i get the error
Error: predict() must take an object where the keys are the named inputs of the model: input_1.
pls help
Wasn't easy to read your code - indentation was off and I don't really know what's in dataset and the other imports.
That said, the problem is probably the format of X_test. During training, you use output from ImageDatagenerator which rescales the images to (299,299) together with the other manipulations. During evaluation, you use the raw data in X_test directly.
Hope this helps /p