Keras: "local variable 'val_ins' referenced before assignment" - python

I'm training a basic image classifier with seven classes, and I'm getting a Python error in Fit which I can't find other people talking about.
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from PIL import Image
import numpy as np
import os
imageSide = 256
def buildAndTrainNetwork():
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (imageSide, imageSide, 3), activation = 'relu', data_format="channels_last"))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 7, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
labelList = [('CarHatchback', [1,0,0,0,0,0,0]), ('CarMinivan', [0,1,0,0,0,0,0]), ('CarPickup', [0,0,1,0,0,0,0]), ('CarSaloon', [0,0,0,1,0,0,0]), ('CarSmart', [0,0,0,0,1,0,0]), ('CarSports', [0,0,0,0,0,1,0]), ('CarVan', [0,0,0,0,0,0,1])]
train_data = []
train_labels = []
test_data = []
for label,labelData in labelList:
dir = "mlData/train/" + label
for img in os.listdir(dir):
path = os.path.join(dir, img)
img = Image.open(path)
img = img.convert('RGB')
img = img.resize((imageSide, imageSide), Image.ANTIALIAS)
img = np.array(img)
train_data.append(img)
train_labels.append(labelData)
for label,labelData in labelList:
dir = "mlData/test/" + label
for img in os.listdir(dir):
path = os.path.join(dir, img)
img = Image.open(path)
img = img.convert('RGB')
img = img.resize((imageSide, imageSide), Image.ANTIALIAS)
img = np.array(img)
test_data.append(img)
train_data = np.array(train_data)
test_data = np.array(test_data)
train_labels = np.array(train_labels)
print("Training shape:")
print(train_data.shape)
print("Train labels shape:")
print(train_labels.shape)
print("Testing shape:")
print(test_data.shape)
classifier.fit(
train_data,
train_labels,
steps_per_epoch=8000,
epochs=10,
validation_data=test_data,
validation_steps=800
)
#
buildAndTrainNetwork()
The error I receive is:
File
"/home/ian/.local/lib/python3.6/site-packages/keras/engine/training.py",
line 1034, in fit
val_ins=val_ins, UnboundLocalError: local variable 'val_ins' referenced before assignment
FYI, the shape output is:
Training shape:
(3502, 256, 256, 3)
Train labels shape:
(3502, 7)
Testing shape:
(3506, 256, 256, 3)
I'm assuming that I haven't formatted the input data correctly, but I'm struggling to see the actual error.

validation_data in classifier.fit should be a tuple with the test images (which you have) and the test labels, which you have but forgot to load.
for label,labelData in labelList:
dir = "mlData/test/" + label
for img in os.listdir(dir):
# ...
test_data.append(img)
test_labels.append(labelData) # add this
Then
classifier.fit(
validation_data=(test_data, test_labels)
# ...
)

Related

Training datasets from kagglecatcanddog, load datasets have some type BMP error

def process_path(img_path, label):
label = tf.one_hot(label, depth=class_num)
image = tf.io.read_file(img_path)
# image = tf.image.decode_bmp(image)
image = tf.image.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, [im_height, im_width])
return image, label
AUTOTUNE = tf.data.experimental.AUTOTUNE
# load train dataset
train_dataset = tf.data.Dataset.from_tensor_slices((train_image_list, train_label_list))
train_dataset = train_dataset.shuffle(buffer_size=train_num)\
.map(process_path, num_parallel_calls=AUTOTUNE).repeat().\
batch(batch_size).prefetch(AUTOTUNE)
# load val dataset
val_dataset = tf.data.Dataset.from_tensor_slices((val_image_list, val_label_list))
val_dataset = val_dataset.map(process_path, num_parallel_calls=AUTOTUNE)\
.repeat().batch(batch_size)
But when I try to find error, I did that:
for i, img in enumerate(train_dataset):
try:
if i==0:
break
print(img)
print('*********************',i,'***********************')
except Exception as e:
print(e)
print('0000000000000000',i,'0000000000000000')
I want to print the first items from 'train_dataset'.
It sometimes tip me false, sometimes I get no error
InvalidArgumentError: Trying to decode BMP format using a wrong op. Use decode_bmp or decode_image instead. Op used: DecodeJpeg
[[{{node DecodeJpeg}}]]
all of my codes
#!/usr/bin/env python
# coding: utf-8
# In[52]:
import matplotlib.pyplot as plt
from model import AlexNet_v1, AlexNet_v2
import tensorflow as tf
import json
import os
import time
import glob
import random
os.environ['CUDA_DEVICE_ORDER'] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
gpus = tf.config.experimental.list_physical_devices("GPU")
if gpus:
try:
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
except RuntimeError as e:
print(e)
exit(-1)
data_root = os.path.abspath(os.path.join(os.getcwd()))
image_path = os.path.join(data_root, 'datasets')
train_dir = os.path.join(image_path, 'train')
validation_dir = os.path.join(image_path, 'val')
assert os.path.exists(train_dir), "cannot find {}".format(train_dir)
assert os.path.exists(validation_dir), "cannot find {}".format(validation_dir)
# create direction for saving weights
if not os.path.exists('save_weights'):
os.makedirs('save_weights')
im_height = 224
im_width = 224
batch_size = 128
epochs = 10
# class dict
data_class = [cla for cla in os.listdir(train_dir) if os.path.isdir(os.path.join(train_dir, cla))]
class_num = len(data_class)
class_dict = dict((value, index) for index, value in enumerate(data_class))
# reverse value and key of dict
inverse_dict = dict((val, key) for key, val in class_dict.items())
json_str = json.dumps(inverse_dict, indent=4)
with open('class_indices.json', 'w') as json_file:
json_file.write(json_str)
# load train images list
train_image_list = glob.glob(train_dir + "/*/*.jpg")
random.shuffle(train_image_list)
train_num = len(train_image_list)
assert train_num > 0, "cannot find any .jpg file in {}".format(train_dir)
train_label_list = [class_dict[path.split(os.path.sep)[-2]] for path in train_image_list]
# load validation images list
val_image_list = glob.glob(validation_dir+'/*/*.jpg')
random.shuffle(val_image_list)
val_num = len(val_image_list)
assert train_num > 0, "cannot find any .jpg file in {}".format(validation_dir)
val_label_list = [class_dict[path.split(os.path.sep)[-2]] for path in val_image_list]
print("using {} images for training, {} images for validation.".format(train_num,
val_num))
def process_path(img_path, label):
label = tf.one_hot(label, depth=class_num)
image = tf.io.read_file(img_path)
# image = tf.image.decode_bmp(image)
image = tf.image.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, [im_height, im_width])
return image, label
AUTOTUNE = tf.data.experimental.AUTOTUNE
# load train dataset
train_dataset = tf.data.Dataset.from_tensor_slices((train_image_list, train_label_list))
train_dataset = train_dataset.shuffle(buffer_size=train_num) .map(process_path, num_parallel_calls=AUTOTUNE).repeat(). batch(batch_size).prefetch(AUTOTUNE)
# load val dataset
val_dataset = tf.data.Dataset.from_tensor_slices((val_image_list, val_label_list))
val_dataset = val_dataset.map(process_path, num_parallel_calls=AUTOTUNE) .repeat().batch(batch_size)
model = AlexNet_v1(im_height=im_height, im_width=im_width, num_classes=2)
model.summary()
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),
metrics=['accuracy'])
callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='./save_weights/myAlex_{epoch}.h5',
save_best_only=True,
save_weights_only=True,
monitor='val_loss')]
history = model.fit(x=train_dataset,
steps_per_epoch=train_num//batch_size,
epochs=epochs,
validation_data=val_dataset,
validation_steps=val_num//batch_size,
callbacks=callbacks)
history_dict = history.history
train_loss = history_dict['loss']
train_acc = history_dict['accuracy']
val_loss = history_dict['val_loss']
val_acc = history_dict['val_accuracy']
# figure 1
plt.figure()
plt.plot(range(epochs), train_loss, label = 'train_loss')
plt.plot(range(epochs), val_loss, label = 'val_loss')
plt.legend()
plt.xlabel('epochs')
plt.ylabel('loss')
# figure 2
plt.figure()
plt.plot(range(epochs), train_acc, label = 'train_acc')
plt.plot(range(epochs), val_acc, label = 'val_acc')
plt.legend()
plt.xlabel('epochs')
plt.ylabel('accuracy')
from tensorflow.keras import layers, models, Model, Sequential
def AlexNet_v1(im_height=224, im_width=224, num_classes=1000):
# tensorflow中的tensor通道排序是NHWC
input_image = layers.Input(shape=(im_height, im_width, 3), dtype="float32") # output(None, 224, 224, 3)
x = layers.ZeroPadding2D(((1, 2), (1, 2)))(input_image) # output(None, 227, 227, 3)
x = layers.Conv2D(48, kernel_size=11, strides=4, activation="relu")(x) # output(None, 55, 55, 48)
x = layers.MaxPool2D(pool_size=3, strides=2)(x) # output(None, 27, 27, 48)
x = layers.Conv2D(128, kernel_size=5, padding="same", activation="relu")(x) # output(None, 27, 27, 128)
x = layers.MaxPool2D(pool_size=3, strides=2)(x) # output(None, 13, 13, 128)
x = layers.Conv2D(192, kernel_size=3, padding="same", activation="relu")(x) # output(None, 13, 13, 192)
x = layers.Conv2D(192, kernel_size=3, padding="same", activation="relu")(x) # output(None, 13, 13, 192)
x = layers.Conv2D(128, kernel_size=3, padding="same", activation="relu")(x) # output(None, 13, 13, 128)
x = layers.MaxPool2D(pool_size=3, strides=2)(x) # output(None, 6, 6, 128)
x = layers.Flatten()(x) # output(None, 6*6*128)
x = layers.Dropout(0.2)(x)
x = layers.Dense(2048, activation="relu")(x) # output(None, 2048)
x = layers.Dropout(0.2)(x)
x = layers.Dense(2048, activation="relu")(x) # output(None, 2048)
x = layers.Dense(num_classes)(x) # output(None, 5)
predict = layers.Softmax()(x)
model = models.Model(inputs=input_image, outputs=predict)
return model

keras model.predict IndexError: list index out of range

I trained a keras model with my own images, and I have defined an output layer of 3 neurons, but when I try to predict an individual image using model.predict(img) it returns a value out of range, so in my network it should only output the values 0, 1 and 2, but it is outputting values like 4, 6, etc.
Here follows the network code:
from textwrap import indent
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import sys
import cv2 as cv
from tensorflow.keras import datasets, layers, models
def main(training_images, training_labels, test_images, test_labels, single_image=None):
#learnModel(training_images, training_labels, test_images, test_labels)
predictionModel(single_image)
def learnModel(training_images, training_labels, test_images, test_labels):
#define the model, train it and save it
model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(280, 400, 1)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64, (3,3), activation='relu')) #Convulotional layers filters images by their features (example: a cat has small legs)
model.add(layers.MaxPooling2D((2,2))) #Max Pooling layers filter the important information
model.add(layers.Conv2D(64, (3,3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(3, activation='softmax')) #Last layer
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=10, validation_data=(test_images, test_labels))
loss, accuracy = model.evaluate(test_images, test_labels)
print(f"Loss: {loss}")
print(f"Accuracy: {accuracy}")
model.save('retina_disease_classifier.model')
def predictionModel(single_image):
model = models.load_model('retina_disease_classifier.model') #This loads an already trained model
class_names = ['Healthy', 'Glaucomatous', 'Diabetic Retinopathy']
img = cv.imread(single_image)
img = np.array([img]).reshape(-1, 280, 400, 1) / 255
prediction = model.predict(img)
index = np.argmax(prediction)
print(f"Prediction is {class_names[index]}")
Here is the code where I build the traning data, labels and test data:
from PIL import Image
from os import listdir
from os.path import isfile, join
from matplotlib import image
from matplotlib.pyplot import show
from numpy import asarray, single
import numpy as np
import sys
import logging
import gzip
import convNetwork
imageDatasetPath = "./Dataset/"
singleImagePath = "./Dataset/34761_dr.jpg"
imageLength = 400
imageHeigth = 280
imagePixelNum = imageLength * imageHeigth
def main():
training_images = createTrainingImages(imageDatasetPath)
training_labels = createTrainingLabels(imageDatasetPath)
test_images= createTrainingImages(imageDatasetPath)
test_labels = createTrainingLabels(imageDatasetPath)
#convNetwork.main(training_images, training_labels, test_images, test_labels)
convNetwork.main(training_images, training_labels, test_images, test_labels, single_image=singleImagePath)
def createTrainingImages(imageDatasetPath):
files = [f for f in listdir(imageDatasetPath) if isfile(join(imageDatasetPath, f))]
training_images = []
for fileName in files:
imagePath = imageDatasetPath + fileName
training_images.append(convertImageArray(imagePath))
training_images = np.array(training_images).reshape(-1, imageHeigth, imageLength, 1)
return training_images
def createTrainingLabels(imageDatasetPath):
files = [f for f in listdir(imageDatasetPath) if isfile(join(imageDatasetPath, f))]
training_labels = []
for fileName in files:
imagePath = imageDatasetPath + fileName
training_labels.append(getDiseaseType(fileName))
training_labels = np.reshape(training_labels, (len(training_labels), 1))
return training_labels
def convertImageArray(imagePath):
image = Image.open(imagePath)
# convert image to numpy array
data = asarray(image)
#data = np.reshape(data, (imagePixelNum, 1))
data = data / 255
return data
def getDiseaseType(imageName):
condition = imageName.split('.')[0]
condition = condition.split('_')[1]
if(condition == "h"):
return 0
elif(condition == "g"):
return 1
elif(condition == "dr"):
return 2
else:
logging.error("Invalid Input")
main()
This is the error that I get:
File "./convNetwork.py", line 76, in predictionModel
print(f"Prediction is {class_names[index]}")
IndexError: list index out of range
From what I understand the number of output neurons is defined in this way:
model.add(layers.Dense(3, activation='softmax'))
So, I dont understand how it is returning more outputs than the maximum defined.

Detecting multiply forms on one image

I made a convolutional neural network, have trained the model, and now it can accurately determine the form that is on the photo.
But now I need to make sure that it determines all the forms that are in one photo. So I need to somehow cut the original photo into parts, and then identify each.
What is the best way to do it? I am using Python3, keras. Learning and recognition code:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from keras.models import Sequential
from keras.layers.core import Dense, Flatten
from keras.layers import Dropout
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import to_categorical
from keras.optimizers import SGD
from keras.models import load_model
from imutils import paths
matplotlib.use ("Agg")
categories = ['bread', 'chicken', 'cucumbers', 'dry_peas', 'eggs',
              'green_peas', 'kolbasa', 'potato', 'raw_beef',
              'spaghetti', 'tomatoes']
dataset = "ingredients"
model_path = "test_model.model"
label_bin = "test_model.pickle"
plot = "output / test_model_plot.png"
print ("[INFO] loading images ...")
data = []
labels = []
imagePaths = sorted (list (paths.list_images (dataset)))
random.seed (42)
random.shuffle (imagePaths)
for imagePath in imagePaths:
    try:
        image = cv2.imread (imagePath)
        image = cv2.resize (image, (32, 32))
        data.append (image / 255)
        label = imagePath.split (os.path.sep) [- 2]
        labels.append (categories.index (label))
    except Exception as e:
        print ("[WARNING]", e)
data = np.array (data)
print (labels)
labels = to_categorical (np.array (labels))
print (labels)
(trainX, testX, trainY, testY) = train_test_split (data, labels,
                                                  test_size = 0.2,
                                                  random_state = 42)
lb = LabelBinarizer ()
trainY = lb.fit_transform (trainY)
testY = lb.transform (testY)
'' '
model = Sequential ()
model.add (Conv2D (32, (3, 3), activation = 'relu', input_shape = (32, 32, 3)))
model.add (MaxPooling2D ((2, 2)))
model.add (Conv2D (64, (3, 3), activation = 'relu'))
model.add (MaxPooling2D ((2, 2)))
model.add (Flatten ())
model.add (Dropout (0.5))
model.add (Dense (512, activation = "sigmoid"))
model.add (Dense (len (lb.classes_), activation = "softmax"))
'' '
model = load_model ('test_model.model')
INIT_LR = 0.01
EPOCHS = 150
print ("[INFO] training network ...")
opt = SGD (lr = INIT_LR)
model.compile (loss = "categorical_crossentropy", optimizer = opt,
              metrics = ["accuracy"])
H = model.fit (trainX, trainY, validation_data = (testX, testY),
              epochs = EPOCHS, batch_size = 32)
print ("[INFO] evaluating network ...")
predictions = model.predict (testX, batch_size = 32)
print (predictions)
#print (classification_report (testY.argmax (axis = 1)
# predictions.argmax (axis = 1), target_names = lb.classes_))
N = np.arange (0, EPOCHS)
plt.style.use ("ggplot")
plt.figure ()
print (H.history.keys ())
plt.plot (N, H.history ["loss"], label = "train_loss")
plt.plot (N, H.history ["val_loss"], label = "val_loss")
plt.plot (N, H.history ["accuracy"], label = "train_acc")
plt.plot (N, H.history ["val_accuracy"], label = "val_acc")
plt.title ("Training Loss and Accuracy (Simple NN)")
plt.xlabel ("Epoch #")
plt.ylabel ("Loss / Accuracy")
plt.legend ()
plt.savefig (plot)
print ("[INFO] serializing network and label binarizer ...")
model.save (model_path)
f = open (label_bin, "wb")
f.write (pickle.dumps (lb))
f.close ()
and
import argparse
import pickle
import cv2
import flask
import werkzeug
from keras.models import load_model
import keras
import tensorflow as tf
import keras.backend.tensorflow_backend as tb
from tensorflow.python.keras.backend import set_session
from tensorflow.python.keras.models import load_model
import sys
sys.modules['keras'] = keras
class FoodRecognizer:
def __init__(self, model, label_bin, size, flatten):
self.label_bin = label_bin
self.size = size
self.width, self.height = self.size
self.flatten = flatten
print("[INFO] loading network and label binarizer...")
set_session(sess)
self.model = load_model(model)
self.lb = pickle.loads(open(self.label_bin, "rb").read())
def load_image(self, image_file):
image = cv2.imread(image_file)
output = image.copy()
image = cv2.resize(image, self.size)
image = image / 255.0
image = image.reshape(1, *image.shape)
self.image = image
def recognize(self):
preds = self.model.predict(self.image)
result = list(preds[0])
for i in range(len(result)):
print(categories[i].ljust(10, " "), result[i], sep='\t')
i = preds.argmax(axis=1)[0]
print()
out = sorted(result)[-3:][::-1]
print("Скорее всего, на фотографии:")
for o in out:
print(categories[result.index(o)], f"{round(o * 100, 2)}%")
label = self.lb.classes_[i]
return label
app = flask.Flask(__name__)
#app.route('/', methods=['POST'])
def handle_request():
print(flask.request.files.to_dict())
imagefile = flask.request.files['image']
filename = werkzeug.utils.secure_filename(imagefile.filename)
print("\nReceived image File name : " + imagefile.filename)
imagefile.save('images/' + str(filename))
MFR.load_image('images/' + filename)
print(MFR.image)
print('images/' + filename)
with graph.as_default():
set_session(sess)
result = MFR.recognize()
print(result)
return categories[result]
categories = ['bread', 'chicken', 'cucumbers', 'dry_peas', 'eggs',
'green_peas', 'kolbasa', 'potato', 'raw_beef',
'spaghetti', 'tomatoes']
if __name__ == "__main__":
model_path = "test_model.model"
label_path = "test_model.pickle"
size = (32, 32)
flatten = 1
sess = tf.Session()
graph = tf.get_default_graph()
MFR = FoodRecognizer(model_path, label_path, size, flatten)
#MFR.load_image("images/test_image.jpg")
#print(categories[MFR.recognize()])
set_session(sess)
app.run(host='10.61.4.238', debug=True, threaded=False)
I think you are refering to image segmentation, check out this article to find out more information.
In short, it is similar to classification but instead of giving one class it draws bounding boxes around the detected objects.

Can't train model for hand gesture (ASL) by using CNN

I've successfully distinguish dog and cat by using CNN, now I am trying to train model for (ASL) American Sign Language, I made some changes but not worked and now I've no idea what to change in code and which way and also I google for this but unfortunately didn't worked, this is my FYP- (Final Year Project) and I am stuck, please help me.
I changed loss = binary_crossentropy to loss = sparse_categorical_crossentropy and but still showing label error.
1 class Data_preprocessing:
'Data preprocessing before goes to ML'
# Train by data list initilization
training_data = []
def __init__(self, datadir, categories, img_size):
Data_preprocessing.img_size = img_size
Data_preprocessing.datadir = datadir
Data_preprocessing.categories = categories
def Create_training_data(self):
for category in Data_preprocessing.categories:
# path to cats or dogs dir
path = os.path.join(Data_preprocessing.datadir, category)
class_num = Data_preprocessing.categories.index(category)
# After having the directory for images
# Started to read image by using OpenCv and directly convert it to GRAYSCALE
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, (Data_preprocessing.img_size, Data_preprocessing.img_size))
Data_preprocessing.training_data.append([new_array, class_num])
except Exception as e:
pass
self.Saving_processed_data()
def Saving_processed_data(self):
random.shuffle(Data_preprocessing.training_data)
x = []
y = []
for features, label in Data_preprocessing.training_data:
x.append(features)
y.append(label)
x = np.array(x).reshape(-1, Data_preprocessing.img_size, Data_preprocessing.img_size, 1)
# Saving data by using "pickle"
pickle_out = open("x.pickle", "wb")
pickle.dump(x, pickle_out)
pickle_out.close()
pickle_out = open("y.pickle", "wb")
pickle.dump(y, pickle_out)
pickle_out.close()
categories = ["Dog","Cat"]
categories = ["A","B","C","D","del","E","F","G","H","I","J","K","L","M","N","nothing","O","P","Q","R","S","space","T","U","V","W","X","Y","Z"]
data_preprocessing = Data_preprocessing("ASLDS\\ASLDS",categories, 50)
data_preprocessing.Create_training_data()
2 class Learning_model:
def __init__(self):
pass
def TrainModel(self):
self.x = pickle.load(open("x.pickle", "rb"))
self.y = pickle.load(open("y.pickle", "rb"))
self.x = self.x/255.0
self.model = Sequential()
self.model.add(Conv2D(64, (3,3), input_shape = self.x.shape[1:]))
self.model.add(Activation("relu"))
self.model.add(MaxPooling2D(pool_size=(2,2)))
self.model.add(Conv2D(64, (3,3)))
self.model.add(Activation("relu"))
self.model.add(MaxPooling2D(pool_size=(2,2)))
self.model.add(Flatten())
self.model.add(Dense(64))
self.model.add(Dense(1))
self.model.add(Activation('sigmoid'))
self.model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
self.model.fit(self.x, self.y, batch_size = 32, epochs=10, validation_split = 0.1)
self.model.save("64x3-CNN-ASL.model")
trained_model = Learning_model()
trained_model.TrainModel()
I am expecting that if I input an image of any alphabet so it is supposed to show me corresponding name of that alphabet.
You should change loss to categorical cross entropy. Even I built a similar CNN with Keras.
This CNN is built to recognize 3 different types of images, but you can change input_shape to detect any number of categories.
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# Initialising the CNN
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 3, activation = 'softmax')) # output layer
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
# Using the CNN on 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 = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
classifier.fit_generator(training_set,
steps_per_epoch = (8000/32),
epochs = 25,
validation_data = test_set,
validation_steps = (2000/32))
# Fetching Predictions
import numpy as np
from skimage.io import imread
from skimage.transform import resize
class_labels = {v: k for k, v in training_set.class_indices.items()}
img = imread('dataset/single_prediction/random.jpg')
img = resize(img,(64,64))
img = np.expand_dims(img,axis=0)
if(np.max(img)>1):
img = img/255.0
prediction = classifier.predict_classes(img)
print ("\n\n")
print (class_labels[prediction[0]])

