1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | #!/usr/bin/env python3 ''' Beginning my deep learning journey File: dl_catsVdogs_v3.py This is a continuation from dl_cats_Vdogs.py. This version 3 addresses the over fitting issues via usage of a pre-trained network A pre-trained network is a saved version of a network which was trained on a larger dataset. The two ways to use pre-trained networks are feature extraction and fine-tuning Feature extraction uses representation learned from previous models to extract interesting features. These features are then run against a newly trained classifier Author: Nik Alleyne Author Blog: www.securitynik.com Date: 2020-03-06 ''' import os, shutil from keras import (models, optimizers) from keras.applications import VGG16 from keras.layers import (Conv2D, MaxPooling2D, Flatten, Dense, Dropout) from keras.preprocessing.image import (ImageDataGenerator, image) from matplotlib import pyplot as plt def main(): cats_dogs_dataset = './PetImages' cats_dogs = '/tmp/cats_dogs' print('[*] Checking to the if "{}" directory exists ...'.format(cats_dogs)) if (os.path.exists(cats_dogs)): print('[-] Deleting directory {}'.format(cats_dogs)) shutil.rmtree(cats_dogs) print('[+] Making temporary image directory ...') os.mkdir(cats_dogs) print(' [+] Creating training set directory ...') train_dir = os.path.join(cats_dogs, 'train_set') cats_train = os.path.join(train_dir, 'cats') dogs_train = os.path.join(train_dir, 'dogs') os.mkdir(train_dir) os.mkdir(cats_train) os.mkdir(dogs_train) print(' [+] Creating validation set directory ...') val_dir = os.path.join(cats_dogs, 'val_set') cats_val = os.path.join(val_dir, 'cats') dogs_val = os.path.join(val_dir, 'dogs') os.mkdir(val_dir) os.mkdir(cats_val) os.mkdir(dogs_val) print(' [+] Creating testing set directory ...') test_dir = os.path.join(cats_dogs, 'test_set') cats_test = os.path.join(test_dir, 'cats') dogs_test = os.path.join(test_dir, 'dogs') os.mkdir(test_dir) os.mkdir(cats_test) os.mkdir(dogs_test) # copy the first 1000 cat images from for training data cat_train_images = ['{}.jpg'.format(i) for i in range(1000)] for cat in cat_train_images: src = os.path.join(cats_dogs_dataset +'/Cat', cat) dst = os.path.join(cats_train, cat) shutil.copyfile(src, dst) # copy the first 1000 dog images for training data dog_train_images = ['{}.jpg'.format(i) for i in range(1000)] for dog in dog_train_images: src = os.path.join(cats_dogs_dataset +'/Dog', dog) dst = os.path.join(dogs_train, dog) shutil.copyfile(src, dst) # copy the next 500 cat images and used as validation data cat_val_images = ['{}.jpg'.format(i) for i in range(1000, 1500)] for cat in cat_val_images: src = os.path.join(cats_dogs_dataset +'/Cat', cat) dst = os.path.join(cats_val, cat) shutil.copyfile(src, dst) # copy the next 500 dog images and used as validation data dog_val_images = ['{}.jpg'.format(i) for i in range(1000, 1500)] for dog in dog_val_images: src = os.path.join(cats_dogs_dataset +'/Dog', dog) dst = os.path.join(dogs_val, dog) shutil.copyfile(src, dst) # copy the final 500 cat images and used as test data cat_test_images = ['{}.jpg'.format(i) for i in range(1500, 2000)] for cat in cat_test_images: src = os.path.join(cats_dogs_dataset +'/Cat', cat) dst = os.path.join(cats_test, cat) shutil.copyfile(src, dst) # copy the final 500 dog images and used as test data dog_test_images = ['{}.jpg'.format(i) for i in range(1500, 2000)] for dog in dog_test_images: src = os.path.join(cats_dogs_dataset +'/Dog', dog) dst = os.path.join(dogs_test, dog) shutil.copyfile(src, dst) # Verifying the number of cat records in each directory print('[*] Total cat training images: {}:{}'.format(cats_train, len(os.listdir(cats_train)))) print('[*] Total cat validation images: {}:{}'.format(cats_val, len(os.listdir(cats_val)))) print('[*] Total cat test images: {}:{}'.format(cats_test, len(os.listdir(cats_test)))) # Verifying the number of dog records in each directory print('[*] Total cat training images: {}:{}'.format(dogs_train, len(os.listdir(dogs_train)))) print('[*] Total cat validation images: {}:{}'.format(dogs_val, len(os.listdir(dogs_val)))) print('[*] Total cat test images: {}:{}'.format(dogs_test, len(os.listdir(dogs_test)))) # Initiate the VGG16 convulational base pretrained_model_base = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3)) #rint the summary of the network print('[*] Here is the convulational network base \n{}'.format(pretrained_model_base.summary())) ''' Create the colvolution neural network from the pretrained model. This is meant to help to address the overfitting related to small datasets. This is being used in conjunction with data augmentation ''' convnet = models.Sequential() convnet.add(pretrained_model_base) # Flatten the layers convnet.add(Flatten()) # Add dense layers convnet.add(Dense(512, activation='relu')) convnet.add(Dense(1, activation='sigmoid')) # Compile the model convnet.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=0.01), metrics=['accuracy']) print('[*] Here is the model summary \n{}'.format(convnet.summary())) # Train the network using data augmentation training_data_generator = ImageDataGenerator(rescale=1.0/255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True,fill_mode='nearest') # Testing data should not be augmented testing_data_generator = ImageDataGenerator(rescale=1.0/255) training_data_generated = training_data_generator.flow_from_directory(train_dir, target_size=(150, 150), batch_size=32, class_mode='binary') validation_data_generated = testing_data_generator.flow_from_directory(val_dir, target_size=(150, 150), batch_size=32, class_mode='binary') convnet.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=0.02), metrics=['accuracy']) ''' Try to fit on the training data to see what occurrs. Set the epoch and steps as 10 just for my learning. These numbers should be larger ''' convnet_history = convnet.fit_generator(training_data_generated, steps_per_epoch=5, epochs=10, validation_data=validation_data_generated, validation_steps=8) print('[*] Here is what the network history looks like:\n {}'.format(convnet_history.history)) # Save the model convnet.save('/tmp/convnet_v3.h5') ''' Plot the loss and accuracy of the model This is being done over the training and validation data ''' train_accuracy = convnet_history.history['accuracy'] train_loss = convnet_history.history['loss'] validation_accuracy = convnet_history.history['val_accuracy'] validation_loss = convnet_history.history['val_loss'] convnet_epochs = range(1, len(train_accuracy) + 1) # Plot the graph to compare the training and validation loss and accuracy plt.plot(convnet_epochs, train_accuracy, 'b', label='Training Accuracy') plt.plot(convnet_epochs, validation_accuracy, 'bo', label='Validation Accuracy') plt.title('Training vs Validation Accuracy') plt.legend() plt.figure() plt.plot(convnet_epochs, train_loss, 'b', label='Training Loss') plt.plot(convnet_epochs, validation_loss, 'bo', label='Validation Loss') plt.title('Training vs Validation Accuracy') plt.legend() plt.show() if __name__ == '__main__': main() ''' References: https://www.microsoft.com/en-us/download/details.aspx?id=54765 https://keras.io/preprocessing/image/ https://keras.io/models/sequential/ https://keras.io/applications/#extract-features-with-vgg16 ''' |
Monday, March 23, 2020
Beginning Deep Learning with Dogs and Cats Classification
This code is all part of my deep learning journey and as always, is being placed here so I can always revisit it as I continue to expand on my learning of this topic.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment