Skip to content

Instantly share code, notes, and snippets.

@carlos-aguayo
Created February 23, 2018 15:24
Show Gist options
  • Save carlos-aguayo/c14c5535e3ac6dbc31600d46421f3ffd to your computer and use it in GitHub Desktop.
Save carlos-aguayo/c14c5535e3ac6dbc31600d46421f3ffd to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"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