Created
February 23, 2018 15:24
-
-
Save carlos-aguayo/c14c5535e3ac6dbc31600d46421f3ffd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"/home/ubuntu/anaconda3/envs/tensorflow_p27/lib/python2.7/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", | |
" from ._conv import register_converters as _register_converters\n", | |
"Using TensorFlow backend.\n", | |
"/home/ubuntu/anaconda3/envs/tensorflow_p27/lib/python2.7/site-packages/matplotlib/__init__.py:962: UserWarning: Duplicate key in file \"/home/ubuntu/.config/matplotlib/matplotlibrc\", line #2\n", | |
" (fname, cnt))\n", | |
"/home/ubuntu/anaconda3/envs/tensorflow_p27/lib/python2.7/site-packages/matplotlib/__init__.py:962: UserWarning: Duplicate key in file \"/home/ubuntu/.config/matplotlib/matplotlibrc\", line #3\n", | |
" (fname, cnt))\n" | |
] | |
} | |
], | |
"source": [ | |
"from keras import applications\n", | |
"from keras.applications import VGG16\n", | |
"from keras.preprocessing.image import ImageDataGenerator\n", | |
"from keras import optimizers\n", | |
"from keras.models import Sequential\n", | |
"from keras.models import Model\n", | |
"from keras.layers import Dropout, Flatten, Dense" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# path to the model weights files.\n", | |
"weights_path = 'vgg16_weights.h5' # https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3\n", | |
"top_model_weights_path = 'bottleneck_fc_model.h5'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# dimensions of our images.\n", | |
"img_width, img_height = 150, 150\n", | |
"\n", | |
"train_data_dir = 'data/train'\n", | |
"validation_data_dir = 'data/validation'\n", | |
"nb_train_samples = 2000\n", | |
"nb_validation_samples = 800\n", | |
"epochs = 50\n", | |
"batch_size = 16" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Load VGG16, we will use that in a second**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Model loaded.\n" | |
] | |
} | |
], | |
"source": [ | |
"# build the VGG16 network\n", | |
"base_model = VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3))\n", | |
"print('Model loaded.')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Let's build a neural network and load it with the weights from Part 2**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"_________________________________________________________________\n", | |
"Layer (type) Output Shape Param # \n", | |
"=================================================================\n", | |
"flatten_1 (Flatten) (None, 8192) 0 \n", | |
"_________________________________________________________________\n", | |
"dense_1 (Dense) (None, 256) 2097408 \n", | |
"_________________________________________________________________\n", | |
"dropout_1 (Dropout) (None, 256) 0 \n", | |
"_________________________________________________________________\n", | |
"dense_2 (Dense) (None, 1) 257 \n", | |
"=================================================================\n", | |
"Total params: 2,097,665\n", | |
"Trainable params: 2,097,665\n", | |
"Non-trainable params: 0\n", | |
"_________________________________________________________________\n", | |
"None\n" | |
] | |
} | |
], | |
"source": [ | |
"# build a classifier model to put on top of the convolutional model\n", | |
"top_model = Sequential()\n", | |
"top_model.add(Flatten(input_shape=base_model.output_shape[1:]))\n", | |
"top_model.add(Dense(256, activation='relu'))\n", | |
"top_model.add(Dropout(0.5))\n", | |
"top_model.add(Dense(1, activation='sigmoid'))\n", | |
"\n", | |
"# note that it is necessary to start with a fully-trained\n", | |
"# classifier, including the top classifier,\n", | |
"# in order to successfully do fine-tuning\n", | |
"top_model.load_weights(top_model_weights_path)\n", | |
"\n", | |
"print top_model.summary()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"_________________________________________________________________\n", | |
"Layer (type) Output Shape Param # \n", | |
"=================================================================\n", | |
"input_1 (InputLayer) (None, 150, 150, 3) 0 \n", | |
"_________________________________________________________________\n", | |
"block1_conv1 (Conv2D) (None, 150, 150, 64) 1792 \n", | |
"_________________________________________________________________\n", | |
"block1_conv2 (Conv2D) (None, 150, 150, 64) 36928 \n", | |
"_________________________________________________________________\n", | |
"block1_pool (MaxPooling2D) (None, 75, 75, 64) 0 \n", | |
"_________________________________________________________________\n", | |
"block2_conv1 (Conv2D) (None, 75, 75, 128) 73856 \n", | |
"_________________________________________________________________\n", | |
"block2_conv2 (Conv2D) (None, 75, 75, 128) 147584 \n", | |
"_________________________________________________________________\n", | |
"block2_pool (MaxPooling2D) (None, 37, 37, 128) 0 \n", | |
"_________________________________________________________________\n", | |
"block3_conv1 (Conv2D) (None, 37, 37, 256) 295168 \n", | |
"_________________________________________________________________\n", | |
"block3_conv2 (Conv2D) (None, 37, 37, 256) 590080 \n", | |
"_________________________________________________________________\n", | |
"block3_conv3 (Conv2D) (None, 37, 37, 256) 590080 \n", | |
"_________________________________________________________________\n", | |
"block3_pool (MaxPooling2D) (None, 18, 18, 256) 0 \n", | |
"_________________________________________________________________\n", | |
"block4_conv1 (Conv2D) (None, 18, 18, 512) 1180160 \n", | |
"_________________________________________________________________\n", | |
"block4_conv2 (Conv2D) (None, 18, 18, 512) 2359808 \n", | |
"_________________________________________________________________\n", | |
"block4_conv3 (Conv2D) (None, 18, 18, 512) 2359808 \n", | |
"_________________________________________________________________\n", | |
"block4_pool (MaxPooling2D) (None, 9, 9, 512) 0 \n", | |
"_________________________________________________________________\n", | |
"block5_conv1 (Conv2D) (None, 9, 9, 512) 2359808 \n", | |
"_________________________________________________________________\n", | |
"block5_conv2 (Conv2D) (None, 9, 9, 512) 2359808 \n", | |
"_________________________________________________________________\n", | |
"block5_conv3 (Conv2D) (None, 9, 9, 512) 2359808 \n", | |
"_________________________________________________________________\n", | |
"block5_pool (MaxPooling2D) (None, 4, 4, 512) 0 \n", | |
"_________________________________________________________________\n", | |
"sequential_1 (Sequential) (None, 1) 2097665 \n", | |
"=================================================================\n", | |
"Total params: 16,812,353\n", | |
"Trainable params: 9,177,089\n", | |
"Non-trainable params: 7,635,264\n", | |
"_________________________________________________________________\n", | |
"None\n" | |
] | |
} | |
], | |
"source": [ | |
"# add the model on top of the convolutional base\n", | |
"# model.add(top_model)\n", | |
"model = Model(inputs=base_model.input, outputs=top_model(base_model.output))\n", | |
"\n", | |
"# set the first 25 layers (up to the last conv block)\n", | |
"# to non-trainable (weights will not be updated)\n", | |
"for layer in model.layers[:15]:\n", | |
" layer.trainable = False\n", | |
"\n", | |
"# compile the model with a SGD/momentum optimizer\n", | |
"# and a very slow learning rate.\n", | |
"model.compile(loss='binary_crossentropy',\n", | |
" optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),\n", | |
" metrics=['accuracy'])\n", | |
"\n", | |
"print model.summary()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Found 2000 images belonging to 2 classes.\n", | |
"Found 800 images belonging to 2 classes.\n" | |
] | |
} | |
], | |
"source": [ | |
"# prepare data augmentation configuration\n", | |
"train_datagen = ImageDataGenerator(\n", | |
" rescale=1. / 255,\n", | |
" shear_range=0.2,\n", | |
" zoom_range=0.2,\n", | |
" horizontal_flip=True)\n", | |
"\n", | |
"test_datagen = ImageDataGenerator(rescale=1. / 255)\n", | |
"\n", | |
"train_generator = train_datagen.flow_from_directory(\n", | |
" train_data_dir,\n", | |
" target_size=(img_height, img_width),\n", | |
" batch_size=batch_size,\n", | |
" class_mode='binary')\n", | |
"\n", | |
"validation_generator = test_datagen.flow_from_directory(\n", | |
" validation_data_dir,\n", | |
" target_size=(img_height, img_width),\n", | |
" batch_size=batch_size,\n", | |
" class_mode='binary')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"** Finally train the model! **" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Epoch 1/50\n", | |
"125/125 [==============================] - 22s 179ms/step - loss: 0.5183 - acc: 0.8350 - val_loss: 0.2734 - val_acc: 0.9100\n", | |
"Epoch 2/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.2378 - acc: 0.9095 - val_loss: 0.2529 - val_acc: 0.9050\n", | |
"Epoch 3/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.1763 - acc: 0.9410 - val_loss: 0.3169 - val_acc: 0.9075\n", | |
"Epoch 4/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.1411 - acc: 0.9500 - val_loss: 0.3348 - val_acc: 0.9075\n", | |
"Epoch 5/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.1235 - acc: 0.9520 - val_loss: 0.2526 - val_acc: 0.9137\n", | |
"Epoch 6/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.1013 - acc: 0.9620 - val_loss: 0.3191 - val_acc: 0.9075\n", | |
"Epoch 7/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0806 - acc: 0.9695 - val_loss: 0.3303 - val_acc: 0.9150\n", | |
"Epoch 8/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0605 - acc: 0.9785 - val_loss: 0.3676 - val_acc: 0.9187\n", | |
"Epoch 9/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0623 - acc: 0.9760 - val_loss: 0.3317 - val_acc: 0.9250\n", | |
"Epoch 10/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0761 - acc: 0.9745 - val_loss: 0.3928 - val_acc: 0.9237\n", | |
"Epoch 11/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0536 - acc: 0.9815 - val_loss: 0.2517 - val_acc: 0.9225\n", | |
"Epoch 12/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0484 - acc: 0.9845 - val_loss: 0.4273 - val_acc: 0.9225\n", | |
"Epoch 13/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0409 - acc: 0.9860 - val_loss: 0.3266 - val_acc: 0.9213\n", | |
"Epoch 14/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0404 - acc: 0.9855 - val_loss: 0.4019 - val_acc: 0.9150\n", | |
"Epoch 15/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0263 - acc: 0.9925 - val_loss: 0.3818 - val_acc: 0.9163\n", | |
"Epoch 16/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0275 - acc: 0.9905 - val_loss: 0.4401 - val_acc: 0.9250\n", | |
"Epoch 17/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0284 - acc: 0.9895 - val_loss: 0.3713 - val_acc: 0.9150\n", | |
"Epoch 18/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0285 - acc: 0.9900 - val_loss: 0.3477 - val_acc: 0.9263\n", | |
"Epoch 19/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0206 - acc: 0.9940 - val_loss: 0.3831 - val_acc: 0.9200\n", | |
"Epoch 20/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0157 - acc: 0.9910 - val_loss: 0.5340 - val_acc: 0.9125\n", | |
"Epoch 21/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0202 - acc: 0.9925 - val_loss: 0.4502 - val_acc: 0.9125\n", | |
"Epoch 22/50\n", | |
"125/125 [==============================] - 21s 164ms/step - loss: 0.0206 - acc: 0.9940 - val_loss: 0.5521 - val_acc: 0.9200\n", | |
"Epoch 23/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0190 - acc: 0.9935 - val_loss: 0.3896 - val_acc: 0.9225\n", | |
"Epoch 24/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0122 - acc: 0.9950 - val_loss: 0.4255 - val_acc: 0.9313\n", | |
"Epoch 25/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.0084 - acc: 0.9970 - val_loss: 0.4214 - val_acc: 0.9200\n", | |
"Epoch 26/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0058 - acc: 0.9985 - val_loss: 0.3923 - val_acc: 0.9250\n", | |
"Epoch 27/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0224 - acc: 0.9925 - val_loss: 0.4568 - val_acc: 0.9287\n", | |
"Epoch 28/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0379 - acc: 0.9920 - val_loss: 0.3002 - val_acc: 0.9250\n", | |
"Epoch 29/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.0285 - acc: 0.9945 - val_loss: 0.5268 - val_acc: 0.9137\n", | |
"Epoch 30/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0400 - acc: 0.9875 - val_loss: 0.3688 - val_acc: 0.9225\n", | |
"Epoch 31/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0102 - acc: 0.9955 - val_loss: 0.4523 - val_acc: 0.9313\n", | |
"Epoch 32/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0054 - acc: 0.9985 - val_loss: 0.5035 - val_acc: 0.9263\n", | |
"Epoch 33/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0195 - acc: 0.9940 - val_loss: 0.4182 - val_acc: 0.9225\n", | |
"Epoch 34/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0136 - acc: 0.9950 - val_loss: 0.4399 - val_acc: 0.9300\n", | |
"Epoch 35/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0168 - acc: 0.9945 - val_loss: 0.4108 - val_acc: 0.9237\n", | |
"Epoch 36/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0047 - acc: 0.9995 - val_loss: 0.4880 - val_acc: 0.9250\n", | |
"Epoch 37/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0202 - acc: 0.9970 - val_loss: 0.4422 - val_acc: 0.9237\n", | |
"Epoch 38/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0142 - acc: 0.9965 - val_loss: 0.4092 - val_acc: 0.9213\n", | |
"Epoch 39/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0097 - acc: 0.9955 - val_loss: 0.3900 - val_acc: 0.9275\n", | |
"Epoch 40/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0113 - acc: 0.9960 - val_loss: 0.4725 - val_acc: 0.9137\n", | |
"Epoch 41/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.0058 - acc: 0.9985 - val_loss: 0.4197 - val_acc: 0.9237\n", | |
"Epoch 42/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0084 - acc: 0.9970 - val_loss: 0.4394 - val_acc: 0.9237\n", | |
"Epoch 43/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0109 - acc: 0.9970 - val_loss: 0.4607 - val_acc: 0.9225\n", | |
"Epoch 44/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0046 - acc: 0.9980 - val_loss: 0.4826 - val_acc: 0.9250\n", | |
"Epoch 45/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.0026 - acc: 0.9990 - val_loss: 0.4939 - val_acc: 0.9313\n", | |
"Epoch 46/50\n", | |
"125/125 [==============================] - 20s 163ms/step - loss: 0.0014 - acc: 0.9990 - val_loss: 0.5016 - val_acc: 0.9237\n", | |
"Epoch 47/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0361 - acc: 0.9915 - val_loss: 0.4228 - val_acc: 0.9137\n", | |
"Epoch 48/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0213 - acc: 0.9935 - val_loss: 0.3931 - val_acc: 0.9250\n", | |
"Epoch 49/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0086 - acc: 0.9965 - val_loss: 0.4426 - val_acc: 0.9200\n", | |
"Epoch 50/50\n", | |
"125/125 [==============================] - 20s 164ms/step - loss: 0.0045 - acc: 0.9985 - val_loss: 0.4834 - val_acc: 0.9300\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"<keras.callbacks.History at 0x7f19b8e6d150>" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# fine-tune the model\n", | |
"model.fit_generator(\n", | |
" train_generator,\n", | |
" steps_per_epoch=nb_train_samples // batch_size,\n", | |
" epochs=epochs,\n", | |
" validation_data=validation_generator,\n", | |
" validation_steps=nb_validation_samples // batch_size,\n", | |
" verbose=1)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Fine tuning, after 50 epochs, we have an accuracy of 93%**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Environment (conda_tensorflow_p27)", | |
"language": "python", | |
"name": "conda_tensorflow_p27" | |
}, | |
"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.14" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment