I am beginner in machine learning. I am making a CNN model using keras to detect pest from leaf image. During training the data, memory exceed and I was unable to train. I have used kaggle/Google Collab but in both I have memory probelm.
I was suggested to use Data Generator, but while trying to do, I was unable to do. Is there any other way to efficiently train or any example whether data generator is used(Have seen many examples but have problem while adding.
import numpy as np
import pickle
import cv2
from os import listdir
from sklearn.preprocessing import LabelBinarizer
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation, Flatten, Dropout, Dense
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
from keras.preprocessing import image
from keras.preprocessing.image import img_to_array
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
EPOCHS = 25
INIT_LR = 1e-3
BS = 32
default_image_size = tuple((256, 256))
image_size = 0
directory_root = 'PlantVillage/'
width=256
height=256
depth=3
#Function to convert images to array
def convert_image_to_array(image_dir):
try:
image = cv2.imread(image_dir)
if image is not None:
image = cv2.resize(image,default_image_size)
return img_to_array(image)
else:
return np.array([])
except Exception as e:
print(f"Error : {e}")
return None
image_list, label_list = [], []
try:
print("[INFO] Loading images ...")
root_dir = listdir(directory_root)
#Looping inside root_directory
for directory in root_dir :
# remove .DS_Store from list
if directory == ".DS_Store" :
root_dir.remove(directory)
for plant_folder in root_dir :
plant_disease_folder_list = listdir(f"{directory_root}/{plant_folder}")
print(f"[INFO] Processing {plant_folder} ...")
#looping in images
for disease_folder in plant_disease_folder_list :
# remove .DS_Store from list
if disease_folder == ".DS_Store" :
plant_disease_folder_list.remove(plant_folder)
#If all data taken not able to train
for images in plant_disease_folder_list:
image_directory = f"{directory_root}/{plant_folder}/{images}"
if image_directory.endswith(".jpg") == True or image_directory.endswith(".JPG") == True:
image_list.append(convert_image_to_array(image_directory))
label_list.append(plant_folder)
print("[INFO] Image loading completed")
except Exception as e:
print(f"Error : {e}")
#Get Size of Processed Image
image_size = len(image_list)
#Converting multi-class labels to binary labels(belong or doesnot belong in the class)
label_binarizer = LabelBinarizer()
image_labels = label_binarizer.fit_transform(label_list)
#Saving label binarizer instance using pickle
pickle.dump(label_binarizer,open('label_transform.pkl','wb'))
n_classes = len(label_binarizer.classes_)
print(label_binarizer.classes_)
#Normalizing image from [0,255] to [0,1]
np_image_list = np.array(image_list, dtype = np.float)/255.0
#Splitting data into training and test set 80:20
print('Splitting data to train,test')
x_train, x_test, y_train, y_test = train_test_split(np_image_list, image_labels, test_size=0.2, random_state = 42)
#Creating image generator object which performs random rotations, shifs,flips,crops,sheers
aug = ImageDataGenerator(
rotation_range = 25, width_shift_range=0.1,
height_shift_range=0.1, shear_range=0.2,
zoom_range=0.2, horizontal_flip = True,
fill_mode="nearest")
model = Sequential()
inputShape = (height, width, depth)
chanDim = -1
if K.image_data_format() == "channels_first":
inputShape = (depth, height, width)
chanDim = 1
model.add(Conv2D(32, (3, 3), padding="same",input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(64, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(128, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(32))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(n_classes))
model.add(Activation("softmax"))
#model.summary()
#Compiling the CNN
opt = Adam(lr= INIT_LR, decay= INIT_LR/EPOCHS)
#distribution
model.compile(loss="binary_crossentropy", optimizer = opt, metrics=["accuracy"])
#training the Model
print("Training Model.....")
history = model.fit_generator(
aug.flow(x_train, y_train, batch_size= BS),
validation_data = (x_test, y_test),
steps_per_epoch = len(x_train) // BS,
epochs = EPOCHS, verbose = 1
)
You find code in this link too.
The problem here is that you have loaded the complete data in the workspace, which fills lots of memory and create lots of extra load on the processes.
One thing you can used is data-generator with flow_from_directory, which allows you to define the augmentation and pre-processing pipeline along with data on the fly. The advantage here is that workspace doesn't have extra load of data. You can find an example here.
Feel free to ask question.
You can convert images into binary format which is understandable by tensorflow called "tfrecord" format.
Please refer to the below links
https://www.tensorflow.org/guide/datasets http://www.machinelearninguru.com/deep_learning/tensorflow/basics/tfrecord/tfrecord.html
Related
Objective: Classify whether a cell is parasitic(malria-ed) or uninfected
Dataset is from Kaggle: https://www.kaggle.com/iarunava/cell-images-for-detecting-malaria
Imports:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
from sklearn.metrics import classification_report, confusion_matrix
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, MaxPool2D, Conv2D, Flatten
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from matplotlib.image import imread
Paths:
file_path = "/whatever-you-store-the-data/cell_images/"
test_path = "/whatever-you-store-the-data/cell_images/test/"
train_path = "/whatever-you-store-the-data/cell_images/train/"
The average size of an image is (130, 130, 3) # (width, height, colour_channels):
image_shape = (130, 130, 3)
ImageDataGenerator:
image_gen = ImageDataGenerator(rotation_range=20,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
zoom_range=0.1,
horizontal_flip=True,
vertical_flip=True,
fill_mode="nearest")
The Model:
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=image_shape, activation="relu"))
model.add(MaxPool2D((2, 2)))
model.add(Dropout(0.5))
model.add(Conv2D(64, (3, 3), activation="relu"))
model.add(MaxPool2D((2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(64, (3, 3), activation="relu"))
model.add(MaxPool2D((2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(1, activation="sigmoid"))
model.compile(loss="binary_crossentropy",
optimizer="adam",
metrics=["accuracy"])
EarlyStopping Callback:
early_stop = EarlyStopping(monitor="val_loss",
patience=5,
verbose=1,
mode="min")
Generators:
train_image_gen = image_gen.flow_from_directory(train_path,
target_size=image_shape[:2],
color_mode="rgb",
batch_size=32,
class_mode="binary")
test_image_gen = image_gen.flow_from_directory(test_path,
target_size=image_shape[:2],
color_mode="rgb",
batch_size=32,
class_mode="binary",
shuffle=False)
Fitting the model:
results = model.fit_generator(train_image_gen,
epochs=20,
validation_data=test_image_gen,
callbacks=[early_stop])
Here is the output:
Epoch 1/20
390/Unknown - 9339s 24s/step - loss: 4.4232 - accuracy: 0.5135
First of all why is it in the form of n/Unknown, more importantly, why is it taking 9339s. That is not the problem, the problem lies in why the estimated time of training keeps on increasing, it began at somewhere around 240s, it then increases with time until it eventually reached 9339s. What is happening here and how do I solve this?
I have a simple sequential deep model as below, which performs a binary classification. I pass the 3 color channels of my dataset images to the model for training. How can I add grayscale as the 4th channel to my model? What changes do I need to make?
from keras.models import Sequential, load_model, Model
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from PIL import Image
from random import shuffle, choice
import numpy as np
import os
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from keras import optimizers
IMAGE_SIZE = 300
epochs_num = 100
batch_size = 64
IMAGE_DIRECTORY = './data'
def label_img(name):
if name == 'fire': return np.array([1, 0])
elif name == 'none' : return np.array([0, 1])
def load_data():
print("Loading images...")
train_data = []
directories = next(os.walk(IMAGE_DIRECTORY))[1]
for dirname in directories:
print("Loading {0}".format(dirname))
file_names = next(os.walk(os.path.join(IMAGE_DIRECTORY, dirname)))[2]
for i in range(len(file_names)):
image_name = choice(file_names)
image_path = os.path.join(IMAGE_DIRECTORY, dirname, image_name)
label = label_img(dirname)
if "DS_Store" not in image_path:
img = Image.open(image_path)
img = img.resize((IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
train_data.append([np.array(img), label])
shuffle(train_data)
return train_data
def create_model():
model = Sequential()
model.add(Conv2D(32, kernel_size = (5, 5), activation='relu', input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(128, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(128, activation='relu'))
model.add(Dense(2, activation = 'softmax'))
return model
training_data = load_data()
training_images = np.array([i[0] for i in training_data])
training_labels = np.array([i[1] for i in training_data])
print(str(len(training_images)))
# Split the data
training_images, validation_images, training_labels, validation_labels = train_test_split(training_images, training_labels, test_size=0.2, shuffle= True)
print(str(len(training_images)))
print('creating model')
#========================
model = create_model()
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
filepath="./checkpoints/model_{epoch:03d}_{accuracy:.4f}_{val_accuracy:.4f}_{val_loss:.7f}.h5"
checkpoint = ModelCheckpoint(filepath, monitor=["accuracy"], verbose=1, mode='max', save_weights_only=False)
callbacks_list = [checkpoint]
datagen = ImageDataGenerator(zoom_range=0.2, horizontal_flip=True)
datagen.fit(training_images)
train_gen=datagen.flow(training_images, training_labels, batch_size=batch_size)
#validation
val_datagen = ImageDataGenerator(horizontal_flip=True)
val_datagen.fit(training_images)
val_gen=datagen.flow(validation_images, validation_labels, batch_size=batch_size)
model.fit(train_gen, validation_data=val_gen, epochs=epochs_num, verbose=1, callbacks=callbacks_list)
i dont't think that you need to add gray scale and i 'm not sure if you can "add" it as an extra channel. Gray scale image is an image that RGB values are the same on the same pixel. You can train your classifier to classify gray scale images or coloured ones or both (not recommended). But if your raw data is coloured images keep them as they are and use data augmentation if you need more.
I am trying to predict a digit by using a keras example, when i trained my model everything is fine and the accuracy of test data is very good, but when i want to predict a digit i have some problem with the match of dimensions , i tryed to change the dimension of the digit but it still the same error .
here is my code :
main.py:
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.optimizers import Adam
from keras.layers.convolutional import MaxPooling2D
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
from keras import backend as K
# Read training and test data files
train = pd.read_csv("C:/Users/GOT/Desktop/Arabic Handwritten Digits Dataset CSV/csvTrainImages 60k x 784.csv").values
test = pd.read_csv("C:/Users/GOT/Desktop/Arabic Handwritten Digits Dataset CSV/csvTestImages 10k x 784.csv").values
train_label = pd.read_csv("C:/Users/GOT/Desktop/Arabic Handwritten Digits Dataset CSV/csvTrainLabel 60k x 1.csv").values
test_label = pd.read_csv("C:/Users/GOT/Desktop/Arabic Handwritten Digits Dataset CSV/csvTestLabel 10k x 1.csv").values
print(train.shape)
#Reshape and normalize training data
trainX = train[:, 0:].reshape(train.shape[0],1,28, 28).astype( 'float32' )
X_train = trainX / 255.0
y_train = train_label[:, 0]
# print(y_train.shape)
#Reshape and normalize test data
testX = test[:,0:].reshape(test.shape[0],1, 28, 28).astype( 'float32' )
X_test = testX / 255.0
y_test = test_label[:,0]
# print(y_test.shape)
#one hot encode
from keras.utils import np_utils
number_of_classes = 10
y_train = np_utils.to_categorical(y_train, number_of_classes)
y_test = np_utils.to_categorical(y_test, number_of_classes)
model = Sequential()
K.set_image_dim_ordering('th')
model.add(Conv2D(30, 5, 5, border_mode= 'valid' , input_shape=(1, 28, 28),activation= 'relu' ))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(15, 3, 3, activation= 'relu' ))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation= 'relu' ))
model.add(Dense(50, activation= 'relu' ))
model.add(Dense(10, activation= 'softmax' ))
# # Compile model
model.compile(loss= 'categorical_crossentropy' , optimizer= 'adam' , metrics=[ 'accuracy' ])
model.fit(X_train, y_train,
epochs=20,
batch_size= 160)
model.summary()
model.save('modelRasool.h5')
score = model.evaluate(X_test, y_test, batch_size=128)
print("The Accuracy and the Loss :")
print(score)
teset_predict.py
from keras.models import load_model
from PIL import Image
import numpy as np
model = load_model('C:/Users/GOT/PycharmProjects/test/modelRasool.h5')
for index in range(2):
img = Image.open('data/' + str(index) + '.png').convert("L")
img = img.resize((28,28))
im2arr = np.array(img)
im2arr = im2arr.reshape(1,28,28,1)
# Predicting the Test set results
y_pred = model.predict(im2arr)
print(y_pred)
the Error :
ValueError: Error when checking input: expected conv2d_1_input to have shape (1, 28, 28) but got array with shape (28, 28, 1)
please help me
it's easy your shape input need be (1 ,1 28,28)
im2arr = np.array(img)
im2arr = im2arr.reshape(1,1,28,28)
I'm trying to do deployment from Keras to opencv c++.
I trained a simple CNN with the mnist dataset (my example is a modified Keras example). After training I exposed tensorflow graph from Keras backend and saved the model and the graph.
tensorFlowSession = K.get_session()
tf.saved_model.simple_save(tensorFlowSession, newpath + "/TensorFlow", inputs={"x": x}, outputs={"y": y})
tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow", "trainGraph_def.pbtxt")
Then I tried to load the saved model using opencv in python, I started with opencv in python, however I experience a similar error using opencv in c++.
net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
The problem is the opencv failed to load tensorflow graph, I get an error-
[libprotobuf ERROR /io/opencv/3rdparty/protobuf/src/google/protobuf/wire_format_lite.cc:629] String field 'tensorflow.FunctionDef.Node.ret' contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes.
Saving and loading a tensorflow graph using opencv should be rather straightforward, what am I missing here? See attached my code.
'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''
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 tensorflow as tf
import datetime
import cv2 as cv
from pathlib import Path
import numpy as np
from os import listdir
from os.path import isfile, join
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
batch_size = 128
num_classes = 10
epochs = 1
# input image dimensions
img_rows, img_cols = 28, 28
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
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)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
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'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# Save as tensor flow graph
# Save the model to pd file
exportModelDir = '/home/iaiai/Documents/Shahar/DataSets/TrainedNetworks/MnistKeras/'
newpath = exportModelDir + str(datetime.datetime.now())
print ("output dir", newpath)
if not os.path.exists(newpath):
os.makedirs(newpath)
x = tf.placeholder(dtype=tf.float32, shape=input_shape)
y = tf.placeholder(dtype=tf.float32, shape=num_classes)
tensorFlowSession = K.get_session()
tf.saved_model.simple_save(tensorFlowSession, newpath + "/TensorFlow", inputs={"x": x}, outputs={"y": y})
# with tf.Session() as sess:
# tf.train.Saver(tf.trainable_variables()).save(sess, newpath + "/TensorFlow/" + 'saveTrainableVariables')
if not os.path.exists(newpath + "/TensorFlow/" + 'saveTrainableVariables/'):
os.makedirs(newpath + "/TensorFlow/" + 'saveTrainableVariables/')
tf.train.Saver(tf.trainable_variables()).save(tensorFlowSession, newpath + "/TensorFlow/saveTrainableVariables/" + 'saveTrainableVariables')
# Write graph in tensorflow format
tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow", "trainGraph_def.pbtxt")
tf.train.write_graph(tensorFlowSession.graph,newpath + "/TensorFlow", "trainGraph.pbtxt")
tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow", "trainGraph_def_notAsText.pbtxt", False)
# now try to load the tensorflow graph from opencv python module
net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
here is the full error message
[libprotobuf ERROR /io/opencv/3rdparty/protobuf/src/google/protobuf/wire_format_lite.cc:629] String field 'tensorflow.FunctionDef.Node.ret' contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes.
Traceback (most recent call last):
File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1664, in <module>
main()
File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1658, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1068, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/snap/pycharm-community/79/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/home/iaiai/Documents/Shahar/Project2/MnistKerasExport/mnist_cnn.py", line 106, in <module>
net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
cv2.error: OpenCV(3.4.2) /io/opencv/modules/dnn/src/tensorflow/tf_io.cpp:44: error: (-2:Unspecified error) FAILED: ReadProtoFromBinaryFile(param_file, param). Failed to parse GraphDef file: /home/iaiai/Documents/Shahar/DataSets/TrainedNetworks/MnistKeras/2018-09-06 08:35:34.025216/TensorFlow/saved_model.pb in function 'ReadTFNetParamsFromBinaryFileOrDie'
The same with my net but with *.pbtxt file.
FAILED: ReadProtoFromTextFile(param_file, param). Failed to parse GraphDef file: ./output_graph.pbtxt" char *
It seems OK with *.pb and here the code to generate it:
output_nodes = [n.name for n in tf.get_default_graph().as_graph_def().node]
# Freeze the graph
frozen_gdef = tf.graph_util.convert_variables_to_constants(
sess,
sess.graph_def,
output_nodes)
# Save the frozen graph
with open('./model/output_graph.pb', 'wb') as f:
f.write(frozen_gdef.SerializeToString())
Hope that help!
Let me known if it is ok with your *.pbtxt
I have been developing a program for my school project which recognizes numbers. For that I have used Python, Keras and the MNIST Dataset. This is the code I used to train it:
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Convolution2D, MaxPooling2D, Activation, AveragePooling2D
from keras import backend as K
import matplotlib.pyplot as plt
import matplotlib
batch_size = 32
num_classes = 10
epochs = 10
img_rows, img_cols = 28, 28
(x_train, y_train), (x_test, y_test) = mnist.load_data()
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)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Convolution2D(6, (5, 5), input_shape=input_shape))
model.add(Activation('sigmoid'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(12, (5, 5)))
model.add(Activation('sigmoid'))
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(192))
model.add(Dense(10))
model.add(Activation('sigmoid'))
model.add(Dense(10))
model.add(Activation('softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
hist = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
model.save('model3.h5')
train_loss = hist.history['loss']
val_loss = hist.history['val_loss']
train_acc = hist.history['acc']
val_acc = hist.history['val_acc']
xc = range(epochs)
plt.figure(1,figsize=(7,5))
plt.plot(xc,train_loss)
plt.plot(xc,val_loss)
plt.xlabel('num of Epochs')
plt.ylabel('loss')
plt.title('train_loss vs val_loss')
plt.grid(True)
plt.legend(['train','val'])
print(plt.style.available) # use bmh, classic,ggplot for big pictures
plt.style.use(['classic'])
plt.figure(2,figsize=(7,5))
plt.plot(xc,train_acc)
plt.plot(xc,val_acc)
plt.xlabel('num of Epochs')
plt.ylabel('accuracy')
plt.title('train_acc vs val_acc')
plt.grid(True)
plt.legend(['train','val'],loc=4)
#print plt.style.available # use bmh, classic,ggplot for big pictures
plt.style.use(['classic'])
plt.show()
I saved the model under the name model3.h5. However, in another program I wrote, I was trying to predict with the model I saved the numbers I entered in Paint. I had 10 pictures (0-9) and while predicting the model predicted that all numbers are number 8, which is of course wrong.
However, during training, accuracy was close to 98.5% and the loss was less than 0.1. Am I doing something wrong?
Here is the code that I run for predicting it on unseen data. It resizes the picture to 28 columns and 28 rows so it can run on my CNN.
This is my first project on Convolutional Neural Networks and I don't know "some extra techniques" that could help me do better on the unseen data.
I tried some different architectures as well (doing convolutional layers with max pooling and relu activation functions, then adding full connected layers) but the result was still the same. I also tried to set it to 100 or 200 epochs, still no use...
import os, cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
from keras import backend as K
from keras.models import load_model
K.set_image_dim_ordering('tf')
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD,RMSprop,adam
PATH = os.getcwd()
data_path = PATH + '\myNumbers'
data_dir_list = os.listdir(data_path) #direktoriji unutra
img_data = []
for file in data_dir_list:
test_image = cv2.imread(data_path + "\\" + file)
test_image = cv2.cvtColor(test_image, cv2.COLOR_RGB2GRAY)
test_image = cv2.resize(test_image,(28,28))
test_image = np.array(test_image)
test_image = test_image.astype('float32')
test_image /= 255
print (test_image.shape)
test_image= np.expand_dims(test_image, axis=3)
test_image= np.expand_dims(test_image, axis=0)
print (test_image.shape)
img_data.append(test_image)
model = load_model("model3.h5")
for img in img_data:
print(model.predict(img))
print(model.predict_classes(img))