From ec823fe6883b64705c2c16c35f8b4d715e9b0593 Mon Sep 17 00:00:00 2001 From: Silver-T Date: Wed, 23 May 2018 17:02:21 +1000 Subject: [PATCH] Edited model, need to change load_images.py to expand waldo data --- mini_proj/Load_Images.py | 45 ++++++++++++++++++++++------ mini_proj/waldo_model.py | 63 ++++++++++++++++++++-------------------- 2 files changed, 67 insertions(+), 41 deletions(-) diff --git a/mini_proj/Load_Images.py b/mini_proj/Load_Images.py index d0b986e..67d791b 100644 --- a/mini_proj/Load_Images.py +++ b/mini_proj/Load_Images.py @@ -19,6 +19,7 @@ def gen_data(w_path, n_w_path): i = 0 for image_name in waldo_file_list: pic = cv2.imread(os.path.join(w_path, image_name)) # NOTE: cv2.imread() returns a numpy array in BGR not RGB + pic = pic/255 # Scaling images down to values of 0-255 imgs_raw.append(np.rollaxis(pic, -1)) # rolls colour axis to 0 imgs_lbl.append(1) # Value of 1 as Waldo is present in the image @@ -28,22 +29,48 @@ def gen_data(w_path, n_w_path): i = 0 for image_name in not_waldo_file_list: pic = cv2.imread(os.path.join(n_w_path, image_name)) + pic = pic/255 # Scaling images down to values of 0-255 imgs_raw.append(np.rollaxis(pic, -1)) imgs_lbl.append(0) print('Completed: {0}/{1} non-Waldo images'.format(i+1, total_nw)) i += 1 - # Calculate what 30% of each set is - third_of_w = math.floor(0.3*total_w) - third_of_nw = math.floor(0.3*total_nw) + ## Randomise and split data into training and test sets + # Code was modified from code written by: Kyle O'Brien (medium.com/@kylepob61392) + n_images = len(imgs_raw) + TRAIN_TEST_SPLIT = 0.75 + + # Split at the given index + split_index = int(TRAIN_TEST_SPLIT * n_images) + shuffled_indices = np.random.permutation(n_images) + train_indices = shuffled_indices[0:split_index] + test_indices = shuffled_indices[split_index:] + + train_data = [] + train_lbl = [] + test_data = [] + test_lbl = [] + + # Split the images and the labels + for index in train_indices: + train_data.append(imgs_raw[index]) + train_lbl.append(imgs_lbl[index]) + + for index in test_indices: + test_data.append(imgs_raw[index]) + test_lbl.append(imgs_lbl[index]) + + # # Calculate what 30% of each set is + # third_of_w = math.floor(0.3*total_w) + # third_of_nw = math.floor(0.3*total_nw) - # Split data into training and test data (60%/30%) - train_data = np.append(imgs_raw[(third_of_w+1):total_w], imgs_raw[(total_w + third_of_nw + 1):len(imgs_raw)-1], axis=0) - train_lbl = np.append(imgs_lbl[(third_of_w+1):total_w], imgs_lbl[(total_w + third_of_nw + 1):len(imgs_lbl)-1], axis=0) - # If axis not given, both arrays are flattened before being appended - test_data = np.append(imgs_raw[0:third_of_w], imgs_raw[total_w:(total_w + third_of_nw)], axis=0) - test_lbl = np.append(imgs_lbl[0:third_of_w], imgs_lbl[total_w:(total_w + third_of_nw)], axis=0) + # # Split data into training and test data (60%/30%) + # train_data = np.append(imgs_raw[(third_of_w+1):total_w], imgs_raw[(total_w + third_of_nw + 1):len(imgs_raw)-1], axis=0) + # train_lbl = np.append(imgs_lbl[(third_of_w+1):total_w], imgs_lbl[(total_w + third_of_nw + 1):len(imgs_lbl)-1], axis=0) + # # If axis not given, both arrays are flattened before being appended + # test_data = np.append(imgs_raw[0:third_of_w], imgs_raw[total_w:(total_w + third_of_nw)], axis=0) + # test_lbl = np.append(imgs_lbl[0:third_of_w], imgs_lbl[total_w:(total_w + third_of_nw)], axis=0) try: # Save the data as numpy files diff --git a/mini_proj/waldo_model.py b/mini_proj/waldo_model.py index 0d9aa43..33496a9 100644 --- a/mini_proj/waldo_model.py +++ b/mini_proj/waldo_model.py @@ -10,14 +10,16 @@ from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D from keras.models import Model from sklearn import svm, tree, naive_bayes, ensemble +from sklearn.metrics import accuracy_score from _image_classifier import ImageClassifier -from keras.optimizers import Adadelta +from keras.optimizers import Adam from keras.callbacks import ModelCheckpoint from keras import backend as K K.set_image_dim_ordering('th') np.random.seed(7) +from keras.utils import to_categorical ''' Model definition define the network structure ''' @@ -25,28 +27,28 @@ def FCN(): ## List of model layers inputs = Input((3, 64, 64)) - conv1 = Conv2D(8, (2, 2), activation='relu', padding='same', input_shape=(64, 64, 3))(inputs) + conv1 = Conv2D(16, (3, 3), activation='relu', padding='same', input_shape=(64, 64, 3))(inputs) m_pool1 = MaxPooling2D(pool_size=(2, 2))(conv1) - conv2 = Conv2D(16, (2, 2), activation='relu', padding='same')(m_pool1) - drop1 = Dropout(0.2)(conv2) # Drop some portion of features to prevent overfitting - m_pool2 = MaxPooling2D(pool_size=(2, 2))(drop1) + conv2 = Conv2D(32, (3, 3), activation='relu', padding='same')(m_pool1) + #drop1 = Dropout(0.2)(conv2) # Drop some portion of features to prevent overfitting + m_pool2 = MaxPooling2D(pool_size=(2, 2))(conv2) - conv3 = Conv2D(32, (2, 2), activation='relu', padding='same')(m_pool2) - drop2 = Dropout(0.2)(conv3) # Drop some portion of features to prevent overfitting - m_pool2 = MaxPooling2D(pool_size=(2, 2))(drop2) + conv3 = Conv2D(32, (3, 3), activation='relu', padding='same')(m_pool2) + # drop2 = Dropout(0.2)(conv3) # Drop some portion of features to prevent overfitting + # m_pool2 = MaxPooling2D(pool_size=(2, 2))(drop2) - conv4 = Conv2D(164, (2, 2), activation='relu', padding='same')(m_pool2) + # conv4 = Conv2D(64, (2, 2), activation='relu', padding='same')(m_pool2) - flat = Flatten()(conv4) # Makes data 1D + flat = Flatten()(conv3) # Makes data 1D dense = Dense(64, activation='relu')(flat) # Fully connected layer drop3 = Dropout(0.2)(dense) - classif = Dense(2, activation='softmax')(drop3) # Final layer to classify + classif = Dense(2, activation='sigmoid')(drop3) # Final layer to classify ## Define the model structure model = Model(inputs=inputs, outputs=classif) # Optimizer recommended Adadelta values (lr=0.01) - model.compile(optimizer=Adadelta(lr=0.1), loss='sparse_categorical_crossentropy', metrics=['accuracy']) + model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy']) return model @@ -57,37 +59,36 @@ lbl_train = np.load('Waldo_train_lbl.npy') im_test = np.load('Waldo_test_data.npy') lbl_test = np.load('Waldo_test_lbl.npy') +lbl_train = to_categorical(lbl_train) # One hot encoding the labels +lbl_test = to_categorical(lbl_test) + ## Define model model = FCN() -svm_iclf = ImageClassifier(svm.SVC) -tree_iclf = ImageClassifier(tree.DecisionTreeClassifier) -naive_bayes_iclf = ImageClassifier(naive_bayes.GaussianNBd) -ensemble_iclf = ImageClassifier(ensemble.RandomForestClassifier) +# svm_iclf = ImageClassifier(svm.SVC) +# tree_iclf = ImageClassifier(tree.DecisionTreeClassifier) +# naive_bayes_iclf = ImageClassifier(naive_bayes.GaussianNBd) +# ensemble_iclf = ImageClassifier(ensemble.RandomForestClassifier) ## Define training parameters epochs = 20 # an epoch is one forward pass and back propogation of all training data -batch_size = 5 -#lrate = 0.01 -#decay = lrate/epochs -# epoch - one forward pass and one backward pass of all training data -# batch size - number of training example used in one forward/backward pass -# (higher batch size uses more memory) -# learning rate - controls magnitude of weight changes in training the NN +batch_size = 150 # batch size - number of training example used in one forward/backward pass +# (higher batch size uses more memory, smaller batch size takes more time) +#lrate = 0.01 # Learning rate of the model - controls magnitude of weight changes in training the NN +#decay = lrate/epochs # Decay rate of the model ## Train model # Purely superficial output sys.stdout.write("\nFitting model") sys.stdout.flush() for i in range(0, 3): - t.sleep(0.8) + t.sleep(0.5) sys.stdout.write('.') sys.stdout.flush() +t.sleep(0.5) print() # Outputs the model structure -for i in range(0, len(model.layers)): - print("Layer {}: {}".format(i, model.layers[i].output)) -print('-'*30) +print(model.summary()) filepath = "checkpoint.hdf5" # Defines the model checkpoint file checkpoint = ModelCheckpoint(filepath, verbose=1, save_best_only=False) # Defines the checkpoint process @@ -120,15 +121,13 @@ model.save('Waldo.h5') print("\nModel weights and structure have been saved.\n") ## Testing the model -# Show data stats -print('*'*30) -print(im_test.shape) -print(lbl_test.shape) -print('*'*30) start = t.time() # Passes the dataset through the model pred_lbl = model.predict(im_test, verbose=1, batch_size=batch_size) end = t.time() +pred_lbl = np.round(pred_lbl) +accuracy = accuracy_score(lbl_test, pred_lbl) +print("Accuracy: " + str(accuracy)) print("Images generated in {} seconds".format(end - start)) np.save('predicted_results.npy', pred_lbl)