0 validation loss while training TensorFlow CNN model - tensorflow

import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
DATADIR = "C:\\Users\\John\\Documents\\CroppedYale"
CATEGORIES = ["yaleB01","yaleB02","yaleB03","yaleB04","yaleB05","yaleB06","yaleB07","yaleB08","yaleB09","yaleB10","yaleB11","yaleB12","yaleB13","yaleB15","yaleB16","yaleB17","yaleB18","yaleB19","yaleB20","yaleB21","yaleB22","yaleB23","yaleB24","yaleB25","yaleB26","yaleB27","yaleB28","yaleB29","yaleB30","yaleB31","yaleB32","yaleB33","yaleB34","yaleB35","yaleB36","yaleB37","yaleB38","yaleB39"]
for category in CATEGORIES:
path = os.path.join(DATADIR, category)
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
plt.imshow(img_array, cmap="gray")
plt.show()
break
break
print(img_array)
IMG_SIZE = 50
new_array = cv2.resize(img_array, (IMG_SIZE,IMG_SIZE))
plt.imshow(new_array,cmap="gray")
plt.show()
training_data = []
def create_training_data():
for category in CATEGORIES:
path = os.path.join(DATADIR, category)
class_num = CATEGORIES.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE,IMG_SIZE))
training_data.append([new_array, class_num])
except Exception as e:
pass
create_training_data()
print(len(training_data))
import random
random.shuffle(training_data)
for sample in training_data[:10]:
print(sample[1])
X = []
y = []
for features, label in training_data:
X.append(features)
y.append(label)
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array(y)
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
X = X/255.0
model = Sequential()
model.add( (Conv2D(64 , (3,3) , input_shape = X.shape[1:])))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64 , (3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation("relu"))
model.add(Dense(1))
model.add(Activation("sigmoid"))
model.compile(loss="CategoricalCrossentropy",
optimizer="adam",
metrics=['accuracy'])
model.fit(X, y, batch_size=32, epochs=10, validation_split=0.1)
Does anyone know why I get 0.00 loss? Obviously I'm doing something wrong. I just don't know what. It's 40 people with their own folder each folder has 36 images of their face. Is it a problem with how I processed my data or the model itself? Maybe the model has wrong layers or the preprocessing is wrong altogether.

Related

Model not learning with tf.keras.preprocessing.image_dataset_from_directory

I tried to make a simple model to recognize images of animals (3 classes),
with the function tf.keras.preprocessing.image_dataset_from_directory, when i fit the model with the train and validation dataset, it seems to work, but on evaluate and predict, it find always the same class, I dont know why, here is my code :
import matplotlib.pyplot as plt
import numpy as np
import PIL
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow import keras
import os
i = 0
def fast_scandir(dirname):
subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
classnames = fast_scandir("/home/someone/Documents/machinelearning/path/testimage")
for name in classnames:
classnames[i] = classnames[i].replace("/home/someone/Documents/machinelearning/path/images/","")
i+=1
i=0
classesnum = len(classnames)
#print(classesnum)
img_height = 256
img_width = 256
batch_size = 16
IMAGE_SIZE = 256
data_dir = "/home/someone/Documents/machinelearning/path/testimage"
test_dir = "/home/someone/Documents/machinelearning/path/testimage"
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
print(train_ds)
'''
test_ds = tf.keras.preprocessing.image_dataset_from_directory(
test_dir,
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
'''
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
'''
#####debug######
for images,labels in train_ds.take(1):
for i in range(len(labels)):
img = plt.imshow(images[i].numpy().astype("uint8"))
plt.title(str(labels[i]))
plt.show()
'''
#tf.data.experimental.cardinality(train_ds)
#print(val_ds)
#print(np.shape(val_ds))
#print(type(val_ds))
import matplotlib.pyplot as plt
pretrained_model= tf.keras.applications.ResNet50(include_top=False,
input_shape=(img_width,img_height,3),
pooling='avg',classes=classesnum,
weights='imagenet')
for layer in pretrained_model.layers:
layer.trainable=False
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import optimizers
model = Sequential()
model.add(Conv2D(32,(3,3),input_shape=(IMAGE_SIZE,IMAGE_SIZE,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(96,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(128,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(512,activation='relu'))
model.add(Dense(3,activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.Adam(learning_rate=3e-4),
metrics=['accuracy'])
history = model.fit(train_ds, validation_data=val_ds, epochs=10)
fig1 = plt.gcf()
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.axis(ymin=0.4,ymax=1)
plt.grid()
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'validation'])
plt.show()
model.save("/home/someone/Documents/machinelearning/path/model.h5")
'''
evaluation = model.evaluate(test_ds, return_dict=True)
for name, value in evaluation.items():
print(f"{name}: {value:.4f}")
'''
I think its something that is set wrong like a bad number of classes somewhere..
It seems that setting shuffle=True in the dataset, resolved the issue, because somehow just a part of the dataset is used in my model.

I couldn't save a sequential model in Keras

## Step 1) Import Libraries
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICE"] = ""
from tensorflow.python.client import device_lib;
print(device_lib.list_local_devices());
import keras
import numpy as np
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
#### Set some parameters
batch_size = 256
num_classes = 10
epochs = 3
## Step 2) Load and Prepare data|
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print('y_train shape:', y_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
### Prepare data
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure()
fig_size = [20, 20]
plt.rcParams["figure.figsize"] = fig_size
idx = 0
for idx in range(1,101):
ax = plt.subplot(10, 10, idx)
img = x_train[idx,:,:,:]
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.imshow(img, cmap="Greys_r")
plt.show()
#### Preprocess class lables
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
#### Data Augmentation
datagen = ImageDataGenerator(
featurewise_center = False, # set input mean to over the dataset
samplewise_center = False, # set each sample mean to 0
featurewise_std_normalization = False, # divide inputs of the dataset
samplewise_std_normalization = False, # divide each input by its std
zca_whitening = False, # apply ZCA whitening
rotation_range = 0, # randomply rotate images in the range (degrees, 0 to 180)
width_shift_range = 0.1, # randomly shift images horiznontally (fraction of totla width)
height_shift_range = 0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip = True, # randomly flip images
vertical_flip = False) # randomly flip images
## Setp 3) Define model architecture
model = Sequential()
model.add(Conv2D(32, (3,3), padding = 'same', activation = 'relu', input_shape = x_train.shape[1:]))
model.add(Conv2D(32, (3,3), activation = 'relu',))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3,3), padding = 'same', activation = 'relu',))
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(512, activation = 'relu',))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation = 'softmax'))
## Step 4) Compile model
# model.compile(loss='categorical_crossentropy', optimizer = 'Adagrad', metrics = ['accuracy'])
model.compile(loss='categorical_crossentropy', optimizer = 'Adam', metrics = ['accuracy'])
#### Summary of model
model.summary()
## Step 5) Fit model on training data
# Compute quantities required for feature-wise normalization
# (std, mean, and principal components if ZCA whitening is applied).
datagen.fit(x_train)
# Fit the model on the batches generated by datagen.flow().
model.fit_generator(datagen.flow(x_train, y_train, batch_size = batch_size),
steps_per_epoch = x_train.shape[0] // batch_size, # // is the quotient without remainder
epochs = epochs,
validation_data = (x_test, y_test))
model.save('my_model')
And I have error
AttributeError Traceback (most recent call last)
<ipython-input-18-b71b28267016> in <module>
1 from tensorflow.keras.models import load_model
----> 2 model.save('my_model')
~\anaconda3\envs\tf\lib\site-packages\keras\engine\network.py in save(self, filepath, overwrite, include_optimizer)
1150 raise NotImplementedError
1151 from ..models import save_model
-> 1152 save_model(self, filepath, overwrite, include_optimizer)
1153
1154 #saving.allow_write_to_gcs
~\anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py in save_wrapper(obj, filepath, overwrite, *args, **kwargs)
447 os.remove(tmp_filepath)
448 else:
--> 449 save_function(obj, filepath, overwrite, *args, **kwargs)
450
451 return save_wrapper
~\anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py in save_model(model, filepath, overwrite, include_optimizer)
539 return
540 with H5Dict(filepath, mode='w') as h5dict:
--> 541 _serialize_model(model, h5dict, include_optimizer)
542 elif hasattr(filepath, 'write') and callable(filepath.write):
543 # write as binary stream
~\anaconda3\envs\tf\lib\site-packages\keras\engine\saving.py in _serialize_model(model, h5dict, include_optimizer)
161 layer_group[name] = val
162 if include_optimizer and model.optimizer:
--> 163 if isinstance(model.optimizer, optimizers.TFOptimizer):
164 warnings.warn(
165 'TensorFlow optimizers do not '
AttributeError: module 'keras.optimizers' has no attribute 'TFOptimizer'
I trained a sequential model and tried to save it by the code model.save(filename)
But it says AttributeError: module 'keras.optimizers' has no attribute 'TFOptimizer'
The error appears on model.save(path).
I don't know why I couldn't save the sequential model.
That error appears even when I directly import TFOptimizer from keras.optimizers
I also installed H
I had the same problem. When I changed the version of keras and tensorflow to keras2.2.5 and tensorflow1.14.0, the problem was solved.

Why my Keras Image classification prediction always return one value...?

I am using CNN to classify multiple people. People's number is 114 and each has about 120 image dataset.
I use keras and model that is used in dog vs cat classification.
It works well in Dogs and Cat classification.
But this is only return same value in different person image.
It says accuracy 99.12 but not work.
this is my train code
# coding: utf-8
# In[1]:
import os
import cv2
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.cross_validation import train_test_split
from keras import backend as K
from keras import layers, models, optimizers
from keras.preprocessing.image import ImageDataGenerator, img_to_array, array_to_img
from keras.applications.resnet50 import preprocess_input
from keras.utils import np_utils
from numpy import array
# In[2]:
TRAIN_DIR = './Dataset'
train_folder_list = array(os.listdir(TRAIN_DIR))
# In[13]:
X = []
Y = []
# In[14]:
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(train_folder_list)
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
for idx, index in enumerate(range(len(train_folder_list))):
path = os.path.join(TRAIN_DIR, train_folder_list[index])
path = path + '/'
img_list = os.listdir(path)
for img in img_list:
img_path = os.path.join(path, img)
img = cv2.imread(img_path)
if img is not None:
img = cv2.resize(img, (100, 100))
img = img_to_array(img)
X.append(img)
Y.append(idx)
X = np.array(X, dtype="float") / 255.0
# In[15]:
(X_train, X_test, Y_train, Y_test) = train_test_split(X,Y,test_size=0.2, random_state = 42)
Y_train = np_utils.to_categorical(Y_train, len(train_folder_list))
Y_test = np_utils.to_categorical(Y_test, len(train_folder_list))
print(X_train[0])
# In[17]:
nb_train_samples = len(X_train)
nb_valivation_samples = len(X_test)
batch_size = 32
# In[18]:
print(K.image_data_format())
# In[19]:
model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), input_shape=(100, 100, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(32, (3, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(64, (3, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(500))
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(114))
model.add(layers.Activation('softmax'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.summary()
# In[20]:
train_datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
# In[21]:
train_generator = train_datagen.flow(X_train, Y_train, batch_size=batch_size)
test_generator = test_datagen.flow(X_test , Y_test, batch_size=batch_size)
print(train_generator)
# In[ ]:
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=3,
validation_data=test_generator,
validation_steps=nb_valivation_samples // batch_size
)
model.save_weights('model_weights.h5')
model.save('model_keras.h5')
and my test code
from keras.models import load_model
import cv2
from keras.applications.resnet50 import preprocess_input
import numpy as np
model = load_model('model_keras.h5')
img = cv2.imread('input_test.jpg')
if img is not None:
img = cv2.resize(img, (100,100), interpolation=cv2.INTER_CUBIC)
img = np.reshape(img,[1,100,100,3])
img = preprocess_input(img)
classes = model.predict_classes(img)
print(classes)
Replace binary_crossentropy with categorical_crossentropy like this:
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])

ValueError: Error when checking target: expected dense_2 to have shape (None, 2) but got array with shape (321, 3)

I want to create an image classifier using keras, and train it with a few example images. Then, i will be using pre-trained models and adding a few layers at the end, but first, i want to understand keras and CNNs.
My console prints the following error:
ValueError: Error when checking target: expected dense_2 to have shape
(None, 2) but got array with shape (321, 3)
Here is my code:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import sys
import time
import numpy as np
import cv2
import time
from PIL import Image
import keras
import glob
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD
from sklearn.preprocessing import LabelBinarizer
labels = ['buena', 'mala', 'otro']
def to_one_hot(labels, ys):
result = np.zeros((len(ys),len(labels)))
for i in range(result.shape[0]):
for j in range(result.shape[1]):
result[i,j] = int(ys[i] == labels[j])
return result
def build_dataset(labels):
num_classes = len(labels)
x = []
y = []
for label in labels:
for filename in (glob.glob('./tf_files/papas_fotos/'+label+'/*.jpg')):
img = cv2.imread(filename)
img = np.resize(img,(100,100, 3))
x.append(img)
y.append(label)
y = to_one_hot(labels, y)
# y = keras.utils.to_categorical(y, num_classes=3)
x = np.array(x)
x_train = x[20:]
y_train = y[20:]
x_test = x[:19]
y_test = y[:19]
print (x.shape, y.shape)
return x_train, y_train, x_test, y_test
model = Sequential()
# input: 100x100 images with 3 channels -> (100, 100, 3) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
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(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
x_train, y_train, x_test, y_test = build_dataset(labels)
model = load_model('thebestmodel.h5')
print (model)
model.fit(x_train, y_train, batch_size=32, epochs=20)
score = model.evaluate(x_test, y_test, batch_size=32)
model.save('thebestmodel.h5')
print (score)
What mistake am I making? I think that may be the size of my one hot encoded labels, but i can't make it work.
Thanks!
Although your code was fixed for this specific error, you're loading a saved model: model = load_model('thebestmodel.h5')
This is undoing everything before this line.

How can I predict bigger sized image if the model is trained on a smaller sized image using keras

I'm using the following keras code with tensorflow backend to classify the difference between dog and a cat. It is not predicting any image above 800x800 image. How can I predict or resize the image to predict an hd image.
Code to train:
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.preprocessing.image import load_img, img_to_array
from keras.models import model_from_json
from scipy.misc import imresize
# Initialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Convolution2D(32, 3, 3, input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Convolution2D(32, 3, 3, activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(
training_set,
samples_per_epoch=80,
nb_epoch=100,
validation_data=test_set,
nb_val_samples=2000
)
print(training_set.class_indices)
Code to predict:
from keras.models import model_from_json
json_file = open('model.json', 'r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
# load weights into new model
model.load_weights("model.h5")
# evaluate loaded model on test data
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
import shutil
import matplotlib.pyplot as plt
import requests
url = raw_input("Please enter the image url/link")
response = requests.get(url, stream=True)
with open('test.jpg', 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
from keras.preprocessing import image
import numpy as np
test = image.load_img('test.jpg')
test = image.img_to_array(test)
test = np.expand_dims(test, axis=0)
result = model.predict(test)
if result[0][0] == 1:
prediction = 'dog'
print prediction
else:
prediction = 'cat'
print prediction
According to the Keras docs you can just specify the target size using:
test = image.load_img('test.jpg', target_size=(224, 224))
see https://keras.io/applications/ for an example.