{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using gpu device 0: GeForce GTX TITAN X (CNMeM is enabled with initial size: 90.0% of memory, cuDNN 4007)\n" ] } ], "source": [ "from theano.sandbox import cuda\n", "cuda.use('gpu0')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using Theano backend.\n" ] } ], "source": [ "%matplotlib inline\n", "import utils; reload(utils)\n", "from utils import *\n", "from __future__ import division, print_function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setup" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "path = \"data/dogscats/\"\n", "model_path = path + 'models/'\n", "if not os.path.exists(model_path): os.mkdir(model_path)\n", "\n", "batch_size=64" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 23000 images belonging to 2 classes.\n", "Found 2000 images belonging to 2 classes.\n" ] } ], "source": [ "batches = get_batches(path+'train', shuffle=False, batch_size=batch_size)\n", "val_batches = get_batches(path+'valid', shuffle=False, batch_size=batch_size)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 23000 images belonging to 2 classes.\n", "Found 2000 images belonging to 2 classes.\n", "Found 0 images belonging to 0 classes.\n" ] } ], "source": [ "(val_classes, trn_classes, val_labels, trn_labels, \n", " val_filenames, filenames, test_filenames) = get_classes(path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook we're going to create an ensemble of models and use their average as our predictions. For each ensemble, we're going to follow our usual fine-tuning steps:\n", "\n", "1) Create a model that retrains just the last layer\n", "2) Add this to a model containing all VGG layers except the last layer\n", "3) Fine-tune just the dense layers of this model (pre-computing the convolutional layers)\n", "4) Add data augmentation, fine-tuning the dense layers without pre-computation.\n", "\n", "So first, we need to create our VGG model and pre-compute the output of the conv layers:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "model = Vgg16().model\n", "conv_layers,fc_layers = split_at(model, Convolution2D)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "conv_model = Sequential(conv_layers)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "val_features = conv_model.predict_generator(val_batches, val_batches.nb_sample)\n", "trn_features = conv_model.predict_generator(batches, batches.nb_sample)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "save_array(model_path + 'train_convlayer_features.bc', trn_features)\n", "save_array(model_path + 'valid_convlayer_features.bc', val_features)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the future we can just load these precomputed features:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "trn_features = load_array(model_path+'train_convlayer_features.bc')\n", "val_features = load_array(model_path+'valid_convlayer_features.bc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also save some time by pre-computing the training and validation arrays with the image decoding and resizing already done:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 23000 images belonging to 2 classes.\n", "Found 2000 images belonging to 2 classes.\n" ] } ], "source": [ "trn = get_data(path+'train')\n", "val = get_data(path+'valid')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [], "source": [ "save_array(model_path+'train_data.bc', trn)\n", "save_array(model_path+'valid_data.bc', val)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the future we can just load these resized images:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "trn = load_array(model_path+'train_data.bc')\n", "val = load_array(model_path+'valid_data.bc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we can precompute the output of all but the last dropout and dense layers, for creating the first stage of the model:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "model.pop()\n", "model.pop()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ll_val_feat = model.predict_generator(val_batches, val_batches.nb_sample)\n", "ll_feat = model.predict_generator(batches, batches.nb_sample)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "save_array(model_path + 'train_ll_feat.bc', ll_feat)\n", "save_array(model_path + 'valid_ll_feat.bc', ll_val_feat)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ll_feat = load_array(model_path+ 'train_ll_feat.bc')\n", "ll_val_feat = load_array(model_path + 'valid_ll_feat.bc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "...and let's also grab the test data, for when we need to submit:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 12500 images belonging to 1 classes.\n" ] } ], "source": [ "test = get_data(path+'test')\n", "save_array(model_path+'test_data.bc', test)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [], "source": [ "test = load_array(model_path+'test_data.bc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Last layer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The functions automate creating a model that trains the last layer from scratch, and then adds those new layers on to the main model." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def get_ll_layers():\n", " return [ \n", " BatchNormalization(input_shape=(4096,)),\n", " Dropout(0.5),\n", " Dense(2, activation='softmax') \n", " ]" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def train_last_layer(i):\n", " ll_layers = get_ll_layers()\n", " ll_model = Sequential(ll_layers)\n", " ll_model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])\n", " ll_model.optimizer.lr=1e-5\n", " ll_model.fit(ll_feat, trn_labels, validation_data=(ll_val_feat, val_labels), nb_epoch=12)\n", " ll_model.optimizer.lr=1e-7\n", " ll_model.fit(ll_feat, trn_labels, validation_data=(ll_val_feat, val_labels), nb_epoch=1)\n", " ll_model.save_weights(model_path+'ll_bn' + i + '.h5')\n", "\n", " vgg = Vgg16()\n", " model = vgg.model\n", " model.pop(); model.pop(); model.pop()\n", " for layer in model.layers: layer.trainable=False\n", " model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])\n", "\n", " ll_layers = get_ll_layers()\n", " for layer in ll_layers: model.add(layer)\n", " for l1,l2 in zip(ll_model.layers, model.layers[-3:]):\n", " l2.set_weights(l1.get_weights())\n", " model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])\n", " model.save_weights(model_path+'bn' + i + '.h5')\n", " return model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dense model" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def get_conv_model(model):\n", " layers = model.layers\n", " last_conv_idx = [index for index,layer in enumerate(layers) \n", " if type(layer) is Convolution2D][-1]\n", "\n", " conv_layers = layers[:last_conv_idx+1]\n", " conv_model = Sequential(conv_layers)\n", " fc_layers = layers[last_conv_idx+1:]\n", " return conv_model, fc_layers, last_conv_idx" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def get_fc_layers(p, in_shape):\n", " return [\n", " MaxPooling2D(input_shape=in_shape),\n", " Flatten(),\n", " Dense(4096, activation='relu'),\n", " BatchNormalization(),\n", " Dropout(p),\n", " Dense(4096, activation='relu'),\n", " BatchNormalization(),\n", " Dropout(p),\n", " Dense(2, activation='softmax')\n", " ]" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def train_dense_layers(i, model):\n", " conv_model, fc_layers, last_conv_idx = get_conv_model(model)\n", " conv_shape = conv_model.output_shape[1:]\n", " fc_model = Sequential(get_fc_layers(0.5, conv_shape))\n", " for l1,l2 in zip(fc_model.layers, fc_layers): \n", " weights = l2.get_weights()\n", " l1.set_weights(weights)\n", " fc_model.compile(optimizer=Adam(1e-5), loss='categorical_crossentropy', \n", " metrics=['accuracy'])\n", " fc_model.fit(trn_features, trn_labels, nb_epoch=2, \n", " batch_size=batch_size, validation_data=(val_features, val_labels))\n", "\n", " gen = image.ImageDataGenerator(rotation_range=10, width_shift_range=0.05, \n", " width_zoom_range=0.05, zoom_range=0.05,\n", " channel_shift_range=10, height_shift_range=0.05, shear_range=0.05, horizontal_flip=True)\n", " batches = gen.flow(trn, trn_labels, batch_size=batch_size)\n", " val_batches = image.ImageDataGenerator().flow(val, val_labels, \n", " shuffle=False, batch_size=batch_size)\n", "\n", " for layer in conv_model.layers: layer.trainable = False\n", " for layer in get_fc_layers(0.5, conv_shape): conv_model.add(layer)\n", " for l1,l2 in zip(conv_model.layers[last_conv_idx+1:], fc_model.layers): \n", " l1.set_weights(l2.get_weights())\n", "\n", " conv_model.compile(optimizer=Adam(1e-5), loss='categorical_crossentropy', \n", " metrics=['accuracy'])\n", " conv_model.save_weights(model_path+'no_dropout_bn' + i + '.h5')\n", " conv_model.fit_generator(batches, samples_per_epoch=batches.N, nb_epoch=1, \n", " validation_data=val_batches, nb_val_samples=val_batches.N)\n", " for layer in conv_model.layers[16:]: layer.trainable = True\n", " conv_model.fit_generator(batches, samples_per_epoch=batches.N, nb_epoch=8, \n", " validation_data=val_batches, nb_val_samples=val_batches.N)\n", "\n", " conv_model.optimizer.lr = 1e-7\n", " conv_model.fit_generator(batches, samples_per_epoch=batches.N, nb_epoch=10, \n", " validation_data=val_batches, nb_val_samples=val_batches.N)\n", " conv_model.save_weights(model_path + 'aug' + i + '.h5')" ] }, { "cell_type": "markdown", "metadata": { "heading_collapsed": true }, "source": [ "## Build ensemble" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false, "hidden": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/12\n", "23000/23000 [==============================] - 0s - loss: 0.5184 - acc: 0.7895 - val_loss: 0.1549 - val_acc: 0.9440\n", "Epoch 2/12\n", "23000/23000 [==============================] - 0s - loss: 0.1984 - acc: 0.9237 - val_loss: 0.0941 - val_acc: 0.9670\n", "Epoch 3/12\n", "23000/23000 [==============================] - 0s - loss: 0.1524 - acc: 0.9426 - val_loss: 0.0762 - val_acc: 0.9735\n", "Epoch 4/12\n", "23000/23000 [==============================] - 0s - loss: 0.1247 - acc: 0.9542 - val_loss: 0.0662 - val_acc: 0.9740\n", "Epoch 5/12\n", "23000/23000 [==============================] - 0s - loss: 0.1128 - acc: 0.9567 - val_loss: 0.0609 - val_acc: 0.9760\n", "Epoch 6/12\n", "23000/23000 [==============================] - 0s - loss: 0.1043 - acc: 0.9635 - val_loss: 0.0560 - val_acc: 0.9775\n", "Epoch 7/12\n", "23000/23000 [==============================] - 0s - loss: 0.1010 - acc: 0.9640 - val_loss: 0.0548 - val_acc: 0.9790\n", "Epoch 8/12\n", "23000/23000 [==============================] - 0s - loss: 0.0980 - acc: 0.9650 - val_loss: 0.0526 - val_acc: 0.9780\n", "Epoch 9/12\n", "23000/23000 [==============================] - 0s - loss: 0.0926 - acc: 0.9656 - val_loss: 0.0513 - val_acc: 0.9785\n", "Epoch 10/12\n", "23000/23000 [==============================] - 0s - loss: 0.0881 - acc: 0.9680 - val_loss: 0.0500 - val_acc: 0.9795\n", "Epoch 11/12\n", "23000/23000 [==============================] - 0s - loss: 0.0933 - acc: 0.9666 - val_loss: 0.0497 - val_acc: 0.9800\n", "Epoch 12/12\n", "23000/23000 [==============================] - 0s - loss: 0.0842 - acc: 0.9693 - val_loss: 0.0484 - val_acc: 0.9805\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/1\n", "23000/23000 [==============================] - 0s - loss: 0.0824 - acc: 0.9696 - val_loss: 0.0486 - val_acc: 0.9805\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/2\n", "23000/23000 [==============================] - 21s - loss: 0.0798 - acc: 0.9719 - val_loss: 0.0500 - val_acc: 0.9830\n", "Epoch 2/2\n", "23000/23000 [==============================] - 21s - loss: 0.0415 - acc: 0.9853 - val_loss: 0.0551 - val_acc: 0.9840\n", "Epoch 1/1\n", "23000/23000 [==============================] - 271s - loss: 0.0559 - acc: 0.9814 - val_loss: 0.0578 - val_acc: 0.9825\n", "Epoch 1/8\n", "23000/23000 [==============================] - 271s - loss: 0.0515 - acc: 0.9834 - val_loss: 0.0645 - val_acc: 0.9860\n", "Epoch 2/8\n", "23000/23000 [==============================] - 271s - loss: 0.0385 - acc: 0.9875 - val_loss: 0.0670 - val_acc: 0.9850\n", "Epoch 3/8\n", "23000/23000 [==============================] - 271s - loss: 0.0313 - acc: 0.9890 - val_loss: 0.0715 - val_acc: 0.9850\n", "Epoch 4/8\n", "23000/23000 [==============================] - 271s - loss: 0.0287 - acc: 0.9903 - val_loss: 0.0733 - val_acc: 0.9840\n", "Epoch 5/8\n", "23000/23000 [==============================] - 271s - loss: 0.0244 - acc: 0.9924 - val_loss: 0.0773 - val_acc: 0.9840\n", "Epoch 6/8\n", "23000/23000 [==============================] - 271s - loss: 0.0205 - acc: 0.9927 - val_loss: 0.0900 - val_acc: 0.9845\n", "Epoch 7/8\n", "23000/23000 [==============================] - 271s - loss: 0.0209 - acc: 0.9929 - val_loss: 0.0860 - val_acc: 0.9865\n", "Epoch 8/8\n", "23000/23000 [==============================] - 420s - loss: 0.0186 - acc: 0.9930 - val_loss: 0.0923 - val_acc: 0.9845\n", "Epoch 1/10\n", "23000/23000 [==============================] - 315s - loss: 0.0196 - acc: 0.9930 - val_loss: 0.0909 - val_acc: 0.9845\n", "Epoch 2/10\n", "23000/23000 [==============================] - 362s - loss: 0.0165 - acc: 0.9945 - val_loss: 0.1023 - val_acc: 0.9830\n", "Epoch 3/10\n", "23000/23000 [==============================] - 447s - loss: 0.0179 - acc: 0.9940 - val_loss: 0.0871 - val_acc: 0.9845\n", "Epoch 4/10\n", "23000/23000 [==============================] - 601s - loss: 0.0112 - acc: 0.9960 - val_loss: 0.1030 - val_acc: 0.9830\n", "Epoch 5/10\n", "23000/23000 [==============================] - 528s - loss: 0.0130 - acc: 0.9956 - val_loss: 0.0946 - val_acc: 0.9830\n", "Epoch 6/10\n", "23000/23000 [==============================] - 657s - loss: 0.0110 - acc: 0.9961 - val_loss: 0.0904 - val_acc: 0.9850\n", "Epoch 7/10\n", "23000/23000 [==============================] - 621s - loss: 0.0116 - acc: 0.9963 - val_loss: 0.0872 - val_acc: 0.9865\n", "Epoch 8/10\n", "23000/23000 [==============================] - 603s - loss: 0.0118 - acc: 0.9960 - val_loss: 0.0813 - val_acc: 0.9870\n", "Epoch 9/10\n", "23000/23000 [==============================] - 616s - loss: 0.0100 - acc: 0.9967 - val_loss: 0.1053 - val_acc: 0.9835\n", "Epoch 10/10\n", "23000/23000 [==============================] - 661s - loss: 0.0098 - acc: 0.9968 - val_loss: 0.0970 - val_acc: 0.9840\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/12\n", "23000/23000 [==============================] - 0s - loss: 0.5106 - acc: 0.7935 - val_loss: 0.1504 - val_acc: 0.9455\n", "Epoch 2/12\n", "23000/23000 [==============================] - 0s - loss: 0.2005 - acc: 0.9241 - val_loss: 0.0890 - val_acc: 0.9680\n", "Epoch 3/12\n", "23000/23000 [==============================] - 0s - loss: 0.1465 - acc: 0.9444 - val_loss: 0.0714 - val_acc: 0.9745\n", "Epoch 4/12\n", "23000/23000 [==============================] - 0s - loss: 0.1280 - acc: 0.9540 - val_loss: 0.0614 - val_acc: 0.9765\n", "Epoch 5/12\n", "23000/23000 [==============================] - 0s - loss: 0.1131 - acc: 0.9586 - val_loss: 0.0561 - val_acc: 0.9795\n", "Epoch 6/12\n", "23000/23000 [==============================] - 0s - loss: 0.1079 - acc: 0.9620 - val_loss: 0.0515 - val_acc: 0.9795\n", "Epoch 7/12\n", "23000/23000 [==============================] - 0s - loss: 0.0998 - acc: 0.9631 - val_loss: 0.0484 - val_acc: 0.9825\n", "Epoch 8/12\n", "23000/23000 [==============================] - 0s - loss: 0.0947 - acc: 0.9673 - val_loss: 0.0457 - val_acc: 0.9845\n", "Epoch 9/12\n", "23000/23000 [==============================] - 0s - loss: 0.0913 - acc: 0.9676 - val_loss: 0.0449 - val_acc: 0.9855\n", "Epoch 10/12\n", "23000/23000 [==============================] - 0s - loss: 0.0921 - acc: 0.9670 - val_loss: 0.0451 - val_acc: 0.9845\n", "Epoch 11/12\n", "23000/23000 [==============================] - 0s - loss: 0.0893 - acc: 0.9681 - val_loss: 0.0441 - val_acc: 0.9840\n", "Epoch 12/12\n", "23000/23000 [==============================] - 0s - loss: 0.0836 - acc: 0.9691 - val_loss: 0.0428 - val_acc: 0.9850\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/1\n", "23000/23000 [==============================] - 0s - loss: 0.0833 - acc: 0.9718 - val_loss: 0.0434 - val_acc: 0.9850\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/2\n", "23000/23000 [==============================] - 21s - loss: 0.0814 - acc: 0.9736 - val_loss: 0.0463 - val_acc: 0.9850\n", "Epoch 2/2\n", "23000/23000 [==============================] - 21s - loss: 0.0389 - acc: 0.9859 - val_loss: 0.0493 - val_acc: 0.9850\n", "Epoch 1/1\n", "23000/23000 [==============================] - 271s - loss: 0.0613 - acc: 0.9807 - val_loss: 0.0563 - val_acc: 0.9855\n", "Epoch 1/8\n", "23000/23000 [==============================] - 325s - loss: 0.0450 - acc: 0.9860 - val_loss: 0.0685 - val_acc: 0.9840\n", "Epoch 2/8\n", "23000/23000 [==============================] - 766s - loss: 0.0364 - acc: 0.9877 - val_loss: 0.0616 - val_acc: 0.9845\n", "Epoch 3/8\n", "23000/23000 [==============================] - 600s - loss: 0.0338 - acc: 0.9891 - val_loss: 0.0585 - val_acc: 0.9845\n", "Epoch 4/8\n", "23000/23000 [==============================] - 634s - loss: 0.0288 - acc: 0.9903 - val_loss: 0.0740 - val_acc: 0.9845\n", "Epoch 5/8\n", "23000/23000 [==============================] - 791s - loss: 0.0265 - acc: 0.9904 - val_loss: 0.0789 - val_acc: 0.9840\n", "Epoch 6/8\n", "23000/23000 [==============================] - 780s - loss: 0.0254 - acc: 0.9909 - val_loss: 0.0853 - val_acc: 0.9855\n", "Epoch 7/8\n", "23000/23000 [==============================] - 680s - loss: 0.0180 - acc: 0.9937 - val_loss: 0.0747 - val_acc: 0.9870\n", "Epoch 8/8\n", "23000/23000 [==============================] - 776s - loss: 0.0191 - acc: 0.9939 - val_loss: 0.0871 - val_acc: 0.9845\n", "Epoch 1/10\n", "23000/23000 [==============================] - 712s - loss: 0.0191 - acc: 0.9929 - val_loss: 0.0943 - val_acc: 0.9855\n", "Epoch 2/10\n", "23000/23000 [==============================] - 679s - loss: 0.0175 - acc: 0.9946 - val_loss: 0.0723 - val_acc: 0.9850\n", "Epoch 3/10\n", "23000/23000 [==============================] - 640s - loss: 0.0148 - acc: 0.9949 - val_loss: 0.0756 - val_acc: 0.9845\n", "Epoch 4/10\n", "23000/23000 [==============================] - 761s - loss: 0.0147 - acc: 0.9953 - val_loss: 0.0772 - val_acc: 0.9850\n", "Epoch 5/10\n", "23000/23000 [==============================] - 733s - loss: 0.0163 - acc: 0.9946 - val_loss: 0.0931 - val_acc: 0.9830\n", "Epoch 6/10\n", "23000/23000 [==============================] - 574s - loss: 0.0107 - acc: 0.9967 - val_loss: 0.0874 - val_acc: 0.9845\n", "Epoch 7/10\n", "23000/23000 [==============================] - 611s - loss: 0.0123 - acc: 0.9958 - val_loss: 0.0918 - val_acc: 0.9855\n", "Epoch 8/10\n", "23000/23000 [==============================] - 668s - loss: 0.0098 - acc: 0.9965 - val_loss: 0.0896 - val_acc: 0.9855\n", "Epoch 9/10\n", "23000/23000 [==============================] - 624s - loss: 0.0096 - acc: 0.9964 - val_loss: 0.1012 - val_acc: 0.9850\n", "Epoch 10/10\n", "23000/23000 [==============================] - 747s - loss: 0.0113 - acc: 0.9960 - val_loss: 0.0961 - val_acc: 0.9835\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/12\n", "23000/23000 [==============================] - 1s - loss: 0.5167 - acc: 0.7867 - val_loss: 0.1299 - val_acc: 0.9555\n", "Epoch 2/12\n", "23000/23000 [==============================] - 0s - loss: 0.1922 - acc: 0.9265 - val_loss: 0.0803 - val_acc: 0.9695\n", "Epoch 3/12\n", "23000/23000 [==============================] - 0s - loss: 0.1461 - acc: 0.9454 - val_loss: 0.0646 - val_acc: 0.9745\n", "Epoch 4/12\n", "23000/23000 [==============================] - 0s - loss: 0.1255 - acc: 0.9536 - val_loss: 0.0543 - val_acc: 0.9790\n", "Epoch 5/12\n", "23000/23000 [==============================] - 0s - loss: 0.1113 - acc: 0.9608 - val_loss: 0.0505 - val_acc: 0.9820\n", "Epoch 6/12\n", "23000/23000 [==============================] - 0s - loss: 0.1058 - acc: 0.9607 - val_loss: 0.0464 - val_acc: 0.9825\n", "Epoch 7/12\n", "23000/23000 [==============================] - 0s - loss: 0.0957 - acc: 0.9654 - val_loss: 0.0448 - val_acc: 0.9840\n", "Epoch 8/12\n", "23000/23000 [==============================] - 0s - loss: 0.0964 - acc: 0.9657 - val_loss: 0.0427 - val_acc: 0.9850\n", "Epoch 9/12\n", "23000/23000 [==============================] - 0s - loss: 0.0996 - acc: 0.9662 - val_loss: 0.0420 - val_acc: 0.9860\n", "Epoch 10/12\n", "23000/23000 [==============================] - 0s - loss: 0.0931 - acc: 0.9670 - val_loss: 0.0408 - val_acc: 0.9855\n", "Epoch 11/12\n", "23000/23000 [==============================] - 0s - loss: 0.0899 - acc: 0.9680 - val_loss: 0.0395 - val_acc: 0.9860\n", "Epoch 12/12\n", "23000/23000 [==============================] - 0s - loss: 0.0837 - acc: 0.9717 - val_loss: 0.0390 - val_acc: 0.9860\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/1\n", "23000/23000 [==============================] - 0s - loss: 0.0861 - acc: 0.9703 - val_loss: 0.0391 - val_acc: 0.9865\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/2\n", "23000/23000 [==============================] - 21s - loss: 0.0796 - acc: 0.9735 - val_loss: 0.0382 - val_acc: 0.9855\n", "Epoch 2/2\n", "23000/23000 [==============================] - 21s - loss: 0.0353 - acc: 0.9874 - val_loss: 0.0364 - val_acc: 0.9880\n", "Epoch 1/1\n", "23000/23000 [==============================] - 271s - loss: 0.0622 - acc: 0.9802 - val_loss: 0.0490 - val_acc: 0.9870\n", "Epoch 1/8\n", "23000/23000 [==============================] - 773s - loss: 0.0426 - acc: 0.9856 - val_loss: 0.0442 - val_acc: 0.9885\n", "Epoch 2/8\n", "23000/23000 [==============================] - 774s - loss: 0.0394 - acc: 0.9864 - val_loss: 0.0501 - val_acc: 0.9885\n", "Epoch 3/8\n", "23000/23000 [==============================] - 687s - loss: 0.0329 - acc: 0.9881 - val_loss: 0.0500 - val_acc: 0.9875\n", "Epoch 4/8\n", "23000/23000 [==============================] - 655s - loss: 0.0292 - acc: 0.9900 - val_loss: 0.0535 - val_acc: 0.9870\n", "Epoch 5/8\n", "23000/23000 [==============================] - 791s - loss: 0.0268 - acc: 0.9914 - val_loss: 0.0605 - val_acc: 0.9855\n", "Epoch 6/8\n", "23000/23000 [==============================] - 789s - loss: 0.0208 - acc: 0.9926 - val_loss: 0.0591 - val_acc: 0.9850\n", "Epoch 7/8\n", "23000/23000 [==============================] - 798s - loss: 0.0191 - acc: 0.9931 - val_loss: 0.0638 - val_acc: 0.9860\n", "Epoch 8/8\n", "23000/23000 [==============================] - 708s - loss: 0.0192 - acc: 0.9932 - val_loss: 0.0597 - val_acc: 0.9850\n", "Epoch 1/10\n", "23000/23000 [==============================] - 606s - loss: 0.0178 - acc: 0.9942 - val_loss: 0.0620 - val_acc: 0.9860\n", "Epoch 2/10\n", "23000/23000 [==============================] - 756s - loss: 0.0158 - acc: 0.9941 - val_loss: 0.0694 - val_acc: 0.9850\n", "Epoch 3/10\n", "23000/23000 [==============================] - 418s - loss: 0.0176 - acc: 0.9939 - val_loss: 0.0641 - val_acc: 0.9855\n", "Epoch 4/10\n", "23000/23000 [==============================] - 271s - loss: 0.0118 - acc: 0.9958 - val_loss: 0.0623 - val_acc: 0.9840\n", "Epoch 5/10\n", "23000/23000 [==============================] - 271s - loss: 0.0150 - acc: 0.9947 - val_loss: 0.0649 - val_acc: 0.9865\n", "Epoch 6/10\n", "23000/23000 [==============================] - 271s - loss: 0.0119 - acc: 0.9961 - val_loss: 0.0595 - val_acc: 0.9880\n", "Epoch 7/10\n", "23000/23000 [==============================] - 304s - loss: 0.0121 - acc: 0.9957 - val_loss: 0.0668 - val_acc: 0.9885\n", "Epoch 8/10\n", "23000/23000 [==============================] - 273s - loss: 0.0124 - acc: 0.9960 - val_loss: 0.0619 - val_acc: 0.9885\n", "Epoch 9/10\n", "23000/23000 [==============================] - 271s - loss: 0.0099 - acc: 0.9963 - val_loss: 0.0649 - val_acc: 0.9865\n", "Epoch 10/10\n", "23000/23000 [==============================] - 273s - loss: 0.0091 - acc: 0.9970 - val_loss: 0.0628 - val_acc: 0.9890\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/12\n", "23000/23000 [==============================] - 0s - loss: 0.4585 - acc: 0.8130 - val_loss: 0.1306 - val_acc: 0.9515\n", "Epoch 2/12\n", "23000/23000 [==============================] - 0s - loss: 0.1920 - acc: 0.9270 - val_loss: 0.0863 - val_acc: 0.9655\n", "Epoch 3/12\n", "23000/23000 [==============================] - 0s - loss: 0.1504 - acc: 0.9450 - val_loss: 0.0705 - val_acc: 0.9740\n", "Epoch 4/12\n", "23000/23000 [==============================] - 0s - loss: 0.1275 - acc: 0.9529 - val_loss: 0.0592 - val_acc: 0.9795\n", "Epoch 5/12\n", "23000/23000 [==============================] - 0s - loss: 0.1190 - acc: 0.9555 - val_loss: 0.0555 - val_acc: 0.9815\n", "Epoch 6/12\n", "23000/23000 [==============================] - 0s - loss: 0.1068 - acc: 0.9609 - val_loss: 0.0536 - val_acc: 0.9805\n", "Epoch 7/12\n", "23000/23000 [==============================] - 0s - loss: 0.1003 - acc: 0.9624 - val_loss: 0.0496 - val_acc: 0.9830\n", "Epoch 8/12\n", "23000/23000 [==============================] - 0s - loss: 0.0979 - acc: 0.9660 - val_loss: 0.0482 - val_acc: 0.9825\n", "Epoch 9/12\n", "23000/23000 [==============================] - 0s - loss: 0.0913 - acc: 0.9678 - val_loss: 0.0475 - val_acc: 0.9830\n", "Epoch 10/12\n", "23000/23000 [==============================] - 0s - loss: 0.0917 - acc: 0.9666 - val_loss: 0.0458 - val_acc: 0.9825\n", "Epoch 11/12\n", "23000/23000 [==============================] - 0s - loss: 0.0980 - acc: 0.9665 - val_loss: 0.0454 - val_acc: 0.9840\n", "Epoch 12/12\n", "23000/23000 [==============================] - 0s - loss: 0.0919 - acc: 0.9675 - val_loss: 0.0443 - val_acc: 0.9840\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/1\n", "23000/23000 [==============================] - 0s - loss: 0.0883 - acc: 0.9685 - val_loss: 0.0440 - val_acc: 0.9850\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/2\n", "23000/23000 [==============================] - 21s - loss: 0.0825 - acc: 0.9720 - val_loss: 0.0437 - val_acc: 0.9850\n", "Epoch 2/2\n", "23000/23000 [==============================] - 21s - loss: 0.0359 - acc: 0.9874 - val_loss: 0.0474 - val_acc: 0.9850\n", "Epoch 1/1\n", "23000/23000 [==============================] - 272s - loss: 0.0581 - acc: 0.9817 - val_loss: 0.0562 - val_acc: 0.9850\n", "Epoch 1/8\n", "23000/23000 [==============================] - 520s - loss: 0.0486 - acc: 0.9833 - val_loss: 0.0590 - val_acc: 0.9830\n", "Epoch 2/8\n", "23000/23000 [==============================] - 745s - loss: 0.0379 - acc: 0.9867 - val_loss: 0.0595 - val_acc: 0.9840\n", "Epoch 3/8\n", "23000/23000 [==============================] - 736s - loss: 0.0329 - acc: 0.9881 - val_loss: 0.0628 - val_acc: 0.9840\n", "Epoch 4/8\n", "23000/23000 [==============================] - 708s - loss: 0.0260 - acc: 0.9903 - val_loss: 0.0722 - val_acc: 0.9855\n", "Epoch 5/8\n", "23000/23000 [==============================] - 700s - loss: 0.0250 - acc: 0.9921 - val_loss: 0.0734 - val_acc: 0.9840\n", "Epoch 6/8\n", "23000/23000 [==============================] - 802s - loss: 0.0212 - acc: 0.9923 - val_loss: 0.0721 - val_acc: 0.9845\n", "Epoch 7/8\n", "23000/23000 [==============================] - 765s - loss: 0.0211 - acc: 0.9928 - val_loss: 0.0772 - val_acc: 0.9835\n", "Epoch 8/8\n", "23000/23000 [==============================] - 743s - loss: 0.0185 - acc: 0.9933 - val_loss: 0.0756 - val_acc: 0.9835\n", "Epoch 1/10\n", "23000/23000 [==============================] - 782s - loss: 0.0168 - acc: 0.9941 - val_loss: 0.0815 - val_acc: 0.9860\n", "Epoch 2/10\n", "23000/23000 [==============================] - 580s - loss: 0.0155 - acc: 0.9942 - val_loss: 0.0771 - val_acc: 0.9840\n", "Epoch 3/10\n", "23000/23000 [==============================] - 654s - loss: 0.0142 - acc: 0.9954 - val_loss: 0.0789 - val_acc: 0.9850\n", "Epoch 4/10\n", "23000/23000 [==============================] - 692s - loss: 0.0141 - acc: 0.9955 - val_loss: 0.0716 - val_acc: 0.9870\n", "Epoch 5/10\n", "23000/23000 [==============================] - 607s - loss: 0.0120 - acc: 0.9959 - val_loss: 0.0757 - val_acc: 0.9850\n", "Epoch 6/10\n", "23000/23000 [==============================] - 789s - loss: 0.0129 - acc: 0.9956 - val_loss: 0.0741 - val_acc: 0.9860\n", "Epoch 7/10\n", "23000/23000 [==============================] - 767s - loss: 0.0111 - acc: 0.9960 - val_loss: 0.0747 - val_acc: 0.9865\n", "Epoch 8/10\n", "23000/23000 [==============================] - 557s - loss: 0.0103 - acc: 0.9967 - val_loss: 0.0774 - val_acc: 0.9870\n", "Epoch 9/10\n", "23000/23000 [==============================] - 521s - loss: 0.0106 - acc: 0.9962 - val_loss: 0.0855 - val_acc: 0.9855\n", "Epoch 10/10\n", "23000/23000 [==============================] - 484s - loss: 0.0095 - acc: 0.9970 - val_loss: 0.0780 - val_acc: 0.9850\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/12\n", "23000/23000 [==============================] - 0s - loss: 0.5435 - acc: 0.7783 - val_loss: 0.1669 - val_acc: 0.9440\n", "Epoch 2/12\n", "23000/23000 [==============================] - 0s - loss: 0.2054 - acc: 0.9227 - val_loss: 0.0999 - val_acc: 0.9675\n", "Epoch 3/12\n", "23000/23000 [==============================] - 0s - loss: 0.1549 - acc: 0.9405 - val_loss: 0.0763 - val_acc: 0.9725\n", "Epoch 4/12\n", "23000/23000 [==============================] - 0s - loss: 0.1327 - acc: 0.9520 - val_loss: 0.0642 - val_acc: 0.9755\n", "Epoch 5/12\n", "23000/23000 [==============================] - 0s - loss: 0.1147 - acc: 0.9573 - val_loss: 0.0590 - val_acc: 0.9790\n", "Epoch 6/12\n", "23000/23000 [==============================] - 0s - loss: 0.1078 - acc: 0.9605 - val_loss: 0.0545 - val_acc: 0.9815\n", "Epoch 7/12\n", "23000/23000 [==============================] - 0s - loss: 0.1001 - acc: 0.9631 - val_loss: 0.0526 - val_acc: 0.9820\n", "Epoch 8/12\n", "23000/23000 [==============================] - 0s - loss: 0.0977 - acc: 0.9654 - val_loss: 0.0515 - val_acc: 0.9815\n", "Epoch 9/12\n", "23000/23000 [==============================] - 0s - loss: 0.0937 - acc: 0.9660 - val_loss: 0.0497 - val_acc: 0.9825\n", "Epoch 10/12\n", "23000/23000 [==============================] - 0s - loss: 0.0942 - acc: 0.9683 - val_loss: 0.0489 - val_acc: 0.9835\n", "Epoch 11/12\n", "23000/23000 [==============================] - 0s - loss: 0.0904 - acc: 0.9687 - val_loss: 0.0473 - val_acc: 0.9830\n", "Epoch 12/12\n", "23000/23000 [==============================] - 0s - loss: 0.0855 - acc: 0.9689 - val_loss: 0.0469 - val_acc: 0.9840\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/1\n", "23000/23000 [==============================] - 0s - loss: 0.0861 - acc: 0.9685 - val_loss: 0.0470 - val_acc: 0.9840\n", "Train on 23000 samples, validate on 2000 samples\n", "Epoch 1/2\n", "23000/23000 [==============================] - 21s - loss: 0.0846 - acc: 0.9719 - val_loss: 0.0510 - val_acc: 0.9845\n", "Epoch 2/2\n", "23000/23000 [==============================] - 21s - loss: 0.0392 - acc: 0.9866 - val_loss: 0.0548 - val_acc: 0.9860\n", "Epoch 1/1\n", "23000/23000 [==============================] - 273s - loss: 0.0585 - acc: 0.9800 - val_loss: 0.0608 - val_acc: 0.9875\n", "Epoch 1/8\n", "23000/23000 [==============================] - 677s - loss: 0.0456 - acc: 0.9845 - val_loss: 0.0690 - val_acc: 0.9840\n", "Epoch 2/8\n", "23000/23000 [==============================] - 654s - loss: 0.0398 - acc: 0.9859 - val_loss: 0.0763 - val_acc: 0.9835\n", "Epoch 3/8\n", "23000/23000 [==============================] - 711s - loss: 0.0304 - acc: 0.9894 - val_loss: 0.0662 - val_acc: 0.9840\n", "Epoch 4/8\n", "23000/23000 [==============================] - 646s - loss: 0.0252 - acc: 0.9913 - val_loss: 0.0747 - val_acc: 0.9845\n", "Epoch 5/8\n", "23000/23000 [==============================] - 726s - loss: 0.0246 - acc: 0.9909 - val_loss: 0.0809 - val_acc: 0.9850\n", "Epoch 6/8\n", "23000/23000 [==============================] - 582s - loss: 0.0182 - acc: 0.9933 - val_loss: 0.0715 - val_acc: 0.9850\n", "Epoch 7/8\n", "23000/23000 [==============================] - 627s - loss: 0.0201 - acc: 0.9928 - val_loss: 0.0789 - val_acc: 0.9850\n", "Epoch 8/8\n", "23000/23000 [==============================] - 674s - loss: 0.0172 - acc: 0.9944 - val_loss: 0.0717 - val_acc: 0.9855\n", "Epoch 1/10\n", "23000/23000 [==============================] - 736s - loss: 0.0171 - acc: 0.9939 - val_loss: 0.0820 - val_acc: 0.9850\n", "Epoch 2/10\n", "23000/23000 [==============================] - 634s - loss: 0.0184 - acc: 0.9941 - val_loss: 0.0829 - val_acc: 0.9860\n", "Epoch 3/10\n", "23000/23000 [==============================] - 599s - loss: 0.0156 - acc: 0.9946 - val_loss: 0.0863 - val_acc: 0.9865\n", "Epoch 4/10\n", "23000/23000 [==============================] - 717s - loss: 0.0142 - acc: 0.9952 - val_loss: 0.0903 - val_acc: 0.9850\n", "Epoch 5/10\n", "23000/23000 [==============================] - 809s - loss: 0.0116 - acc: 0.9960 - val_loss: 0.0883 - val_acc: 0.9860\n", "Epoch 6/10\n", "23000/23000 [==============================] - 754s - loss: 0.0127 - acc: 0.9953 - val_loss: 0.0887 - val_acc: 0.9855\n", "Epoch 7/10\n", "23000/23000 [==============================] - 499s - loss: 0.0100 - acc: 0.9964 - val_loss: 0.0835 - val_acc: 0.9850\n", "Epoch 8/10\n", "23000/23000 [==============================] - 317s - loss: 0.0090 - acc: 0.9971 - val_loss: 0.0804 - val_acc: 0.9870\n", "Epoch 9/10\n", "23000/23000 [==============================] - 301s - loss: 0.0111 - acc: 0.9963 - val_loss: 0.0869 - val_acc: 0.9865\n", "Epoch 10/10\n", "23000/23000 [==============================] - 442s - loss: 0.0079 - acc: 0.9971 - val_loss: 0.0805 - val_acc: 0.9870\n" ] } ], "source": [ "for i in range(5):\n", " i = str(i)\n", " model = train_last_layer(i)\n", " train_dense_layers(i, model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Combine ensemble and test" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ens_model = vgg_ft(2)\n", "for layer in ens_model.layers: layer.trainable=True" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def get_ens_pred(arr, fname):\n", " ens_pred = []\n", " for i in range(5):\n", " i = str(i)\n", " ens_model.load_weights('{}{}{}.h5'.format(model_path, fname, i))\n", " preds = ens_model.predict(arr, batch_size=batch_size)\n", " ens_pred.append(preds)\n", " return ens_pred" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val_pred2 = get_ens_pred(val, 'aug')" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": true }, "outputs": [], "source": [ "val_avg_preds2 = np.stack(val_pred2).mean(axis=0)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array(0.9894999861717224, dtype=float32)" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "categorical_accuracy(val_labels, val_avg_preds2).eval()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" }, "nav_menu": {}, "toc": { "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 6, "toc_cell": false, "toc_section_display": "block", "toc_window_display": false }, "widgets": { "state": {}, "version": "1.1.2" } }, "nbformat": 4, "nbformat_minor": 1 }