Not able to use the model.fit() in Keras - tensorflow

Please help me run the code. This doesn't work. I have been trying hard to solve this for days. The model_final.fit() also doesn't work. Why is this showing the same error for the method. This is almost the entire code.
EDIT: The train_generator and validation_generator added.
img_width, img_height = 400, 400
train_data_dir = "data/train"
validation_data_dir = "data/validation"
nb_train_samples = 4125
nb_validation_samples = 466
batch_size = 16,
epochs = 5
output_num_classes = 2
K.set_image_data_format('channels_last')
model = applications.VGG19(weights="imagenet", include_top=False, input_shape=(img_width, img_height, 3))
model.summary()
x = model.output
x = Flatten()(x)
x = Dense(1024, activation="relu")(x)
x = Dropout(0.5)(x)
x = Dense(1024, activation="relu")(x)
predictions = Dense(output_num_classes, activation="softmax")(x)
model_final = Model(inputs=model.input, outputs=predictions)
model_final.compile(loss="categorical_crossentropy",
optimizer=optimizers.SGD(learning_rate=0.0001, momentum=0.9),
metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1./255,
zoom_range=0.3,
width_shift_range=0.3,
height_shift_range=0.3,
rotation_range=30,
horizontal_flip=True,
fill_mode='nearest')
train_generator = train_datagen.flow_from_directory(train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_datagen = ImageDataGenerator(rescale=1./255,
zoom_range=0.3,
width_shift_range=0.3,
height_shift_range=0.3,
rotation_range=30,
horizontal_flip=True,
fill_mode='nearest')
validation_generator = validation_datagen.flow_from_directory(validation_data_dir,
target_size=(img_height, img_width),
batch_size = batch_size,
class_mode='categorical')
The code above is before fitting.
model_final.fit_generator(train_generator,
steps_per_epoch=nb_train_samples,
epochs = epochs,
validation_data = validation_generator,
validation_steps = nb_validation_samples)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
warnings.warn('`Model.fit_generator` is deprecated and '
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-87-b195f52ce8fb> in <module>()
3 epochs = epochs,
4 validation_data = validation_generator,
----> 5 validation_steps = nb_validation_samples)
/usr/local/lib/python3.7/dist-packages/keras_preprocessing/image/iterator.py in __len__(self)
66
67 def __len__(self):
---> 68 return (self.n + self.batch_size - 1) // self.batch_size # round up
69
70 def on_epoch_end(self):
TypeError: unsupported operand type(s) for +: 'int' and 'tuple' ```

I was able to replicate your issue with sample code as shown below
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from google.colab import drive
drive.mount('/content/drive')
train_dir = '/content/drive/My Drive/Dogs_Vs_Cats/train'
test_dir = '/content/drive/My Drive/Dogs_Vs_Cats/test'
img_width, img_height = 224, 224
input_shape = (img_width, img_height, 3)
epochs = 8
batch_size = 32,
train_datagen = ImageDataGenerator(
rescale = 1. /255,
horizontal_flip = True)
test_datagen = ImageDataGenerator(
rescale = 1. /255)
train_data = train_datagen.flow_from_directory(
train_dir,
target_size = (img_width, img_height),
batch_size = batch_size,
class_mode = 'binary')
test_data = test_datagen.flow_from_directory(
test_dir,
target_size = (img_width, img_height),
class_mode = 'binary')
Conv_Base = ResNet50(include_top = False, weights = 'imagenet', input_shape = input_shape)
model = Sequential()
model.add(Conv_Base)
model.add(Flatten())
model.add(Dense(units = 256, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(units = 1, activation = 'sigmoid'))
model.summary()
model.compile(loss = 'binary_crossentropy',
optimizer = 'Adam',
metrics = [tf.keras.metrics.Precision(), tf.keras.metrics.Recall()])
model.fit(
train_data,
steps_per_epoch = 10,
epochs = 2,
validation_data = test_data,
verbose = 1,
validation_steps = 32)
Output:
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Found 2000 images belonging to 2 classes.
Found 1018 images belonging to 2 classes.
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 7, 7, 2048) 23587712
_________________________________________________________________
flatten (Flatten) (None, 100352) 0
_________________________________________________________________
dense (Dense) (None, 256) 25690368
_________________________________________________________________
dropout (Dropout) (None, 256) 0
_________________________________________________________________
dense_1 (Dense) (None, 1) 257
=================================================================
Total params: 49,278,337
Trainable params: 49,225,217
Non-trainable params: 53,120
_________________________________________________________________
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-5a5644117355> in <module>()
60 validation_data = test_data,
61 verbose = 1,
---> 62 validation_steps = 32)
3 frames
/usr/local/lib/python3.7/dist-packages/keras_preprocessing/image/iterator.py in __len__(self)
66
67 def __len__(self):
---> 68 return (self.n + self.batch_size - 1) // self.batch_size # round up
69
70 def on_epoch_end(self):
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
Solution to fix:
As rightly suggested by #Dr. Snoopy, this issue was due to comma right after batch_size definition. It converts the integer into a tuple and which is not supported.
Changing batch_size = 32, to batch_size = 32 has resolved the issue.
Working code as shown below
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from google.colab import drive
drive.mount('/content/drive')
train_dir = '/content/drive/My Drive/Dogs_Vs_Cats/train'
test_dir = '/content/drive/My Drive/Dogs_Vs_Cats/test'
img_width, img_height = 224, 224
input_shape = (img_width, img_height, 3)
epochs = 8
batch_size = 32 # removed comma
train_datagen = ImageDataGenerator(
rescale = 1. /255,
horizontal_flip = True)
test_datagen = ImageDataGenerator(
rescale = 1. /255)
train_data = train_datagen.flow_from_directory(
train_dir,
target_size = (img_width, img_height),
batch_size = batch_size,
class_mode = 'binary')
test_data = test_datagen.flow_from_directory(
test_dir,
target_size = (img_width, img_height),
class_mode = 'binary')
Conv_Base = ResNet50(include_top = False, weights = 'imagenet', input_shape = input_shape)
model = Sequential()
model.add(Conv_Base)
model.add(Flatten())
model.add(Dense(units = 256, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(units = 1, activation = 'sigmoid'))
model.summary()
model.compile(loss = 'binary_crossentropy',
optimizer = 'Adam',
metrics = [tf.keras.metrics.Precision(), tf.keras.metrics.Recall()])
model.fit(
train_data,
steps_per_epoch = 10,
epochs = 2,
validation_data = test_data,
verbose = 1,
validation_steps = 32)
Output:
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Found 2000 images belonging to 2 classes.
Found 1018 images belonging to 2 classes.
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 7, 7, 2048) 23587712
_________________________________________________________________
flatten_1 (Flatten) (None, 100352) 0
_________________________________________________________________
dense_2 (Dense) (None, 256) 25690368
_________________________________________________________________
dropout_1 (Dropout) (None, 256) 0
_________________________________________________________________
dense_3 (Dense) (None, 1) 257
=================================================================
Total params: 49,278,337
Trainable params: 49,225,217
Non-trainable params: 53,120
_________________________________________________________________
Epoch 1/2
10/10 [==============================] - 107s 10s/step - loss: 9.5302 - precision_1: 0.6096 - recall_1: 0.6485 - val_loss: 14405.0479 - val_precision_1: 0.0000e+00 - val_recall_1: 0.0000e+00
Epoch 2/2
10/10 [==============================] - 68s 7s/step - loss: 2.2295 - precision_1: 0.8191 - recall_1: 0.8799 - val_loss: 3977.1418 - val_precision_1: 0.4912 - val_recall_1: 1.0000
<tensorflow.python.keras.callbacks.History at 0x7fbba005cc50>

Related

Shape mismatch with vgg16 keras: expected ndim=4, found ndim=2, shape received [None, None]

In trying to learn keras and deep learning, I want to create an image matting algorithm that uses an architecture similar to a modified autoencoder, where it takes two image inputs (a source image and a user-generated trimap) and produces one image output (the alpha values of the image foreground). The encoder part (of both inputs) is simple feature extraction using pre-trained VGG16. I want to train the decoder using the low-res alphamatting.com dataset.
Running the attached code produces an error:
ValueError: Input 0 of layer block1_conv1 is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: [None, None]
I'm having trouble understanding this error. I verified that my twin_gen closure is producing image batches of shape (22, 256,256,3) for both inputs, so I would guess that the issue is that I have somehow created the model wrong, but I don't see where the error is. Can anyone help shed some light on how I could be seeing this error?
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2DTranspose, Concatenate, BatchNormalization, Input
from tensorflow.keras.preprocessing.image import ImageDataGenerator
def DeConvBlock(input, num_output):
x = Conv2DTranspose(num_output, kernel_size=3, strides=2, activation='relu', padding='same')(input)
x = BatchNormalization()(x)
x = Conv2DTranspose(num_output, kernel_size=3, strides=1, activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2DTranspose(num_output, kernel_size=3, strides=1, activation='relu', padding='same')(x)
x = BatchNormalization()(x)
return x
img_input = Input((256, 256, 3))
img_vgg16 = VGG16(include_top=False, weights='imagenet')
img_vgg16._name = 'img_vgg16'
img_vgg16.trainable = False
tm_input = Input((256, 256, 3))
tm_vgg16 = VGG16(include_top=False, weights='imagenet')
tm_vgg16._name = 'tm_vgg16'
tm_vgg16.trainable = False
img_vgg16 = img_vgg16(img_input)
tm_vgg16 = tm_vgg16(tm_input)
x = Concatenate()([img_vgg16, tm_vgg16])
x = DeConvBlock(x, 512)
x = DeConvBlock(x, 256)
x = DeConvBlock(x, 128)
x = DeConvBlock(x, 64)
x = DeConvBlock(x, 32)
x = Conv2DTranspose(1, kernel_size=3, strides=1, activation='sigmoid', padding='same')(x)
m = Model(inputs=[img_input, tm_input], outputs=x)
m.summary()
m.compile(optimizer='adam', loss='mean_squared_error')
gen = ImageDataGenerator(width_shift_range=0.1, rotation_range=30, height_shift_range=0.1, horizontal_flip=True, validation_split=0.2, preprocessing_function=preprocess_input)
SEED = 49
def twin_gen(generator, subset):
gen_img = generator.flow_from_directory('./data', classes=['input_training_lowres'], seed=SEED, shuffle=False, subset=subset, color_mode='rgb')
gen_map = generator.flow_from_directory('./data/trimap_training_lowres', classes=['Trimap1'], seed=SEED, shuffle=False, subset=subset, color_mode='rgb')
gen_truth = generator.flow_from_directory('./data', classes=['gt_training_lowres'], seed=SEED, shuffle=False, subset=subset, color_mode='rgb')
while True:
img = gen_img.__next__()
tm = gen_map.__next__()
gt = gen_truth.__next__()
yield [[img, tm], gt]
train_gen = twin_gen(gen, 'training')
val_gen = twin_gen(gen, 'validation')
checkpoint_filepath = 'checkpoint'
checkpoint = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_filepath,
save_weights_only=True,
monitor='val_loss',
mode='auto',
save_freq='epoch',
save_best_only=True)
r = m.fit(train_gen, validation_data=val_gen, epochs=10, callbacks=[checkpoint])
First you didn't specify the input shape of VGG16 and you set include_top=False, so the default input shape will be (None, None ,3) for channels_last case.
PS: You can check the source code of keras.applications.VGG16 and keras.applications.imagenet_utils.obtain_input_shape for detail.
As you can see the output None shape by calling model.summary():
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 256, 256, 3) 0
__________________________________________________________________________________________________
input_3 (InputLayer) [(None, 256, 256, 3) 0
__________________________________________________________________________________________________
img_vgg16 (Functional) (None, None, None, 5 14714688 input_1[0][0]
__________________________________________________________________________________________________
tm_vgg16 (Functional) (None, None, None, 5 14714688 input_3[0][0]
__________________________________________________________________________________________________
concatenate (Concatenate) (None, 8, 8, 1024) 0 img_vgg16[0][0]
tm_vgg16[0][0]
__________________________________________________________________________________________________
To fix this you can simply set input_shape=(256, 256, 3) in VGG16, and calling model.summary() will now give you:
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 256, 256, 3) 0
__________________________________________________________________________________________________
input_3 (InputLayer) [(None, 256, 256, 3) 0
__________________________________________________________________________________________________
img_vgg16 (Functional) (None, 8, 8, 512) 14714688 input_1[0][0]
__________________________________________________________________________________________________
tm_vgg16 (Functional) (None, 8, 8, 512) 14714688 input_3[0][0]
__________________________________________________________________________________________________
concatenate (Concatenate) (None, 8, 8, 1024) 0 img_vgg16[0][0]
tm_vgg16[0][0]
__________________________________________________________________________________________________
The main cause of the error is when you calling __next__() it return tuple of two array (data, label) with shape ((batch_size, 256, 256, 3), (batch_size, 1)), but we really just want first one.
Also the data generator should yield tuple not list otherwise there will be no gradients provided for any variable, because the fit function expect (inputs, targets) as returning of data generator.
And you have another problem that your model's output shape is (batch_size, 256, 256, 1) but your gen_truth elements shape is (batch_size, 256, 256, 3) when you load the gen_truth image with color_mode='rgb', in order to get same shape with model's output you should load gen_truth using color_mode='grayscale' if you have grayscale image or load it using color_mode='rgba' and get the last channel value if you want using alpha value (I just guess it from the description in your question, but you should get the idea)
Example code that running without any problem:
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2DTranspose, Concatenate, BatchNormalization, Input
from tensorflow.keras.preprocessing.image import ImageDataGenerator
def DeConvBlock(input, num_output):
x = Conv2DTranspose(num_output, kernel_size=3, strides=2, activation='relu', padding='same')(input)
x = BatchNormalization()(x)
x = Conv2DTranspose(num_output, kernel_size=3, strides=1, activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2DTranspose(num_output, kernel_size=3, strides=1, activation='relu', padding='same')(x)
x = BatchNormalization()(x)
return x
img_input = Input((256, 256, 3))
img_vgg16 = VGG16(include_top=False, input_shape=(256, 256, 3), weights='imagenet')
img_vgg16._name = 'img_vgg16'
img_vgg16.trainable = False
tm_input = Input((256, 256, 3))
tm_vgg16 = VGG16(include_top=False, input_shape=(256, 256, 3), weights='imagenet')
tm_vgg16._name = 'tm_vgg16'
tm_vgg16.trainable = False
img_vgg16 = img_vgg16(img_input)
tm_vgg16 = tm_vgg16(tm_input)
x = Concatenate()([img_vgg16, tm_vgg16])
x = DeConvBlock(x, 512)
x = DeConvBlock(x, 256)
x = DeConvBlock(x, 128)
x = DeConvBlock(x, 64)
x = DeConvBlock(x, 32)
x = Conv2DTranspose(1, kernel_size=3, strides=1, activation='sigmoid', padding='same')(x)
m = Model(inputs=[img_input, tm_input], outputs=x)
m.summary()
m.compile(optimizer='adam', loss='mse')
gen = ImageDataGenerator(width_shift_range=0.1, rotation_range=30, height_shift_range=0.1, horizontal_flip=True, validation_split=0.2, preprocessing_function=preprocess_input)
SEED = 49
def twin_gen(generator, subset):
gen_img = generator.flow_from_directory('./data', classes=['input_training_lowres'], seed=SEED, shuffle=False, subset=subset, color_mode='rgb')
gen_map = generator.flow_from_directory('./data/trimap_training_lowres', classes=['Trimap1'], seed=SEED, shuffle=False, subset=subset, color_mode='rgb')
gen_truth = generator.flow_from_directory('./data', classes=['gt_training_lowres'], seed=SEED, shuffle=False, subset=subset, color_mode='grayscale')
while True:
img = gen_img.__next__()[0]
tm = gen_map.__next__()[0]
gt = gen_truth.__next__()[0]
yield ([img, tm], gt)
train_gen = twin_gen(gen, 'training')
r = m.fit(train_gen, steps_per_epoch=5, epochs=3)

List index out of range while training with model.fit

First of all, I tried to look at other similar questions, but it has not fixed my issues.
I have a project which required me to use Data Augmentation to increase the samples and Transfer Learning with VGG16 to improve the accuracy. I found this Github link online https://github.com/sachinruk/deepschool.io/blob/master/DL-Keras_Tensorflow/Lesson%2013%20-%20Transfer%20Learning%20-%20Solutions.ipynb and I try to apply to my project, but the error is List index out of range. I already loaded the images in data --> train or test --> benign or malign. My image's shape is (360,560,3). I am using Tensorflow 2.1.0. Here is my code.
import random
import numpy as np
from numpy.random import randint as rdi
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from plotly import __version__
import cufflinks as cf
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
cf.go_offline()
import plotly.graph_objects as go
from plotly.offline import *
import plotly.offline as pyo
import chart_studio.plotly as py
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Conv2D, MaxPool2D, Flatten, MaxPooling2D, Activation, Reshape, BatchNormalization
from sklearn.metrics import mean_squared_error, mean_absolute_error, explained_variance_score
from tensorflow.keras.models import load_model
from tensorflow.keras.callbacks import EarlyStopping, TensorBoard
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets import cifar10
import os
from matplotlib.image import imread
from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import warnings
from tensorflow.keras.preprocessing import image
from mpl_toolkits.mplot3d import Axes3D
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.layers import GaussianNoise
from keras import applications
import cv2
from os.path import isfile, isdir, getsize
from tqdm import tqdm
from urllib.request import urlretrieve
import zipfile
import tarfile
import pickle
import glob
import shutil
from os.path import isfile, isdir, getsize
from os import mkdir, makedirs, remove, listdir
# Try to download bottelneck file for later use
class DLProgress(tqdm):
last_block = 0
def hook(self, block_num=1, block_size=1, total_size=None):
self.total = total_size
self.update((block_num - self.last_block) * block_size)
self.last_block = block_num
class DLProgress(tqdm):
last_block = 0
def hook(self, block_num=1, block_size=1, total_size=None):
self.total = total_size
self.update((block_num - self.last_block) * block_size)
self.last_block = block_num
if not isfile('bottleneck_features_train.npy'):
with DLProgress(unit='B', unit_scale=True, miniters=1, desc='Bottleneck features') as pbar:
urlretrieve(
'https://www.dropbox.com/s/a38gpvdcryw0kfc/bottleneck.zip?dl=1',
'bottleneck.zip',
pbar.hook)
with zipfile.ZipFile('bottleneck.zip') as f:
f.extractall('./')
files = listdir('bottleneck 2/')
for f in files:
shutil.move('bottleneck 2/'+f,'./')
shutil.rmtree('bottleneck 2/')
remove('bottleneck.zip')
# Import the Ultrasound dataset
data_dir = 'C:\Spring 2020\Machine Learning and Computer Vision\data'
os.listdir(data_dir)
test_path = data_dir+'\\test\\'
train_path = data_dir+'\\train\\'
os.listdir(test_path)
os.listdir(train_path)
os.listdir(train_path+'\\malign')[0]
para_cell = train_path+'\\malign'+'\\53.jpg'
para_img= imread(para_cell)
para_img.shape
plt.imshow(para_img)
image_shape = (360,560,3)
# Generate some new images
datagen = ImageDataGenerator(rescale=1.0/255)
# Create model
model = applications.VGG16(include_top = False, input_shape = image_shape)
model = applications.VGG16(include_top = False, weights = 'imagenet')
model.summary()
with open('bottleneck_features_train.npy','rb') as f:
bottleneck_features_train = pickle.load(f)
bottleneck_features_train.shape
batch_size = 128
generator = datagen.flow_from_directory(
train_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
batch_size = 128
valid_generator = datagen.flow_from_directory(
test_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
# Use bottleneck file
with open('bottleneck_features_train.npy','rb') as f:
bottleneck_features_train = pickle.load(f)
# Apply model
model = Sequential()
model.add(Flatten(input_shape=bottleneck_features_train.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
batch_size = 128
# Set up the flow of training data
generator = datagen.flow_from_directory(
train_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
generator.class_indices
# Set up the early stop to avoid training so many epochs, but won't increase the accuracy
early_stop = EarlyStopping(monitor='val_loss',patience=5)
warnings.filterwarnings('ignore')
# I think the code stucks here
results = model.fit(bottleneck_features_train, epochs=15, batch_size = batch_size)
# Save to vgg16
model.save('vgg16.h5')
losses = pd.DataFrame(model.history.history)
losses[['loss','val_loss']].plot()
model.metrics_names
model.evaluate_generator(test_image_gen)
#https://datascience.stackexchange.com/questions/13894/how-to-get-predictions-with-predict-generator-on-streaming-test-data-in-keras
pred_probabilities = model.predict_generator(test_image_gen)
#preds_num = pred_probabilities
test_image_gen.classes
predictions = pred_probabilities > 0.5
# Numpy can treat this as True/False for us
predictions
check = classification_report(test_image_gen.classes,predictions)
print(classification_report(test_image_gen.classes,predictions))
print(confusion_matrix(test_image_gen.classes,predictions))
para_cell
my_image = image.load_img(para_cell,target_size=image_shape)
my_image
type(my_image)
my_image = image.img_to_array(my_image)
type(my_image)
my_image.shape
my_image = np.expand_dims(my_image, axis=0)
my_image.shape
para_cell = test_path+'\\benign'+'\\40.jpg'
my_image = image.load_img(para_cell,target_size=image_shape)
my_image
type(my_image)
my_image = image.img_to_array(my_image)
type(my_image)
my_image.shape
my_image = np.expand_dims(my_image, axis=0)
my_image.shape
model.predict(my_image)
The error is:
runfile('C:/Spring 2020/Machine Learning and Computer Vision/hopefully.py', wdir='C:/Spring 2020/Machine Learning and Computer Vision')
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_16 (InputLayer) (None, None, None, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, None, None, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, None, None, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, None, None, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, None, None, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, None, None, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, None, None, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, None, None, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, None, None, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, None, None, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, None, None, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, None, None, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, None, None, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, None, None, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
Found 2198 images belonging to 2 classes.
Found 800 images belonging to 2 classes.
Model: "sequential_7"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_7 (Flatten) (None, 4608) 0
_________________________________________________________________
dense_14 (Dense) (None, 256) 1179904
_________________________________________________________________
dropout_7 (Dropout) (None, 256) 0
_________________________________________________________________
dense_15 (Dense) (None, 1) 257
=================================================================
Total params: 1,180,161
Trainable params: 1,180,161
Non-trainable params: 0
_________________________________________________________________
Found 2198 images belonging to 2 classes.
Train on 19872 samples
Epoch 1/15
128/19872 [..............................] - ETA: 2sTraceback (most recent call last):
File "C:\Spring 2020\Machine Learning and Computer Vision\hopefully.py", line 188, in <module>
results = model.fit(bottleneck_features_train, epochs=15, batch_size = batch_size)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 819, in fit
use_multiprocessing=use_multiprocessing)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 342, in fit
total_epochs=epochs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 128, in run_one_epoch
batch_outs = execution_function(iterator)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_v2_utils.py", line 98, in execution_function
distributed_function(input_fn))
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\def_function.py", line 568, in __call__
result = self._call(*args, **kwds)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\def_function.py", line 615, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\def_function.py", line 497, in _initialize
*args, **kwds))
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py", line 2389, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py", line 2703, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\function.py", line 2593, in _create_graph_function
capture_by_value=self._capture_by_value),
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\framework\func_graph.py", line 978, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\eager\def_function.py", line 439, in wrapped_fn
return weak_wrapped_fn().__wrapped__(*args, **kwds)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_v2_utils.py", line 85, in distributed_function
per_replica_function, args=args)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\distribute\distribute_lib.py", line 763, in experimental_run_v2
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\distribute\distribute_lib.py", line 1819, in call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\distribute\distribute_lib.py", line 2164, in _call_for_each_replica
return fn(*args, **kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\autograph\impl\api.py", line 292, in wrapper
return func(*args, **kwargs)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_v2_utils.py", line 433, in train_on_batch
output_loss_metrics=model._output_loss_metrics)
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_eager.py", line 312, in train_on_batch
output_loss_metrics=output_loss_metrics))
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_eager.py", line 253, in _process_single_batch
training=training))
File "C:\Users\binhd\Anaconda3\lib\site-packages\tensorflow_core\python\keras\engine\training_eager.py", line 167, in _model_loss
per_sample_losses = loss_fn.call(targets[i], outs[i])
IndexError: list index out of range
Like I mentioned above, I re-used some codes from online Github to apply to my previous codes. The codes I re-used are (In just copy and paste the codes above, so you might not need to look at this part. It is just for info):
# Try to download bottelneck file for later use
class DLProgress(tqdm):
last_block = 0
def hook(self, block_num=1, block_size=1, total_size=None):
self.total = total_size
self.update((block_num - self.last_block) * block_size)
self.last_block = block_num
class DLProgress(tqdm):
last_block = 0
def hook(self, block_num=1, block_size=1, total_size=None):
self.total = total_size
self.update((block_num - self.last_block) * block_size)
self.last_block = block_num
if not isfile('bottleneck_features_train.npy'):
with DLProgress(unit='B', unit_scale=True, miniters=1, desc='Bottleneck features') as pbar:
urlretrieve(
'https://www.dropbox.com/s/a38gpvdcryw0kfc/bottleneck.zip?dl=1',
'bottleneck.zip',
pbar.hook)
with zipfile.ZipFile('bottleneck.zip') as f:
f.extractall('./')
files = listdir('bottleneck 2/')
for f in files:
shutil.move('bottleneck 2/'+f,'./')
shutil.rmtree('bottleneck 2/')
remove('bottleneck.zip')
And (In just copy and paste the codes above, so you might not need to look at this part. It is just for info):
# Generate some new images
datagen = ImageDataGenerator(rescale=1.0/255)
# Create model
model = applications.VGG16(include_top = False, input_shape = image_shape)
model = applications.VGG16(include_top = False, weights = 'imagenet')
model.summary()
with open('bottleneck_features_train.npy','rb') as f:
bottleneck_features_train = pickle.load(f)
bottleneck_features_train.shape
batch_size = 128
generator = datagen.flow_from_directory(
train_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
batch_size = 128
valid_generator = datagen.flow_from_directory(
test_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
# Use bottleneck file
with open('bottleneck_features_train.npy','rb') as f:
bottleneck_features_train = pickle.load(f)
# Apply model
model = Sequential()
model.add(Flatten(input_shape=bottleneck_features_train.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
batch_size = 128
# Set up the flow of training data
generator = datagen.flow_from_directory(
train_path,
target_size=image_shape[:2],
batch_size=batch_size,
class_mode=None,
shuffle=False)
generator.class_indices
# Set up the early stop to avoid training so many epochs, but won't increase the accuracy
early_stop = EarlyStopping(monitor='val_loss',patience=5)
warnings.filterwarnings('ignore')
# I think the code stucks here
results = model.fit(bottleneck_features_train, epochs=15, batch_size = batch_size)
How can I fix this issue?
I was able to recreate your issue using the below code. The error occurs when you don't pass the target variable or label in model.fit() function.
Note - You can download the dataset I have used in the code from here.
Error Code -
# MLP for Pima Indians Dataset saved to single file
import numpy as np
from numpy import loadtxt
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# load pima indians dataset
dataset = np.loadtxt("/content/pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# define model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Model Summary
model.summary()
# Fit the model
model.fit(X, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
Output -
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 12) 108
_________________________________________________________________
dense_1 (Dense) (None, 8) 104
_________________________________________________________________
dense_2 (Dense) (None, 1) 9
=================================================================
Total params: 221
Trainable params: 221
Non-trainable params: 0
_________________________________________________________________
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-1-b9b0f557b27e> in <module>()
25
26 # Fit the model
---> 27 model.fit(X, epochs=150, batch_size=10, verbose=0)
28
29 # evaluate the model
1 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training_arrays.py in fit_loop(model, inputs, targets, sample_weights, batch_size, epochs, verbose, callbacks, val_inputs, val_targets, val_sample_weights, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)
185 indices_for_conversion_to_dense = []
186 for i in range(len(feed)):
--> 187 if issparse is not None and issparse(ins[i]) and not K.is_sparse(feed[i]):
188 indices_for_conversion_to_dense.append(i)
189
IndexError: list index out of range
Solution - Pass the target variable or label in model.fit along with training features.
Fixed Code -
# MLP for Pima Indians Dataset saved to single file
import numpy as np
from numpy import loadtxt
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# load pima indians dataset
dataset = np.loadtxt("/content/pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# define model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Model Summary
model.summary()
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
Output -
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_3 (Dense) (None, 12) 108
_________________________________________________________________
dense_4 (Dense) (None, 8) 104
_________________________________________________________________
dense_5 (Dense) (None, 1) 9
=================================================================
Total params: 221
Trainable params: 221
Non-trainable params: 0
_________________________________________________________________
acc: 70.96%

AttributeError: KerasTPUModel' object has no attribute _ckpt_saved_epoch

I am trying to train a model on Google Colab, in order to play around with training on TPU. However, I am running into the following error:
AttributeError Traceback (most recent call last)
<ipython-input-82-e74efc36d872> in <module>()
----> 1 tpu_model.fit_generator(training_set, steps_per_epoch = 8000, epochs = 25)
2 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/callbacks.py in configure_callbacks(callbacks, model, do_validation, batch_size, epochs, steps_per_epoch, samples, verbose, count_mode, mode)
118 callback_list.model.stop_training = False
119 # pylint: disable=protected-access
--> 120 if callback_list.model._ckpt_saved_epoch is not None:
121 # The attribute `_ckpt_saved_epoch` is supposed to be None at the start of
122 # training (it should be made None at the end of successful multi-worker
AttributeError: 'KerasTPUModel' object has no attribute '_ckpt_saved_epoch'
While trying to run the following code.
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
import zipfile
print(tf.VERSION)
local_zip = '/home/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/home')
zip_ref.close()
def create_model():
classifier = tf.keras.models.Sequential()
classifier.add(layers.Conv2D(32, (3, 3), input_shape=(64, 64, 3), activation='relu'))
classifier.add(layers.MaxPooling2D(pool_size=(2, 2)))
classifier.add(layers.Conv2D(32, (3, 3), activation= 'relu'))
classifier.add(layers.MaxPooling2D(pool_size=(2, 2)))
classifier.add(layers.Flatten())
classifier.add(layers.Dense(units=128, activation= 'relu'))
classifier.add(layers.Dense(units=1, activation= 'sigmoid'))
return classifier
train_datagen = ImageDataGenerator(rescale = 1./255, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)
training_set = train_datagen.flow_from_directory('/home/cats_and_dogs_filtered/train', target_size = (64, 64), batch_size = 32, class_mode = 'binary')
model = create_model()
TPU_WORKER = 'grpc://' + os.environ['COLAB_TPU_ADDR']
tpu_model = tf.contrib.tpu.keras_to_tpu_model( model, strategy=tf.contrib.tpu.TPUDistributionStrategy(tf.contrib.cluster_resolver.TPUClusterResolver(TPU_WORKER)))
tpu_model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
tpu_model.save_weights('./tpu_model.h5', overwrite=True)
tpu_model.fit_generator(training_set, steps_per_epoch = 8000, epochs = 25)
I am not sure what is going on. I used similar code to train it on CPU (takes a long time to train).

CNN implementation using Keras and Tensorflow

I have created a CNN model using Keras and I am training it on a MNIST dataset. I got a reasonable accuracy around 98%, which is what I expected:
model = Sequential()
model.add(Conv2D(64, 5, activation="relu", input_shape=(28, 28, 1)))
model.add(MaxPool2D())
model.add(Conv2D(64, 5, activation="relu"))
model.add(MaxPool2D())
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam',
loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(data.x_train, data.y_train,
batch_size=256, validation_data=(data.x_test, data.y_test))
Now I want to build the same model, but using vanilla Tensorflow, here is how I did that:
X = tf.placeholder(shape=[None, 784], dtype=tf.float32, name="X")
Y = tf.placeholder(shape=[None, 10], dtype=tf.float32, name="Y")
net = tf.reshape(X, [-1, 28, 28, 1])
net = tf.layers.conv2d(
net, filters=64, kernel_size=5, padding="valid", activation=tf.nn.relu)
net = tf.layers.max_pooling2d(net, pool_size=2, strides=2)
net = tf.layers.conv2d(
net, filters=64, kernel_size=5, padding="valid", activation=tf.nn.relu)
net = tf.layers.max_pooling2d(net, pool_size=2, strides=2)
net = tf.contrib.layers.flatten(net)
net = tf.layers.dense(net, name="dense1", units=256, activation=tf.nn.relu)
model = tf.layers.dense(net, name="output", units=10)
And here is how I train/test it:
loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y, logits=model)
opt = tf.train.AdamOptimizer().minimize(loss)
accuracy = tf.cast(tf.equal(tf.argmax(model, 1), tf.argmax(Y, 1)), tf.float32)
with tf.Session() as sess:
tf.global_variables_initializer().run()
for batch in range(data.get_number_of_train_batches(batch_size)):
x, y = data.get_next_train_batch(batch_size)
sess.run([loss, opt], feed_dict={X: x, Y: y})
for batch in range(data.get_number_of_test_batches(batch_size)):
x, y = data.get_next_test_batch(batch_size)
sess.run(accuracy, feed_dict={X: x, Y: y})
But the resulting accuracy of the model dropped to ~80%. What are the principal differences between my implementation of that model using Keras and Tensorflow ? Why the accuracy varies so much ?
I don't see any mistakes in your code. Note that your current model is heavily parameterized for such a simple problem because of the Dense layers, which introduce over 260k trainable parameters:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_3 (Conv2D) (None, 24, 24, 64) 1664
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 12, 12, 64) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 8, 8, 64) 102464
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 4, 4, 64) 0
_________________________________________________________________
flatten_2 (Flatten) (None, 1024) 0
_________________________________________________________________
dense_2 (Dense) (None, 256) 262400
_________________________________________________________________
dense_3 (Dense) (None, 10) 2570
=================================================================
Total params: 369,098
Trainable params: 369,098
Non-trainable params: 0
_________________________________________________________________
Below, I will run your code with:
minor adaptations to make the code work with the MNIST dataset in keras.datasets
a simplified model: basically I remove the 256-node Dense layer, drastically reducing the number of trainable parameters, and introduce some dropout for regularization.
With these changes, both models achieve 90%+ validation set accuracy after the first epoch. So it seems the problem you encountered has to do with an ill-posed optimization problem which leads to highly variable outcomes, and not with a bug in your code.
# Import the datasets
import numpy as np
from keras.datasets import mnist
from keras.utils import to_categorical
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Add batch dimension
x_train = np.expand_dims(x_train, axis=-1)
x_test = np.expand_dims(x_test, axis=-1)
# One-hot encode the labels
y_train = to_categorical(y_train, num_classes=None)
y_test = to_categorical(y_test, num_classes=None)
batch_size = 64
# Fit model using Keras
import keras
import numpy as np
from keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Dropout
from keras.models import Sequential
model = Sequential()
model.add(Conv2D(32, 5, activation="relu", input_shape=(28, 28, 1)))
model.add(MaxPool2D())
model.add(Conv2D(32, 5, activation="relu"))
model.add(MaxPool2D())
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam',
loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=32, validation_data=(x_test, y_test), epochs=1)
Result:
Train on 60000 samples, validate on 10000 samples
Epoch 1/1
60000/60000 [==============================] - 35s 583us/step - loss: 1.5217 - acc: 0.8736 - val_loss: 0.0850 - val_acc: 0.9742
Note that the number of trainable parameters is now just a fraction of the amount in your model:
model.summary()
Layer (type) Output Shape Param #
=================================================================
conv2d_3 (Conv2D) (None, 24, 24, 32) 832
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 12, 12, 32) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 8, 8, 32) 25632
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 4, 4, 32) 0
_________________________________________________________________
flatten_2 (Flatten) (None, 512) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 5130
=================================================================
Total params: 31,594
Trainable params: 31,594
Non-trainable params: 0
Now, doing the same with TensorFlow:
# Fit model using TensorFlow
import tensorflow as tf
X = tf.placeholder(shape=[None, 28, 28, 1], dtype=tf.float32, name="X")
Y = tf.placeholder(shape=[None, 10], dtype=tf.float32, name="Y")
net = tf.layers.conv2d(
X, filters=32, kernel_size=5, padding="valid", activation=tf.nn.relu)
net = tf.layers.max_pooling2d(net, pool_size=2, strides=2)
net = tf.layers.conv2d(
net, filters=32, kernel_size=5, padding="valid", activation=tf.nn.relu)
net = tf.layers.max_pooling2d(net, pool_size=2, strides=2)
net = tf.contrib.layers.flatten(net)
net = tf.layers.dropout(net, rate=0.25)
model = tf.layers.dense(net, name="output", units=10)
loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y, logits=model)
opt = tf.train.AdamOptimizer().minimize(loss)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(model, 1), tf.argmax(Y, 1)), tf.float32))
with tf.Session() as sess:
tf.global_variables_initializer().run()
L = []
l_ = 0
for i in range(x_train.shape[0] // batch_size):
x, y = x_train[i*batch_size:(i+1)*batch_size],\
y_train[i*batch_size:(i+1)*batch_size]
l, _ = sess.run([loss, opt], feed_dict={X: x, Y: y})
l_ += np.mean(l)
L.append(l_ / (x_train.shape[0] // batch_size))
print('Training loss: {:.3f}'.format(L[-1]))
acc = []
for j in range(x_test.shape[0] // batch_size):
x, y = x_test[j*batch_size:(j+1)*batch_size],\
y_test[j*batch_size:(j+1)*batch_size]
acc.append(sess.run(accuracy, feed_dict={X: x, Y: y}))
print('Test set accuracy: {:.3f}'.format(np.mean(acc)))
Result:
Training loss: 0.519
Test set accuracy: 0.968
Possible improvement of your models.
I used CNN networks on different problems and always got good effectiveness improvements with regularization techniques, the best ones with dropout.
I suggest to use Dropout on the Dense layers and in case with lower probability on the convolutional ones.
Also data augmentation on the input data is very important, but applicability depends on the problem domain.
P.s: in one case I had to change the optimization from Adam to SGD with Momentum. So, playing with the optimization makes sense. Also Gradient clipping can be considered when your networks starves and doesn't improve effectiveness, may be a numeric issue.

expected conv2d_1_input to have shape (28, 28, 1) but got array with shape (1, 28, 28)

So i'm using the mnist example on keras and I am trying to predict a digit of my own. I'm really struggling with how I can match the dimension sizes as I cant seem to find a way to resize my image to have the rows and columns after the image no. I've tried resizing with via numpy however I just get error after error...
The code
from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
import numpy as np
import cv2
batch_size = 20
num_classes = 10
epochs = 1
img_rows, img_cols = 28, 28
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print("Processing image")
im = cv2.imread('C:/Users/Luke/pic4.png', 0) #loading the image
print(im.shape) #28*28
im = cv2.resize(im, (img_rows, img_cols))
list = [im]
batch = np.array([list for i in range(1)])
print(batch.shape)#1*28*28
batch = batch.astype('float32')
batch /= 255
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
#print("x_train shape")
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
def base_model():
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
return model
cnn_m = base_model()
cnn_m.summary()
print("Predicting image")
cnn_m.predict(batch)
print("Predicted image")
Error
$ python mnist_cnn_test.py
Using TensorFlow backend.
x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
conv2d_2 (Conv2D) (None, 24, 24, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 64) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 12, 12, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 9216) 0
_________________________________________________________________
dense_1 (Dense) (None, 128) 1179776
_________________________________________________________________
dropout_2 (Dropout) (None, 128) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 1290
=================================================================
Total params: 1,199,882
Trainable params: 1,199,882
Non-trainable params: 0
_________________________________________________________________
Predicting image
Traceback (most recent call last):
File "mnist_cnn_test.py", line 100, in <module>
cnn_m.predict(batch)
File "C:\Python35\lib\site-packages\keras\models.py", line 1027, in predict
steps=steps)
File "C:\Python35\lib\site-packages\keras\engine\training.py", line 1782, in predict
check_batch_axis=False)
File "C:\Python35\lib\site-packages\keras\engine\training.py", line 120, in _standardize_input_data
str(data_shape))
ValueError: Error when checking : expected conv2d_1_input to have shape (28, 28, 1) but got array with shape (1, 28, 28)
Looks like you have the wrong data format. Your data is passed as channels_first (i.e. each image is 1 x 28 x 28) but the Conv2D layers expect channels_last (28 x 28 x 1).
One fix would be to pass data_format=channels_first to the Conv2D and MaxPooling layers. However this might not be supported if you are running on the CPU. Alternatively, change this part
if K.image_data_format() == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
to always execute the else block (which does reshaping to a channels_last format). In that case, don't include the data_format argument to the Conv layers (it defaults to channels_last).
Solution:
im = cv2.resize(im, (img_rows, img_cols))
im.reshape((img_rows,img_cols))
print(im.shape) # (28,28)
batch = np.expand_dims(im,axis=0)
print(batch.shape) # (1, 28, 28)
batch = np.expand_dimes(batch,axis=3)
print(batch.shape) # (1, 28, 28,1)
... # build the model
model.predict(batch)
Reasoning:
print(model.input_shape) # (None,28,28,1)
Means any batch size(sample number), 28 * 28 shape and 1 channel.
In your case use 1 as sample number.
You can simply add
K.set_image_dim_ordering('th')