{"cells":[{"metadata":{"_uuid":"567d822a77b80f27f2b43c314796b8da76a08bf8"},"cell_type":"markdown","source":"\n**Forked from** https://www.kaggle.com/orangutan/keras-vgg19-starter\n\n**For details**,.. https://www.kaggle.com/c/dog-breed-identification\n"},{"metadata":{"_cell_guid":"8a7bff8d-c95a-4cfb-8c38-14ab989f769b","_uuid":"4da5a3e7db32799ca0108576e469157094d23111","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport keras\nfrom keras.applications.vgg19 import VGG19\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.models import Model\nfrom keras.layers import Dense, Dropout, Flatten,  Conv2D, MaxPooling2D, GlobalAveragePooling2D\nfrom keras import backend as K\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.preprocessing.image import load_img\n#from keras.applications.vgg16 import preprocess_input\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras.preprocessing.image import img_to_array\nimport os\nfrom tqdm import tqdm\nfrom sklearn import preprocessing\nfrom sklearn.model_selection import train_test_split\nimport cv2\nimport sys\nimport bcolz\nimport random\n\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nfrom subprocess import check_output\nprint(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"0b8fddbc-447f-4083-88c4-9bd5f811253d","_uuid":"7c64ad63b95b36df5a2223b4c499c1caad9c73ee"},"cell_type":"markdown","source":"First we will read in the csv's so we can see some more information on the filenames and breeds"},{"metadata":{"_cell_guid":"bcbeef91-f00e-4a68-b1b8-25e206027bb2","_uuid":"18e9091e9a3d851fb0ce796a3b537ffb7f47c874","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/dog-breed-identification/labels.csv')\ndf_test = pd.read_csv('../input/dog-breed-identification/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"6abe20dc-a411-4334-ad66-2526d99c7f63","_uuid":"0ba75a32f91650bc75440443ab3d11c35e44e1c9","trusted":true},"cell_type":"code","source":"df_train.head(10)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"20c0da740a007aa6df69ca63e1fa645d157929cf","trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom glob import glob\nfrom mpl_toolkits.axes_grid1 import ImageGrid","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"92350610e9da8b22926d8b2f7985e7038d024b38","trusted":true},"cell_type":"code","source":"train_files = glob('../input/dog-breed-identification/train/*.jpg')\ntest_files = glob('../input/dog-breed-identification/test/*.jpg')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b673e68df37d6cc3686f91f7adc3405391548035","scrolled":true,"trusted":true},"cell_type":"code","source":"plt.imshow(plt.imread(train_files[100]))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"1ba5da72-9d82-404d-aa25-ce9739a45775","_uuid":"7fbb53109a3d08bedb1abac074f8186bdea991ac","trusted":true},"cell_type":"code","source":"targets_series = pd.Series(df_train['breed'])\none_hot = pd.get_dummies(targets_series, sparse = True)\none_hot_labels = np.asarray(one_hot)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1b4b0a25f14f055e766b4596ea2fa05f96546962","trusted":true},"cell_type":"code","source":"!ls ../input/keras-pretrained-models/","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"421885e6-97a5-4a43-bdf5-6b60cfc0b3d3","_uuid":"d59fb275c2e30a410c9c8af8489f38138b1513ac"},"cell_type":"markdown","source":"Next we will read in all of the images for test and train, using a for loop through the values of the csv files. I have also set an im_size variable which sets the size for the image to be re-sized to,  90x90 px, you should play with this number to see how it affects accuracy."},{"metadata":{"_cell_guid":"0e89e3ca-7c9e-4f76-aaf8-8c5267e3a415","_uuid":"7b47e6524b0fcf5ccb9a237cbdc8d444ff215dfb","trusted":true},"cell_type":"code","source":"im_size = 224","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"37551a8756b04008c6d71bd4f4b7d70214fb47e1","trusted":true},"cell_type":"code","source":"y_train = []\ny_val = []\nx_train_raw = bcolz.zeros((0,im_size,im_size,3),np.float32)\nx_val_raw = bcolz.zeros((0,im_size,im_size,3),np.float32)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"98aab483-199c-451b-80a9-a9c1cf3d02be","_uuid":"1f099a6a4d6b16ed3202a91d5376b77579664d04","trusted":true},"cell_type":"code","source":"i = 0 \nfor f, breed in tqdm(df_train.values):\n    # load an image from file\n    image = load_img('../input/dog-breed-identification/train/{}.jpg'.format(f), target_size=(im_size, im_size))\n    image = img_to_array(image)\n    # prepare the image for the VGG model\n    #image = preprocess_input(image)\n    label = one_hot_labels[i]\n    if random.randint(1,101) < 80: \n        x_train_raw.append(image)\n        y_train.append(label)\n    else:\n        x_val_raw.append(image)\n        y_val.append(label)\n    i += 1","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"eff86671657ad634082580628cb1ef0f69f3e4fe","trusted":true},"cell_type":"code","source":"y_train_raw = np.array(y_train, np.uint8)\ny_val_raw = np.array(y_val, np.uint8)\ndel(y_train,y_val)\nimport gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"ad4bb94f-2464-4685-9b44-32f5502e224a","_uuid":"0e64cd331abd85c517cf870d41b2440b200a54f1"},"cell_type":"markdown","source":"We check the shape of the outputs to make sure everyting went as expected."},{"metadata":{"_cell_guid":"b26f825e-8c02-43d9-9d1d-3e0092d69d26","_uuid":"a5dddeebe7556cecf31da047693710179ce29f98","trusted":true},"cell_type":"code","source":"print(x_train_raw.shape)\nprint(y_train_raw.shape)\nprint(x_val_raw.shape)\nprint(y_val_raw.shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8586a5da8a6028f8618bf16014c36f3cb52d7e6f","trusted":true},"cell_type":"code","source":"def plotImages( images_arr, n_images=4):\n    fig, axes = plt.subplots(n_images, n_images, figsize=(12,12))\n    axes = axes.flatten()\n    for img, ax in zip( images_arr, axes):\n        ax.imshow(img)\n        ax.set_xticks(())\n        ax.set_yticks(())\n    plt.tight_layout()\nplotImages(x_train_raw[0:16,]/255.)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"60707a5f-0689-4ecf-a0df-3e3e9c76e076","_uuid":"00fdfb9bf52e9f7a8030d88dfab823262c0f1dc2","trusted":true},"cell_type":"code","source":"num_class = y_train_raw.shape[1]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8752f7abf35b6008e6de770f2afb22d839549228","trusted":true},"cell_type":"code","source":"# Create the base pre-trained model\nbase_model = VGG19(weights = 'imagenet', include_top=False, input_shape=(im_size, im_size, 3))\n#base_model = ResNet50(weights = 'imagenet', include_top=False, input_shape=(im_size, im_size, 3))\nbase_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"75a4da8837aad5686bc11b73a8530131b2468f14","trusted":true},"cell_type":"code","source":"len(base_model.layers)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"33175d738fabfe877440e0d2c1e5b394b5076b5f","trusted":true},"cell_type":"code","source":"layers_to_remove = 0\nif layers_to_remove >0:\n    for i in range(0,layers_to_remove):\n        base_model.layers.pop()\n    base_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5b6e311de1f508c48d50e3f8dae9f4a3d316d449","trusted":true},"cell_type":"code","source":"fine_tuning_layers = 0\nlayers_to_freeze = len(base_model.layers) - fine_tuning_layers\nprint(layers_to_freeze)\n\nfor layer in base_model.layers[0:layers_to_freeze]:\n    layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"decf1fdf-5a24-41cd-b9b3-d49825efec82","_uuid":"0946091bb67a488a05f9e39e8dac432b485eb70a","trusted":true},"cell_type":"code","source":"# Add a new top layer\nx = base_model.layers[layers_to_freeze-1+fine_tuning_layers].output\nx = GlobalAveragePooling2D()(x)\n\n# This is the model we will train\nmodel = Model(inputs=base_model.input, outputs=x)\n\nmodel.compile(loss='categorical_crossentropy', \n              optimizer='adam', \n              metrics=['accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0bab62c3d59ca80a64b636c163ad34f1bfee7eb0"},"cell_type":"code","source":"class DataGenerator(keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, data, labels, im_size = 224, batch_size=32, shuffle=True, data_augment = False, test = False):\n        'Initialization'\n        self.batch_size = batch_size\n        self.list_IDs = np.arange(0,data.shape[0])\n        self.shuffle = shuffle\n        if self.shuffle == True:\n            np.random.shuffle(self.list_IDs)        \n        self.data = data\n        self.data_augment = data_augment\n        self.test = test\n        if self.test == False:\n            self.labels = labels\n        self.on_epoch_end()\n\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return int(np.floor(len(self.list_IDs) / self.batch_size))\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        # Generate indexes of the batch\n        indexes = self.list_IDs[index*self.batch_size:(index+1)*self.batch_size]\n\n        # Generate data\n        if self.test == False:\n            X, y = self.__data_generation(indexes)\n            return preprocess_input(X), y\n        else:\n            X = self.__data_generation(indexes)\n            return preprocess_input(X)\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        if self.shuffle == True:\n            np.random.shuffle(self.list_IDs)        \n\n    def __data_generation(self, list_IDs_temp):\n        'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)\n        # Initialization\n        X = np.zeros((list_IDs_temp.shape[0],im_size,im_size,3), dtype=np.float32)\n        if self.test == False:\n            y = np.zeros((list_IDs_temp.shape[0],self.labels.shape[1]), dtype=np.uint8)\n\n        # Generate data\n        for i, ID in enumerate(list_IDs_temp):\n            \n            if self.data_augment == True:\n                if random.randint(1,101) < 50: \n                    flip_horizontal = True\n                else:\n                    flip_horizontal = False\n                if random.randint(1,101) < 50: \n                    flip_vertical = True\n                else:\n                    flip_vertical = False\n                tx = im_size*random.randint(1,2)/100.0\n                ty = im_size*random.randint(1,2)/100.0\n                shear = random.randint(1,10)/100.0\n                zx = random.randint(80,120)/100.0\n                zy = random.randint(80,120)/100.0\n                brightness = random.randint(1,2)/100.0\n                channel_shift_intensity = random.randint(1,10)/100.0\n                \n                X[i,] = self.data[ID,]\n            else:\n                # Store sample\n                X[i,] = self.data[ID,]\n\n            # Store class\n            if self.test == False:\n                y[i,] = self.labels[ID,]\n\n        if self.test == False:\n            return X, y\n        else:\n            return X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5c351398dc0152b44a1f145bee64c830013a0ebf"},"cell_type":"code","source":"batch_size = 32\n\n# Parameters\nparams_trn = {\n          'im_size': im_size,\n          'batch_size': batch_size,\n          'shuffle': True,\n          'data_augment' : True,\n          'test' : False\n         }\nparams_val = {\n          'im_size': im_size,\n          'batch_size': batch_size,\n          'shuffle': True,\n          'data_augment' : False,\n          'test' : False\n         }\n\n# Generators\ntraining_generator = DataGenerator(x_train_raw, y_train_raw, **params_trn)\nvalidation_generator = DataGenerator(x_val_raw, y_val_raw, **params_val)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"f72763e1-68b6-4e54-9b80-ff0f4f94aa28","_uuid":"e8a63ce4e324f3e011b3de7fc459301337d1b8d0","trusted":true},"cell_type":"code","source":"preds_trn = model.predict_generator(training_generator, steps = x_train_raw.shape[0], verbose=1)\npreds_val = model.predict_generator(validation_generator, steps = x_train_raw.shape[0], verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"0457a19d-0e26-4619-a3c8-78c71e7d41e6","_uuid":"626b762d81d28ff77032658092d5bd9523b186b1","trusted":true},"cell_type":"code","source":"preds_trn.shape, preds_val.shape\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"a4ed0f81-8675-4a10-8b19-2d3ef191afe2","_uuid":"b72af806cbbdea33edd7f73d24dbe9b9cbaae805","trusted":true},"cell_type":"code","source":"sub = pd.DataFrame(preds_trn)\nsub.to_csv(\"preds_trn.csv\",index =False)\nsub = pd.DataFrame(y_train_raw)\nsub.to_csv(\"labels_trn.csv\",index =False)\n\nsub = pd.DataFrame(preds_val)\nsub.to_csv(\"preds_val.csv\",index =False)\nsub = pd.DataFrame(y_val_raw)\nsub.to_csv(\"labels_val.csv\",index =False)\n\n","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}