keras CNN same output

I have trained a CNN neural network in python with 800 samples and tested it on 60. The output accuracy is 50 and now every time I use model.predict it gives me the same result.
#main file - run this to train the network
import numpy as np
from keras.datasets import cifar10
from datasetFetch import DataFetch
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.constraints import maxnorm
from keras.optimizers import SGD
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')
import simplejson
from matplotlib import pyplot
from scipy.misc import toimage
# load data
#(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# create a grid of 3x3 images
#for i in range(0, 9):
# pyplot.subplot(3,3,1 + i)
# pyplot.imshow(toimage(X_train[i]))
# show the plot
#pyplot.show()
#init data
CONST_PHOTOS = 400 # number of photos of each type
y_train = []
#train data
data = DataFetch('orange',CONST_PHOTOS)
data1 = data.openPictures()
data = DataFetch('apple', CONST_PHOTOS)
data.removeErrorImages()
data2 = data.openPictures()
#test data
tdata = DataFetch('test-orange',30)
tdata1 = tdata.openPictures()
tdata = DataFetch('test-apple',30)
tdata2 = tdata.openPictures()
#add togheter data
X_train = data.connectData(data1,data2,'train')
y_train = data.getYtrain('train')
X_test = tdata.connectData(tdata1,tdata2,'test')
y_test = tdata.getYtrain('test')
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# normalize inputs from 0-255 to 0.0-1.0
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train = X_train / 255.0
X_test = X_test / 255.0
#one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_train.shape[1] #number of categories
# Create the model
model = Sequential()
model.add(Conv2D(224, (11, 11), input_shape=(224, 224, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(55, (5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_last"))
model.add(Conv2D(13, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.5))
model.add(Conv2D(13, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), data_format="channels_last"))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
epochs = 100
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
#print(model.summary())
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=10)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))
#and then we save
# serialize model to JSON
model_json = model.to_json()
with open("Data/model.json", "w") as json_file:
json_file.write(simplejson.dumps(simplejson.loads(model_json), indent=4))
# serialize weights to HDF5
model.save_weights("Data/model.h5")
print("Saved model to disk")
I used keras and tensorflow. Images are 224x224 pixels each split in 2 categories. I don't know very much about neural network, this being my first attempt to making one this big work. I heard it might be over fitting or maybe I need one more important layer, or maybe my batch-size/epochs/learn rate is wrong.
Any help is appreciated!
Edit1: How is the seed affecting the training of the network?
After training the accuracy is exactly 50% and by using a separate .py file which only loads the model and uses predict function on it returns the exact output percentage for any image I use. I tried with both images used for training and external ones.
I added the dataFetch code.
#preparing the photos to be 224x224 and getting them from urls saved in txt files
from PIL import Image
import requests
from io import BytesIO
import numpy as np
import socket
import random
from scipy import misc
from PIL import ImageChops
import math, operator
from functools import reduce
import glob
import os
import signal
compare = Image.open('/home/mihai/PycharmProjects/neuralnet/compare.jpg')
compare1 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare1.jpg')
compare2 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare2.jpg')
compare3 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare3.jpg')
compare4 = Image.open('/home/mihai/PycharmProjects/neuralnet/compare4.jpg')
def rmsdiff(im1, im2):
"Calculate the root-mean-square difference between two images"
h = ImageChops.difference(im1, im2).histogram()
# calculate rms
return math.sqrt(reduce(operator.add, map(lambda h, i: h*(i**2), h, range(256))) / (float(im1.size[0]) * im1.size[1]))
class DataFetch:
chosenFile = ''
maxNumber = 0
y_train = []
y_test = []
def __init__(self, choice, number):
print('Images with '+choice+'s are being prepared')
self.chosenFile = choice
self.maxNumber = number
def getPictures(self):
imgArr = np.zeros((self.maxNumber, 224, 224, 3), dtype='uint8')
count = 0
class timeoutError(Exception):
signal.alarm(0)
def handler(signum, frame):
raise timeoutError
with open(self.chosenFile, "r") as ins:
for line in ins:
if count < self.maxNumber:
signal.signal(signal.SIGALRM, handler)
signal.alarm(3)
try:
try:
r = requests.get(line)
try:
img = Image.open(BytesIO(r.content))
ok = 0
try:
if rmsdiff(compare, img) > 1.3 and rmsdiff(compare1, img) > 1.3 and rmsdiff(compare2, img) > 1.3 and rmsdiff(compare3, img) > 1.3 and rmsdiff(compare4, img) > 1.3:
ok = 1
else:
print('Image removed from website')
except ValueError:
ok = 1
if ok == 1:
img = img.resize((224, 224))
img = img.convert('RGB')
img.save('/home/mihai/PycharmProjects/neuralnet/images/'+self.chosenFile+'/'+str(count)+".jpg", 'JPEG')
imgArr[count, :, :, :] = img
count = count + 1
print(count)
except OSError:
print('Image not Available')
except socket.error:
print('URL not available')
except timeoutError:
print("URL not available")
return imgArr
def openPictures(self):
cdir = os.getcwd()
imgArr = np.zeros((self.maxNumber, 224, 224, 3), dtype='uint8')
count = 0
for filename in glob.glob(cdir+'/images/'+self.chosenFile+'/*.jpg'):
if count < self.maxNumber:
img = Image.open(filename)
imgArr[count, :, :, :] = img
count = count + 1
return imgArr
def removeErrorImages(self):
cdir = os.getcwd()
for filename in glob.glob(cdir+'/images/'+self.chosenFile+'/*.jpg'):
img = Image.open(filename)
try:
if rmsdiff(compare, img) < 1.3 or rmsdiff(compare1, img) < 1.3 or rmsdiff(compare2, img) < 1.3 or rmsdiff(compare3, img) < 1.3 or rmsdiff(compare4, img) < 1.3:
os.remove(cdir+'/images/'+self.chosenFile+'/'+filename+'.jpg')
except ValueError:
pass
def getYtrain(self,outParam):
if outParam == 'train':
self.y_train = np.reshape(self.y_train, (len(self.y_train), 1))
return self.y_train
else:
self.y_test = np.reshape(self.y_test, (len(self.y_test), 1))
return self.y_test
def connectData(self, data1, data2, outParam):
d1c = 0
d2c = 0
outList = []
X_train = np.zeros((2 * self.maxNumber, 224, 224, 3), dtype='uint8')
for i in range(2 * self.maxNumber):
if d1c < self.maxNumber and d2c <self.maxNumber:
if random.random() <= 0.5:
X_train[d1c + d2c, :, :, :] = data1[d1c, :, :, :]
d1c = d1c + 1
outList.append(0)
else:
X_train[d1c + d2c, :, :, :] = data2[d2c, :, :, :]
d2c = d2c + 1
outList.append(1)
else:
if d1c < self.maxNumber:
X_train[d1c + d2c, :, :, :] = data1[d1c, :, :, :]
d1c = d1c + 1
outList.append(0)
else:
if d2c < self.maxNumber:
X_train[d1c + d2c, :, :, :] = data2[d2c, :, :, :]
d2c = d2c + 1
outList.append(1)
if outParam == 'train':
self.y_train = outList
else:
if outParam == 'test':
self.y_test = outList
return X_train
Code for predict:
#run this to test a sample
from keras.utils import np_utils
from keras.models import model_from_json
from keras.optimizers import SGD
from datasetFetch import DataFetch
# load json and create model
json_file = open('Data/model2.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# load weights into new model
loaded_model.load_weights("Data/model2.h5")
print("Loaded model from disk")
epochs = 100
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
loaded_model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
#prepare X_test
tdata = DataFetch('test-orange',int(3))
tdata1 = tdata.openPictures()
tdata = DataFetch('test-apple',int(3))
tdata2 = tdata.openPictures()
X_test = tdata.connectData(tdata1,tdata2,'test')
y_test = tdata.getYtrain('test')
X_test = X_test.astype('float32')
X_test = X_test / 255.0
y_test = np_utils.to_categorical(y_test)
print('Number of samples to be tested: '+str(X_test.shape[0]))
scores = loaded_model.evaluate(X_test, y_test, verbose=0)
print(scores[1]*100)
score = loaded_model.predict(X_test,batch_size=6, verbose=1)
print(score) #prints percentages
The image preparation was correct. The problem was in the structure of the neural net plus the optimization method used.
Because of the huge number of neurons used for classifying just 2 classes, the structure was over fitting, causing the accuracy to stick at 50%.
The second problem was with the sgd optimizer. I instead used:
opt=keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy']
Hope this helps others as well!

Categories