{"cells":[{"cell_type":"markdown","metadata":{"_cell_guid":"35dd21b2-17ff-4511-19ca-4ca4f6fea3aa"},"source":"Jeff Delaney kernel for Cats vs. Dogs redux using skimage instead of cv2"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"3a1f8b9e-f0a1-9b13-8184-4359c3d64b10"},"outputs":[],"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)\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.\n\n#select Theano as backend\n%env KERAS_BACKEND=theano"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"bda931cc-9290-d98d-e9ce-889b2dfb9a3b"},"outputs":[],"source":"import os, random\n\nfrom skimage.io import imread\nfrom skimage.transform import resize\nimport matplotlib.pyplot as plt\nfrom matplotlib import ticker\nimport seaborn as sns\n%matplotlib inline \n\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Input, Dropout, Flatten, Convolution2D, MaxPooling2D, Dense, Activation\nfrom keras.optimizers import RMSprop\nfrom keras.optimizers import SGD\nfrom keras.callbacks import ModelCheckpoint, Callback, EarlyStopping\nfrom keras.utils import np_utils\nfrom keras import backend as K"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"2d2d3e13-ad2f-db60-97eb-c369d05b9571"},"outputs":[],"source":"random.seed(2718)\nK.set_image_dim_ordering('th') \nprint(\"keras version: \", keras.__version__)\nprint(\"keras image dimension ordering: \", keras.backend.image_dim_ordering())"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"a811f307-478f-d4ee-51c6-13c7d01dd7c2"},"outputs":[],"source":"TRAIN_DIR = '../input/train/'\nTEST_DIR =  '../input/test/'\n\nROWS = 64\nCOLS = 64\nCHANNELS = 3\n\ntrain_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)] # use this for full dataset\ntrain_dogs =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'dog' in i]\ntrain_cats =   [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR) if 'cat' in i]\n\ntest_images =  [TEST_DIR+i for i in os.listdir(TEST_DIR)]\n\n\n# slice datasets for memory efficiency on Kaggle Kernels, delete if using full dataset\ntrain_images = train_dogs[:100] + train_cats[:100]\nrandom.shuffle(train_images)\ntest_images =  test_images[:25]\n\ndef read_image(file_path):\n    im = imread(file_path)\n    im = resize(im, (ROWS, COLS))\n    return im\n    #img = cv2.imread(file_path, cv2.IMREAD_COLOR) #cv2.IMREAD_GRAYSCALE\n    #return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)\n\n\ndef prep_data(images):\n    count = len(images)\n    data = np.ndarray((count, CHANNELS, ROWS, COLS), dtype=np.uint8)\n\n    for i, image_file in enumerate(images):\n        image = read_image(image_file)\n        data[i] = image.T\n        if i%250 == 0: print('Processed {} of {}'.format(i, count))\n    \n    return data\n\ntrain = prep_data(train_images)\ntest  = prep_data(test_images)\n\nprint(\"Train shape: {}\".format(train.shape))\nprint(\"Test shape: {}\".format(test.shape))"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"ae957108-ee27-54ac-1c67-04cf30625cd1"},"outputs":[],"source":"labels = []\nfor i in train_images:\n    if 'dog' in i:\n        labels.append(1)\n    else:\n        labels.append(0)\n\nsns.countplot(labels)\nsns.plt.title('Cats and Dogs')"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"219bfa7e-0b46-2b51-2382-0619352f84e2"},"outputs":[],"source":"optimizer = RMSprop(lr=1e-4)\n\n#epochs = 25\n#lrate = 4.e-4\n#decay = lrate/epochs\n#optimizer = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)\n\n\nobjective = 'binary_crossentropy'\n\n\ndef catdog():\n    \n    model = Sequential()\n\n    model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(3, ROWS, COLS), activation='relu'))\n    model.add(Convolution2D(32, 3, 3, border_mode='same', activation='relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n\n    model.add(Convolution2D(64, 3, 3, border_mode='same', activation='relu'))\n    model.add(Convolution2D(64, 3, 3, border_mode='same', activation='relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    \n    model.add(Convolution2D(128, 3, 3, border_mode='same', activation='relu'))\n    model.add(Convolution2D(128, 3, 3, border_mode='same', activation='relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    \n    model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n    model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n#     model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n\n#     model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n#     model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n#     model.add(Convolution2D(256, 3, 3, border_mode='same', activation='relu'))\n#     model.add(MaxPooling2D(pool_size=(2, 2)))\n\n    model.add(Flatten())\n    model.add(Dense(256, activation='relu'))\n    model.add(Dropout(0.5))\n    \n    model.add(Dense(256, activation='relu'))\n    model.add(Dropout(0.5))\n\n    model.add(Dense(1))\n    model.add(Activation('sigmoid'))\n\n    model.compile(loss=objective, optimizer=optimizer, metrics=['accuracy'])\n    return model\n\n\nmodel = catdog()"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"5e8fcac4-afd7-9a81-f79f-c71b7dd3fb4e"},"outputs":[],"source":"nb_epoch = 10\nbatch_size = 100\n\n## Callback for loss logging per epoch\nclass LossHistory(Callback):\n    def on_train_begin(self, logs={}):\n        self.losses = []\n        self.val_losses = []\n        \n    def on_epoch_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=3, verbose=1, mode='auto')        \n        \ndef run_catdog():\n    \n    history = LossHistory()\n    model.fit(train, labels, batch_size=batch_size, nb_epoch=nb_epoch,\n              validation_split=0.25, verbose=0, shuffle=True, callbacks=[history])\n    \n\n    predictions = model.predict(test, verbose=0)\n    return  predictions, history\n\npredictions, history = run_catdog()"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"5d2eb580-b4ca-23a3-8881-81e460ed6a20"},"outputs":[],"source":"loss = history.losses\nval_loss = history.val_losses\n\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.title('VGG-16 Loss Trend')\nplt.plot(loss, 'blue', label='Training Loss')\nplt.plot(val_loss, 'green', label='Validation Loss')\nplt.xticks(range(0,nb_epoch)[0::2])\nplt.legend()\nplt.show()"},{"cell_type":"markdown","metadata":{"_cell_guid":"c359698b-39bc-2ce8-4f17-63beaa445981"},"source":"This looks like a strong proof that the problems I had running Jeff Delaney kernel on my laptop are due to the fact that I use skimage imread and resize. If I use the same code but read the input images with cv2 I get a proper behavior for the validation loss."},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"d057f87a-de4c-d3af-db70-d2d8d6241685"},"outputs":[],"source":""}],"metadata":{"_change_revision":0,"_is_fork":false,"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.5.2"}},"nbformat":4,"nbformat_minor":0}