Exception: Error when checking : expected lambda_input_2 to have shape (None, 3, 244, 244) but got array with shape (4, 3, 224, 224)
This is the error I encountered on first run through. The array being passed in w/ shape (4, 3, 224, 224) matches that of the lesson example, so that seems right to me. The 4 is linked to the batch_size variable, so it’s the number of images being passed in. For some reason, it detects None
images? Looking into it.
I then encountered this thread, with a similar problem but the methods discussed there don’t help me.
One person suggested setting argument dim_order="th"
on the ImageDataGenerator, which did not work. The other suggestion, to sue data_format=":channels_first"
didn’t work as it seems that is a Keras 2.0 feature (checking pip revealed Keras 1.1 for this course). I also tried this with the backend..set_image_dim_ordering('th')
command and have checked the ~/.keras/keras.json file
file to confirm it is running theano and the dim-ordering is set to ‘th’. I tried using the data_format argument as well, but since I’m running the instance provided by fast.ai I am running Keras 1.1 and thus don’t have that feature.
I have also worked through the redux notebook, looking at the solution and following along in the lesson 2 video. However, while that works for me, and lesson1 continues to work for me, I can not get the redux data I setup to work for me.
I’ve also tried swtiching the dogscatsredux path to be both dogscats and redux, using the lesson 1 and solution provided lesson 2 data - neither work with this code.
Here is the code with my beginner explanations tripped out.
%matplotlib inline
path = "data/dogscatsredux/"
#Other imports
from numpy.random import random, permutation
from scipy import misc, ndimage
from scipy.ndimage.interpolation import zoom
from __future__ import division,print_function
import os, json
from glob import glob
import numpy as np
np.set_printoptions(precision=4, linewidth=100)
from matplotlib import pyplot as plt
#Import the utils library from class (need it for plotting at the end)
import utils; reload(utils)
from utils import plots
#Keras imports
import keras
from keras import backend as K
from keras.utils.data_utils import get_file
from keras.models import Sequential, Model
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.layers import Input
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD, RMSprop
from keras.preprocessing import image
FILES_PATH = 'http://files.fast.ai/models/'; CLASS_FILE='imagenet_class_index.json'
# Keras' get_file() is a handy function that downloads files, and caches them for re-use later
fpath = get_file(CLASS_FILE, FILES_PATH+CLASS_FILE, cache_subdir='models')
with open(fpath) as f: class_dict = json.load(f)
# Convert dictionary with string indexes into an array
classes = [class_dict[str(i)][1] for i in range(len(class_dict))]
def ConvBlock(layers, model, filters):
for i in range(layers):
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(filters, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))
def FCBlock(model):
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
vgg_mean = np.array([123.68, 116.779, 103.939]).reshape((3,1,1))
def vgg_preprocess(x):
x = x - vgg_mean #subtract the mean
return x[:, ::-1] # reverse
def VGG_16():
model = Sequential()
model.add(Lambda(vgg_preprocess, input_shape=(3,244,244)))
ConvBlock(2, model, 64)
ConvBlock(2, model, 128)
ConvBlock(3, model, 256)
ConvBlock(3, model, 512)
ConvBlock(3, model, 512)
model.add(Flatten())
FCBlock(model)
FCBlock(model)
model.add(Dense(1000, activation='softmax'))
return model
model = VGG_16()
fpath = get_file('vgg16.h5', FILES_PATH + 'vgg16.h5', cache_subdir='models')
model.load_weights(fpath)
batch_size = 4
def get_batches(dirname, gen=image.ImageDataGenerator(dim_ordering='th'), shuffle=True,
batch_size=batch_size, class_mode='categorical'):
return gen.flow_from_directory(path+dirname, target_size=(224,224),
class_mode=class_mode, shuffle=shuffle, batch_size=batch_size)
batches = get_batches('train', batch_size=batch_size)
val_batches = get_batches('valid', batch_size=batch_size)
imgs, labels = next(batches)
#Shows the 'truth'
plots(imgs, titles=labels)
def pred_batch(imgs):
preds = model.predict(imgs) # <~ Error is thrown here.
idxs = np.argmax(preds, axis=1) #1 axis cause it's just array of category labels
print('Shape: {}'.format(preds.shape)) #shape of the predictions
print('First 5 classes: {}'.format(classes[:5])) #First 5 classes
print('First 5 probabilities: {}'.format(preds[0, :5]))
print('Predictions prob/class: ')
for i in range(len(idxs)):
idx = idxs[i]
print (' {:.4f}/{}'.format(preds[i, idx], classes[idx]))
pred_batch(imgs) # <~ This is where the error is triggered, on the first line of pred_batch on the .predict call