{"cells":[{"metadata":{"_uuid":"b4d0be03fcd71edc62de65e50a0c9bac21dd62b3"},"cell_type":"markdown","source":"# CS-GY 9223-D: Deep Learning Homework 2\nDue on Friday, 12th March 2019, 11:55 PM\n\nThis homework can be done in pairs.\n\nWrite down the UNIs (NetIDs) of your group (if applicable)\n\nMember 1: Name, NetID\n\nMember 2: Name, NetID"},{"metadata":{"_uuid":"4a0fcc96e49162ba6931c97202af93010e099718"},"cell_type":"markdown","source":"### Create validation data"},{"metadata":{"trusted":true,"_uuid":"4cbc4897e79f9a83bd13f10d8936383903d7cde9"},"cell_type":"code","source":"import os\nimport numpy as np\nimport glob","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b2eda6ef7bfb0db9993c586f02be9de288d827f4"},"cell_type":"code","source":"data_path = '../input/'\nTRAIN = '../input/images_training_rev1/images_training_rev1'\nTEST = '../input/images_test_rev1/images_test_rev1'\nLABELS = '../input/training_solutions_rev1/training_solutions_rev1.csv'\n# g = glob.glob(data_path+'train/*.jpg')\n# shuf = np.random.permutation(g)\n# for i in range(2000):\n#     os.rename(shuf[i], data_path+ 'valid/' + shuf[i].split(\"/\")[-1])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"949cea9ebbedc0a8d170ba2c13e85f7e82175286"},"cell_type":"markdown","source":"## Building VGG model in Keras"},{"metadata":{"trusted":true,"_uuid":"90631c5686d8fc757da85495130396dc5861ad84"},"cell_type":"code","source":"from keras.models import Sequential, Model\nfrom keras.layers.core import Flatten, Dense, Dropout, Lambda, Reshape\nfrom keras.layers import Input\nfrom keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D\nfrom keras.layers import Conv2D, MaxPooling2D, Activation\nfrom keras.optimizers import SGD, RMSprop, Adam\n\nimport matplotlib.pylab as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0ffca860f2c5741c89683fc05eb5891c0445a5ec"},"cell_type":"code","source":"def ConvBlock(layers, model, filters):\n    \"\"\"\n    Create a layered Conv/Pooling block\n    \"\"\"\n    for i in range(layers): \n        model.add(ZeroPadding2D((1,1)))  # zero padding of size 1\n        model.add(Convolution2D(filters, 3, 3, activation='relu'))  # 3x3 filter size \n    model.add(MaxPooling2D((1,1), strides=(2,2)))\n\ndef FCBlock(model):\n    \"\"\"\n    Fully connected block with ReLU and dropout\n    \"\"\"\n    model.add(Dense(4096, activation='relu'))\n    model.add(Dropout(0.5))\n    \ndef VGG_16():\n    \"\"\"\n    Implement VGG16 architecture\n    \"\"\"\n    model = Sequential()\n    model.add(Lambda(lambda x : x, input_shape=(3,106,106)))\n    \n    ConvBlock(2, model, 64)\n    ConvBlock(2, model, 128)\n    ConvBlock(3, model, 256)\n    ConvBlock(3, model, 512)\n    ConvBlock(3, model, 512)\n\n    model.add(Flatten())\n    FCBlock(model)\n    FCBlock(model)\n    \n    model.add(Dense(37, activation = 'sigmoid'))\n    return model\n\n# Compile \noptimizer = RMSprop(lr=1e-6)\nmodel = VGG_16()\nmodel.compile(loss='mean_squared_error', optimizer=optimizer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7e3acc7eb143c505bae188d96201c537725d268a"},"cell_type":"code","source":"from random import shuffle\nfrom scipy.misc import imresize  \n\nclass data_getter:    \n    \"\"\"\n    Creates a class for handling train/valid/test data paths,\n    training labels and image IDs.\n    Useful for switching between sample and full datasets.\n    \"\"\"\n    def __init__(self, path):    \n        self.path = path \n        self.train_path = TRAIN\n        #self.val_path = path + \"valid\"\n        self.test_path = TEST\n        \n        def get_paths(directory):\n            return [f for f in os.listdir(directory)]\n        \n        self.training_images_paths = get_paths(self.train_path)\n        #self.validation_images_paths = get_paths(self.val_path)\n        self.test_images_paths = get_paths(self.test_path)    \n        \n        def get_all_solutions():\n        ### Import solutions file and load into self.solutions\n            import csv\n            all_solutions = {}\n            #/'training_solutions_rev1.csv'\n            with open(LABELS, 'r') as f:\n                reader = csv.reader(f, delimiter=\",\")\n                next(reader)\n                for i, line in enumerate(reader):\n                    all_solutions[line[0]] = [float(x) for x in line[1:]]\n            return all_solutions\n        \n        self.all_solutions = get_all_solutions()\n\n    def get_id(self,fname):\n        return fname.replace(\".jpg\",\"\").replace(\"data\",\"\")\n        \n    def find_label(self,val):\n        return self.all_solutions[val]\n        \n# fetcher = data_getter('data/sample/')\nfetcher = data_getter(data_path)\nprint(fetcher.train_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3cf2d5280454eeb454460f4573002c6c41c8a8ca"},"cell_type":"code","source":"def process_images(paths):\n    \"\"\"\n    Import image at 'paths', decode, centre crop and prepare for batching. \n    \"\"\"\n    count = len(paths)\n    arr = np.zeros(shape=(count,3,106,106))\n    for c, path in enumerate(paths):\n        img = plt.imread(path).T\n        img = img[:,106:106*3,106:106*3] #crop 424x424 -> 212x212\n        img = imresize(img,size=(106,106,3),interp=\"cubic\").T # downsample to half res\n        arr[c] = img\n    return arr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ceee5cf4e0446c317d31221e5d2c4f83912aca78"},"cell_type":"code","source":"## Print some before/after processing images\n\n#process_images([fetcher.train_path + '/' + fetcher.training_images_paths[100]])\nim = plt.imread(fetcher.train_path + '/' + fetcher.training_images_paths[0])\n# print(im.shape)\n\nplt.imshow(im)\nplt.show()\nim = im.T[:,106:106*3,106:106*3] #crop 424x424 -> 212x212\n\nplt.imshow(im.T)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e3d7d9ccf7eff35ae834ffbefee6dffbb5895b9"},"cell_type":"code","source":"# Create generator that yields (current features X, current labels y)\ndef BatchGenerator(getter):\n    while 1:\n        for f in getter.training_images_paths:\n            X_train = process_images([getter.train_path + '/' + fname for fname in [f]])\n            id_ = getter.get_id(f)\n            y_train = np.array(getter.find_label(id_))\n            y_train = np.reshape(y_train,(1,37))\n            yield (X_train, y_train)\n            \ndef ValBatchGenerator(getter):\n    while 1:\n        for f in getter.validation_images_paths:\n            X_train = process_images([getter.val_path + '/' + fname for fname in [f]])\n            id_ = getter.get_id(f)\n            y_train = np.array(getter.find_label(id_))\n            y_train = np.reshape(y_train,(1,37))\n            yield (X_train, y_train)\n                        ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ffc24d1a4d2e7f13ae14050ec84d67627c3f98e5"},"cell_type":"markdown","source":"### Train model"},{"metadata":{"trusted":true,"_uuid":"85cefa050c9c737f0ac1de1ae47cc86f66d048e9"},"cell_type":"code","source":"from keras.callbacks import Callback\nfrom keras.callbacks import ModelCheckpoint, Callback, EarlyStopping\n\nclass LossHistory(Callback):\n    def on_train_begin(self, logs={}):\n        self.losses = []\n        self.val_losses = []\n\n    def on_batch_end(self, batch, logs={}):\n        self.losses.append(logs.get('loss'))\n        self.val_losses.append(logs.get('val_loss'))\n    \nearly_stopping = EarlyStopping(monitor='val_loss', patience=7, verbose=1, mode='auto')\nhistory = LossHistory()\n\nfrom keras.callbacks import ModelCheckpoint\ncheckpointer = ModelCheckpoint(filepath='tmp/weights.hdf5', verbose=1, save_best_only=True)\n\n\nbatch_size = 32\nsteps_to_take = int(len(fetcher.training_images_paths)/batch_size)\n#val_steps_to_take = int(len(fetcher.validation_images_paths)/batch_size)\n                #typically be equal to the number of unique samples if your dataset\n                #divided by the batch size.\n        \n        \n#model = load_model('tmp/weights.hdf5')\n\nhist = model.fit_generator(BatchGenerator(fetcher),\n                    samples_per_epoch=steps_to_take, \n                    nb_epoch=50,\n                    verbose=2,\n                    callbacks=[history,checkpointer,early_stopping],\n                   )","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3d18739a6a8e2a6fd9b13a05b39645c414dd3531"},"cell_type":"markdown","source":"### Plot training/validation loss"},{"metadata":{"trusted":false,"_uuid":"73cfe4a4663e0137e441448ea5538cfae230419b"},"cell_type":"code","source":"plt.figure(figsize=(12,8))\nplt.plot(hist.epoch,hist.history['loss'],label='Test')\nplt.plot(hist.epoch,hist.history['val_loss'],label='Validation',linestyle='--')\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"RMSE\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"59de062204e72f227d2f6dc7296a0d401bdc8a68"},"cell_type":"markdown","source":"### Model Predict"},{"metadata":{"trusted":false,"_uuid":"de0bce34dbb1ed8f6214ba0743a008e09bac9f4e"},"cell_type":"code","source":"# Load best model weights\nfrom keras.models import load_model\nmodel = load_model('tmp/weights.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"bac26fa2d50c11ba4f16c156d3a0a7db9dc679e3"},"cell_type":"code","source":"def TestBatchGenerator(getter):\n    while 1:\n        for f in getter.test_images_paths:\n            X_train = process_images([getter.test_path + '/' + fname for fname in [f]])\n            yield (X_train)\n\npredictions = model.predict_generator(TestBatchGenerator(fetcher),\n                       val_samples = len(fetcher.test_images_paths),\n                        max_q_size = 32,)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"b79ca063d4a4590bcd4ef2b37ae722f6577110a5"},"cell_type":"code","source":"predictions.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"34b113256066527c962327105e2cf02055891990"},"cell_type":"code","source":"header = open('all_zeros_benchmark.csv','r').readlines()[0]\n\nwith open('submission_1.csv','w') as outfile:\n    outfile.write(header)\n    for i in range(len(fetcher.test_images_paths)):\n        id_ = (fetcher.get_id(fetcher.test_images_paths[i]))\n        pred = predictions[i]\n        outline = id_ + \",\" + \",\".join([str(x) for x in pred])\n        outfile.write(outline + \"\\n\")","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.2"}},"nbformat":4,"nbformat_minor":1}