fine tuning VGG16

From: https://www.kaggle.com/takamichitoda/fine-tuning-vgg16

Author: Takamichi Toda

Score: 0.18366

I referred this kernel for leaning how to use Keras.

Keras Starter

In [1]:
import numpy as np
import pandas as pd
import os
In [2]:
train = pd.read_csv("../input/imet-2019-fgvc6/train.csv")
labels = pd.read_csv("../input/imet-2019-fgvc6/labels.csv")
sub = pd.read_csv("../input/imet-2019-fgvc6/sample_submission.csv")

train["id"] = train.id.map(lambda x: "{}.png".format(x))
train["attribute_ids"] = train.attribute_ids.map(lambda x: x.split())
sub["id"] = sub.id.map(lambda x: "{}.png".format(x))

display(sub.head())
display(train.head())
id attribute_ids
0 10023b2cc4ed5f68.png 0 1 2
1 100fbe75ed8fd887.png 0 1 2
2 101b627524a04f19.png 0 1 2
3 10234480c41284c6.png 0 1 2
4 1023b0e2636dcea8.png 0 1 2
id attribute_ids
0 1000483014d91860.png [147, 616, 813]
1 1000fe2e667721fe.png [51, 616, 734, 813]
2 1001614cb89646ee.png [776]
3 10041eb49b297c08.png [51, 671, 698, 813, 1092]
4 100501c227f8beea.png [13, 404, 492, 903, 1093]
In [3]:
batch_size = 32
img_size = 64
nb_epochs = 150
nb_classes = labels.shape[0]
lbls = list(map(str, range(nb_classes)))
In [4]:
%%time

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.25)

train_generator=train_datagen.flow_from_dataframe(
    dataframe=train,
    directory="../input/imet-2019-fgvc6/train",
    x_col="id",
    y_col="attribute_ids",
    batch_size=batch_size,
    shuffle=True,
    class_mode="categorical",
    classes=lbls,
    target_size=(img_size,img_size),
    subset='training')

valid_generator=train_datagen.flow_from_dataframe(
    dataframe=train,
    directory="../input/imet-2019-fgvc6/train",
    x_col="id",
    y_col="attribute_ids",
    batch_size=batch_size,
    shuffle=True,
    class_mode="categorical",    
    classes=lbls,
    target_size=(img_size,img_size),
    subset='validation')


test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_dataframe(  
        dataframe=sub,
        directory = "../input/imet-2019-fgvc6/test",    
        x_col="id",
        target_size = (img_size,img_size),
        batch_size = 1,
        shuffle = False,
        class_mode = None
        )
Using TensorFlow backend.
Found 81928 images belonging to 1103 classes.
Found 27309 images belonging to 1103 classes.
Found 7443 images.
CPU times: user 6.79 s, sys: 9.05 s, total: 15.8 s
Wall time: 1min 28s
In [5]:
from keras.applications.vgg16 import VGG16
from keras.layers import Dropout
from keras.models import Sequential
from keras.layers import Dense, Flatten

vgg_conv = VGG16(weights=None, include_top=False, input_shape=(img_size, img_size, 3))
vgg_conv.load_weights('../input/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')

for layer in vgg_conv.layers[:-4]:
    layer.trainable = False

model = Sequential()
model.add(vgg_conv)
 
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='softmax'))
 
model.summary()
WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
vgg16 (Model)                (None, 2, 2, 512)         14714688  
_________________________________________________________________
flatten_1 (Flatten)          (None, 2048)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 1024)              2098176   
_________________________________________________________________
dropout_1 (Dropout)          (None, 1024)              0         
_________________________________________________________________
dense_2 (Dense)              (None, 1103)              1130575   
=================================================================
Total params: 17,943,439
Trainable params: 10,308,175
Non-trainable params: 7,635,264
_________________________________________________________________
In [6]:
from keras import optimizers

model.compile(optimizers.rmsprop(lr=0.0001, decay=1e-6),loss="categorical_crossentropy",metrics=["accuracy"])
In [7]:
history = model.fit_generator(
                    generator=train_generator,
                    steps_per_epoch=100,
                    validation_data=valid_generator,
                    validation_steps=50,
                    epochs=nb_epochs,
                    verbose=1)
WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Epoch 1/150
100/100 [==============================] - 46s 462ms/step - loss: 18.3016 - acc: 0.0656 - val_loss: 16.5667 - val_acc: 0.1250
Epoch 2/150
100/100 [==============================] - 41s 408ms/step - loss: 16.7756 - acc: 0.0884 - val_loss: 15.9198 - val_acc: 0.1025
Epoch 3/150
100/100 [==============================] - 41s 412ms/step - loss: 16.6616 - acc: 0.0972 - val_loss: 15.4799 - val_acc: 0.0762
Epoch 4/150
100/100 [==============================] - 40s 404ms/step - loss: 15.6332 - acc: 0.0981 - val_loss: 15.0637 - val_acc: 0.1100
Epoch 5/150
100/100 [==============================] - 41s 409ms/step - loss: 15.8566 - acc: 0.1066 - val_loss: 14.9733 - val_acc: 0.1487
Epoch 6/150
100/100 [==============================] - 40s 402ms/step - loss: 15.3851 - acc: 0.1206 - val_loss: 15.1975 - val_acc: 0.1487
Epoch 7/150
100/100 [==============================] - 41s 406ms/step - loss: 15.2951 - acc: 0.1197 - val_loss: 14.9318 - val_acc: 0.1437
Epoch 8/150
100/100 [==============================] - 41s 410ms/step - loss: 15.2171 - acc: 0.1250 - val_loss: 15.0043 - val_acc: 0.1638
Epoch 9/150
100/100 [==============================] - 41s 413ms/step - loss: 15.1355 - acc: 0.1206 - val_loss: 15.1679 - val_acc: 0.1281
Epoch 10/150
100/100 [==============================] - 41s 408ms/step - loss: 14.6990 - acc: 0.1450 - val_loss: 14.5812 - val_acc: 0.1419
Epoch 11/150
100/100 [==============================] - 41s 406ms/step - loss: 14.8562 - acc: 0.1228 - val_loss: 14.6720 - val_acc: 0.1288
Epoch 12/150
100/100 [==============================] - 41s 410ms/step - loss: 14.8757 - acc: 0.1347 - val_loss: 14.4012 - val_acc: 0.1456
Epoch 13/150
100/100 [==============================] - 41s 406ms/step - loss: 14.6870 - acc: 0.1425 - val_loss: 14.2707 - val_acc: 0.1431
Epoch 14/150
100/100 [==============================] - 41s 407ms/step - loss: 14.9353 - acc: 0.1419 - val_loss: 14.4837 - val_acc: 0.1200
Epoch 15/150
100/100 [==============================] - 41s 407ms/step - loss: 14.5486 - acc: 0.1359 - val_loss: 14.1752 - val_acc: 0.1450
Epoch 16/150
100/100 [==============================] - 41s 414ms/step - loss: 14.6435 - acc: 0.1516 - val_loss: 14.1716 - val_acc: 0.1519
Epoch 17/150
100/100 [==============================] - 41s 408ms/step - loss: 14.3720 - acc: 0.1334 - val_loss: 15.0855 - val_acc: 0.1506
Epoch 18/150
100/100 [==============================] - 40s 399ms/step - loss: 14.7157 - acc: 0.1444 - val_loss: 14.3806 - val_acc: 0.1448
Epoch 19/150
100/100 [==============================] - 40s 395ms/step - loss: 14.6222 - acc: 0.1544 - val_loss: 14.1155 - val_acc: 0.1713
Epoch 20/150
100/100 [==============================] - 40s 401ms/step - loss: 14.3239 - acc: 0.1522 - val_loss: 14.2457 - val_acc: 0.1500
Epoch 21/150
100/100 [==============================] - 40s 401ms/step - loss: 14.3527 - acc: 0.1444 - val_loss: 14.2378 - val_acc: 0.1688
Epoch 22/150
100/100 [==============================] - 40s 403ms/step - loss: 14.5618 - acc: 0.1478 - val_loss: 14.5343 - val_acc: 0.1406
Epoch 23/150
100/100 [==============================] - 41s 406ms/step - loss: 14.2108 - acc: 0.1584 - val_loss: 14.1664 - val_acc: 0.1394
Epoch 24/150
100/100 [==============================] - 41s 409ms/step - loss: 14.2561 - acc: 0.1484 - val_loss: 13.9194 - val_acc: 0.1625
Epoch 25/150
100/100 [==============================] - 41s 411ms/step - loss: 14.4097 - acc: 0.1484 - val_loss: 13.9376 - val_acc: 0.1725
Epoch 26/150
100/100 [==============================] - 41s 414ms/step - loss: 14.1241 - acc: 0.1566 - val_loss: 14.1983 - val_acc: 0.1594
Epoch 27/150
100/100 [==============================] - 40s 401ms/step - loss: 14.0290 - acc: 0.1497 - val_loss: 14.2306 - val_acc: 0.1419
Epoch 28/150
100/100 [==============================] - 40s 404ms/step - loss: 13.9317 - acc: 0.1547 - val_loss: 14.0708 - val_acc: 0.1525
Epoch 29/150
100/100 [==============================] - 41s 412ms/step - loss: 14.2542 - acc: 0.1588 - val_loss: 14.3749 - val_acc: 0.1550
Epoch 30/150
100/100 [==============================] - 41s 405ms/step - loss: 14.2814 - acc: 0.1694 - val_loss: 13.9915 - val_acc: 0.1888
Epoch 31/150
100/100 [==============================] - 41s 409ms/step - loss: 14.1541 - acc: 0.1591 - val_loss: 14.0752 - val_acc: 0.1631
Epoch 32/150
100/100 [==============================] - 41s 412ms/step - loss: 14.2089 - acc: 0.1531 - val_loss: 13.9050 - val_acc: 0.1644
Epoch 33/150
100/100 [==============================] - 41s 410ms/step - loss: 13.9952 - acc: 0.1659 - val_loss: 13.8238 - val_acc: 0.1800
Epoch 34/150
100/100 [==============================] - 41s 413ms/step - loss: 14.3139 - acc: 0.1644 - val_loss: 13.8812 - val_acc: 0.1363
Epoch 35/150
100/100 [==============================] - 40s 401ms/step - loss: 14.1557 - acc: 0.1628 - val_loss: 13.9964 - val_acc: 0.1632
Epoch 36/150
100/100 [==============================] - 40s 403ms/step - loss: 14.1836 - acc: 0.1744 - val_loss: 14.0589 - val_acc: 0.1406
Epoch 37/150
100/100 [==============================] - 40s 405ms/step - loss: 13.8944 - acc: 0.1625 - val_loss: 13.9955 - val_acc: 0.1550
Epoch 38/150
100/100 [==============================] - 40s 404ms/step - loss: 14.0934 - acc: 0.1519 - val_loss: 14.1699 - val_acc: 0.1675
Epoch 39/150
100/100 [==============================] - 41s 409ms/step - loss: 14.1126 - acc: 0.1572 - val_loss: 13.9418 - val_acc: 0.1556
Epoch 40/150
100/100 [==============================] - 42s 417ms/step - loss: 14.0785 - acc: 0.1634 - val_loss: 13.9797 - val_acc: 0.1706
Epoch 41/150
100/100 [==============================] - 41s 413ms/step - loss: 14.1119 - acc: 0.1537 - val_loss: 14.3395 - val_acc: 0.1650
Epoch 42/150
100/100 [==============================] - 40s 402ms/step - loss: 14.0399 - acc: 0.1541 - val_loss: 13.7481 - val_acc: 0.1794
Epoch 43/150
100/100 [==============================] - 40s 405ms/step - loss: 14.1614 - acc: 0.1719 - val_loss: 13.7803 - val_acc: 0.1844
Epoch 44/150
100/100 [==============================] - 40s 399ms/step - loss: 14.2894 - acc: 0.1487 - val_loss: 13.8969 - val_acc: 0.1725
Epoch 45/150
100/100 [==============================] - 40s 400ms/step - loss: 13.9289 - acc: 0.1725 - val_loss: 13.4394 - val_acc: 0.1756
Epoch 46/150
100/100 [==============================] - 41s 410ms/step - loss: 13.9580 - acc: 0.1756 - val_loss: 13.8076 - val_acc: 0.1588
Epoch 47/150
100/100 [==============================] - 41s 412ms/step - loss: 14.2319 - acc: 0.1634 - val_loss: 14.0592 - val_acc: 0.1831
Epoch 48/150
100/100 [==============================] - 40s 404ms/step - loss: 13.8426 - acc: 0.1609 - val_loss: 13.7201 - val_acc: 0.1787
Epoch 49/150
100/100 [==============================] - 40s 400ms/step - loss: 14.0948 - acc: 0.1709 - val_loss: 13.4858 - val_acc: 0.1713
Epoch 50/150
100/100 [==============================] - 40s 404ms/step - loss: 13.8716 - acc: 0.1572 - val_loss: 13.7642 - val_acc: 0.1638
Epoch 51/150
100/100 [==============================] - 40s 403ms/step - loss: 14.2121 - acc: 0.1628 - val_loss: 13.8148 - val_acc: 0.1694
Epoch 52/150
100/100 [==============================] - 37s 371ms/step - loss: 14.0592 - acc: 0.1750 - val_loss: 13.6902 - val_acc: 0.1670
Epoch 53/150
100/100 [==============================] - 37s 372ms/step - loss: 13.6180 - acc: 0.1788 - val_loss: 13.4905 - val_acc: 0.1919
Epoch 54/150
100/100 [==============================] - 38s 376ms/step - loss: 13.9477 - acc: 0.1812 - val_loss: 13.7440 - val_acc: 0.1575
Epoch 55/150
100/100 [==============================] - 38s 382ms/step - loss: 13.8417 - acc: 0.1622 - val_loss: 13.6963 - val_acc: 0.1663
Epoch 56/150
100/100 [==============================] - 38s 381ms/step - loss: 13.8347 - acc: 0.1784 - val_loss: 13.4819 - val_acc: 0.1900
Epoch 57/150
100/100 [==============================] - 38s 377ms/step - loss: 14.0684 - acc: 0.1672 - val_loss: 13.5132 - val_acc: 0.1969
Epoch 58/150
100/100 [==============================] - 38s 380ms/step - loss: 13.7268 - acc: 0.1784 - val_loss: 13.8909 - val_acc: 0.1600
Epoch 59/150
100/100 [==============================] - 38s 379ms/step - loss: 13.7821 - acc: 0.1619 - val_loss: 13.2954 - val_acc: 0.1831
Epoch 60/150
100/100 [==============================] - 38s 378ms/step - loss: 13.8293 - acc: 0.1750 - val_loss: 13.8781 - val_acc: 0.1656
Epoch 61/150
100/100 [==============================] - 38s 383ms/step - loss: 13.7457 - acc: 0.1694 - val_loss: 13.8869 - val_acc: 0.1694
Epoch 62/150
100/100 [==============================] - 38s 379ms/step - loss: 13.5901 - acc: 0.1762 - val_loss: 13.8328 - val_acc: 0.1706
Epoch 63/150
100/100 [==============================] - 39s 390ms/step - loss: 13.7588 - acc: 0.1697 - val_loss: 13.8146 - val_acc: 0.1775
Epoch 64/150
100/100 [==============================] - 38s 384ms/step - loss: 14.0173 - acc: 0.1756 - val_loss: 13.5606 - val_acc: 0.1844
Epoch 65/150
100/100 [==============================] - 38s 385ms/step - loss: 13.5422 - acc: 0.1809 - val_loss: 13.7813 - val_acc: 0.1731
Epoch 66/150
100/100 [==============================] - 39s 386ms/step - loss: 13.7585 - acc: 0.1759 - val_loss: 13.8375 - val_acc: 0.1819
Epoch 67/150
100/100 [==============================] - 38s 383ms/step - loss: 13.4647 - acc: 0.1744 - val_loss: 14.2386 - val_acc: 0.1844
Epoch 68/150
100/100 [==============================] - 39s 385ms/step - loss: 13.8490 - acc: 0.1687 - val_loss: 13.7533 - val_acc: 0.1487
Epoch 69/150
 71/100 [====================>.........] - ETA: 7s - loss: 13.8051 - acc: 0.1646
In [8]:
import json

with open('history.json', 'w') as f:
    json.dump(history.history, f)

history_df = pd.DataFrame(history.history)
history_df[['loss', 'val_loss']].plot()
history_df[['acc', 'val_acc']].plot()
Out[8]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f9a509e0438>
In [9]:
%%time

test_generator.reset()
predict=model.predict_generator(test_generator, steps = len(test_generator.filenames))
CPU times: user 2min 19s, sys: 4.31 s, total: 2min 24s
Wall time: 2min 12s
In [10]:
predicted_class_indices = np.argmax(predict,axis=1)

labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

sub["attribute_ids"] = predictions
sub['id'] = sub['id'].map(lambda x: str(x)[:-4])

sub.to_csv("submission.csv",index=False)
sub.head()
Out[10]:
id attribute_ids
0 10023b2cc4ed5f68 1059
1 100fbe75ed8fd887 1039
2 101b627524a04f19 121
3 10234480c41284c6 1046
4 1023b0e2636dcea8 671