{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","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 \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport sklearn\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\nimport os\n#print(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"images_dir_name = '../input/stage_1_test_images'\ninput_dir = '../input/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10742b6b80d714ea368b598068db8a9d1a0812fc"},"cell_type":"code","source":"# retrieve all the labels and store those into a collection\nclasses_trainable = pd.read_csv(input_dir+'classes-trainable.csv')\nall_labels = classes_trainable['label_code']\nprint ('The number of unique labels is {}'.format(len(all_labels)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"52217f2ad8197cb5655285cadb8a81270698dc0a"},"cell_type":"code","source":"# set the number of labels which will be used as an output layer size for a model\nnum_labels = len(all_labels)\n\n# build the index dictionary based on the labels collection\nlabels_index = {label:idx for idx, label in enumerate(all_labels)}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"93ec4932dec8bafd2cff021f6389429876886db9","scrolled":true},"cell_type":"code","source":"# retrieve the list of train images (in our case we'll be using the test images just to get the model up and running)\n# this will be changed to the train data set in the future.\ntrain_image_names = [img_name[:-4] for img_name in os.listdir(images_dir_name)]\nprint (train_image_names[0])\nprint (\"number of training images is {}\".format(len(train_image_names)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8c7d47b568edcd42058be5ad6a3dde58a3afbf85"},"cell_type":"code","source":"# retrieve the list of train labels (machine labels for now; need to work on replacing the machine labels with human ones if available)\n# for now I'll be using tuning labels\nlabels = pd.read_csv('../input/tuning_labels.csv')\nlabels.head()\ntrain_images = []\ntrain_labels_raw = []\nfor index, row in labels.iterrows():\n    train_images.append(row[0])\n    labels_raw = row[1].split(' ')\n    train_labels_raw.append([labels_index[label] for label in labels_raw])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d31008f8a50039609536225c532b924f1b3275cf"},"cell_type":"code","source":"# do the multi-hot encoding\ndef multi_hot_encode(x, num_classes):\n    encoded = []\n    for labels in x:\n        labels_encoded = np.zeros(num_classes)\n        \n        for item in labels:\n            labels_encoded[item] = 1\n            \n        encoded.append(labels_encoded)\n        \n    encoded = np.array(encoded)\n    \n    return encoded\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a15653ebf8e1b1b23e6502beb0b5b0a8a07969c"},"cell_type":"code","source":"train_labels = multi_hot_encode(train_labels_raw, num_labels)\nprint (train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4f688c64b93222fd7e1281cfe72db8f2c12f57cf"},"cell_type":"code","source":"from sklearn.utils import shuffle\n#import tensorflow as tf\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0c6b49a520bd310a3dc27e4d0b916ed33c001708"},"cell_type":"code","source":"# define the normalization logic for an image data\ndef normalize(x):\n    return (x.astype(float) - 128)/128","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"412521fb55f08645761ad9af578327143c1217d2"},"cell_type":"code","source":"# define the dimensions of the processed image\nx_dim = 100\ny_dim = 100\nn_channels = 3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"18c2c801ee8b6f94514f7bd6b436be2fc4fe775f"},"cell_type":"code","source":"# define scaling for logic for an image data\ndef scale(x):\n    return cv2.resize(x, (x_dim, y_dim))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7af7989010f3eaed71ec4c91d2206470bf7e6070"},"cell_type":"code","source":"# read and pre-process image\ndef preprocess(image_name):\n    img = cv2.imread(image_name)\n    scaled = scale(img)\n    normalized = normalize(scaled)\n    \n    return np.array(normalized)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bbf15964fd31cf9840e0354994af2196c4359167"},"cell_type":"code","source":"# prepare the collection of labels\ndef get_labels(image_name):\n    labels = []\n    \n    # todo implement\n    \n    return labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8959d0df27e7b169b25d7f43ac929fd875572005"},"cell_type":"code","source":"# build the generator for training\ndef generator(samples, sample_labels, batch_size=32):\n    num_samples = len(samples)\n    \n    while 1: # Loop forever so the generator never terminates\n        sklearn.utils.shuffle(samples, sample_labels)\n        for offset in range(0, num_samples, batch_size):\n            batch_samples = samples[offset:offset+batch_size]\n            batch_labels = sample_labels[offset:offset+batch_size]\n\n            images = []\n            labels = []\n\n            for i, batch_sample in enumerate(batch_samples):\n\n                image = preprocess(images_dir_name+'/'+batch_sample+'.jpg')\n\n                # this will be needed later once get the real data\n                #image_labels = get_labels(batch_sample)\n\n                images.append(image)\n                labels.append(batch_labels[i])\n\n            X_train = np.array(images)\n            y_train = np.array(labels)\n            yield sklearn.utils.shuffle(X_train, y_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8da090e008d0661d6ae4add9bc4efafb401bb2cb"},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense, Activation, Conv2D, BatchNormalization, MaxPooling2D, Lambda, Dropout, Flatten, Cropping2D\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a9fb6aae62271ff2c6b4e2a48103f779eb2a6f93"},"cell_type":"code","source":"def build_model(num_classes):\n    model = Sequential()\n    \n    # convolutions with maxpooling and batchnorm\n    model.add(Conv2D(24, kernel_size=(5,5), strides=(1,1), padding='same', input_shape=(x_dim, y_dim, n_channels)))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))\n    model.add(Conv2D(36, kernel_size=(5,5), strides=(1,1), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))\n    model.add(Conv2D(48, kernel_size=(5,5), strides=(1,1), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))\n    model.add(Conv2D(64, kernel_size=(3,3), strides=(1,1), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))\n    model.add(Conv2D(64, kernel_size=(3,3), strides=(1,1), padding='same'))\n    model.add(BatchNormalization())\n    model.add(Activation('relu'))\n    model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))\n    \n    # flatten and add fully connected layers\n    model.add(Flatten())\n    model.add(Dense(num_classes*2))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.25))\n    model.add(Activation('relu'))\n    model.add(Dense(num_classes*2))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.25))\n    model.add(Activation('relu'))\n    model.add(Dense(num_classes))\n    model.add(Activation('sigmoid'))\n    \n    # compile with Adam optimizer and mean squared error as the loss function\n    model.compile(loss=\"binary_crossentropy\", optimizer='adam', metrics=[\"accuracy\"])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"89c34e3c4e91ea9b58062d3037f32b0d7ebcface"},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nXtrain, Xvalid, ytrain, yvalid = train_test_split(train_images, train_labels, test_size=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"37defcdc8e0bac8e40e1909a4d501af15b9854ed"},"cell_type":"code","source":"# define the number of epochs\nepochs=5\nbatch_size = 32","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f56e1846be72834918dda6c93313f1e32f15dfc7"},"cell_type":"code","source":"# trains the model\n# defined 2 callbacks: early stopping and checkpoint to save the model if the validation loss has been improved\ndef train_model(model, train_generator, validation_generator, epochs=3):\n    early_stopping_callback = EarlyStopping(monitor='val_loss', patience=1)\n    checkpoint_callback = ModelCheckpoint('best_model.h5', monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n\n    \n    model.fit_generator(train_generator, steps_per_epoch=len(ytrain)//batch_size, validation_data=validation_generator, validation_steps=len(yvalid)//batch_size, epochs=epochs, callbacks=[early_stopping_callback, checkpoint_callback])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ef74300bcc144f32edea7a8db8a26abbcb378465","scrolled":true},"cell_type":"code","source":"# compile and train the model using the generator function\ntrain_generator = generator(Xtrain, ytrain, batch_size=batch_size)\nvalidation_generator = generator(Xvalid, yvalid, batch_size=batch_size)\n\nmodel = build_model(num_labels)\n\ntrain_model(model, train_generator, validation_generator, epochs)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"acf1d91afa307d5ba73ca8223a350e7450f23e64"},"cell_type":"code","source":"# predict one label\ndef predict(model, image_name, threshold=0.5):\n    image = preprocess(image_name)\n    image = np.reshape(image,[1,x_dim, y_dim, n_channels])\n    prediction = model.predict(image)[0]\n    \n    print (prediction)\n    \n    indices = np.argwhere(prediction >= threshold).flatten()\n    print (indices)\n    \n    labels = all_labels[indices]\n    \n    return labels\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6dc928cd8bc50cd2949c4b0bd3c48eef87075db0"},"cell_type":"code","source":"img_name = images_dir_name+'/'+Xtrain[0]+'.jpg'\n\nprint (predict(model, img_name))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"76429350443b0f52c513871a01c06a7c37841266"},"cell_type":"code","source":"","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}