{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","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 all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Chargement des labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('../input/dog-breed-identification/labels.csv')\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Visualisation du set"},{"metadata":{"trusted":true},"cell_type":"code","source":"df.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['breed'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"120 races de chiens\n\n\n66 images d'`eskimo_dog` contre 126 images de `scottish_deerhound`. Il y a un rapport *2 entre les deux mais l'output est constitué de 120 races donc on peut ne pas undersampler\n> certains vont flipper/faire une symétrie des images pour avoir plus de données d'entrainement"},{"metadata":{},"cell_type":"markdown","source":"### Visualisation des données"},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import load_img\n\nimages = []\nfor img in df['id'].values.tolist():\n    #print(img)\n    images.append(np.asarray(load_img('../input/dog-breed-identification/train/'+ img +'.jpg', target_size=(100, 100), color_mode='rgb')))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(images[0])\nprint(images[0].shape)\nplt.imshow(images[0]) #pas très beau avec le cmap grey...\nplt.axis('off')\nplt.title(df.breed[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> Qu'il est beau !"},{"metadata":{},"cell_type":"markdown","source":"### Mise en forme\n> C'est un peu du bricolage..."},{"metadata":{"trusted":true},"cell_type":"code","source":"df_list_breed = df['breed'].values.tolist()\nraces = set(df_list_breed) #set() récupère les valeurs uniques\n# on map les races avec un chiffre pour pouvoir utiliser to_categorical (il y a peut être plus optimisé)\nprint(races)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"races = ['siberian_husky', 'border_terrier', 'lhasa', 'japanese_spaniel', 'miniature_pinscher', 'boxer', 'rhodesian_ridgeback', 'gordon_setter', 'collie', 'miniature_poodle', 'otterhound', 'borzoi', 'irish_terrier', 'black-and-tan_coonhound', 'dandie_dinmont', 'german_shepherd', 'maltese_dog', 'tibetan_terrier', 'west_highland_white_terrier', 'miniature_schnauzer', 'norwegian_elkhound', 'beagle', 'english_springer', 'kuvasz', 'affenpinscher', 'silky_terrier', 'scotch_terrier', 'irish_wolfhound', 'yorkshire_terrier', 'boston_bull', 'saluki', 'whippet', 'standard_poodle', 'vizsla', 'keeshond', 'malinois', 'pembroke', 'toy_poodle', 'giant_schnauzer', 'staffordshire_bullterrier', 'walker_hound', 'american_staffordshire_terrier', 'labrador_retriever', 'toy_terrier', 'pomeranian', 'english_foxhound', 'irish_water_spaniel', 'malamute', 'greater_swiss_mountain_dog', 'german_short-haired_pointer', 'afghan_hound', 'irish_setter', 'flat-coated_retriever', 'dingo', 'papillon', 'italian_greyhound', 'english_setter', 'shih-tzu', 'basenji', 'briard', 'redbone', 'kerry_blue_terrier', 'wire-haired_fox_terrier', 'norwich_terrier', 'norfolk_terrier', 'weimaraner', 'great_pyrenees', 'lakeland_terrier', 'bouvier_des_flandres', 'bernese_mountain_dog', 'basset', 'schipperke', 'sealyham_terrier', 'cairn', 'newfoundland', 'shetland_sheepdog', 'brittany_spaniel', 'rottweiler', 'tibetan_mastiff', 'french_bulldog', 'border_collie', 'soft-coated_wheaten_terrier', 'bull_mastiff', 'chihuahua', 'sussex_spaniel', 'bloodhound', 'ibizan_hound', 'african_hunting_dog', 'australian_terrier', 'chesapeake_bay_retriever', 'leonberg', 'groenendael', 'blenheim_spaniel', 'great_dane', 'doberman', 'mexican_hairless', 'chow', 'komondor', 'brabancon_griffon', 'kelpie', 'bluetick', 'samoyed', 'cardigan', 'golden_retriever', 'curly-coated_retriever', 'clumber', 'cocker_spaniel', 'appenzeller', 'airedale', 'bedlington_terrier', 'scottish_deerhound', 'pug', 'eskimo_dog', 'entlebucher', 'dhole', 'saint_bernard', 'standard_schnauzer', 'old_english_sheepdog', 'welsh_springer_spaniel', 'pekinese']\ni=0\nmap_race = {}\nfor race in races:\n    map_race[race] = i\n    i= i + 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i = 0\ny = []\nfor sample in df['breed']:\n    y.append(map_race[sample])\nprint(y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils.np_utils import to_categorical\n\nX = np.array(images)\ny = y\n\nprint(y)\nprint(y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10,20))\nfor i in range(0,49) :\n    plt.subplot(10,5,i+1)\n    plt.axis('off')\n    plt.imshow(images[i])\n    plt.title(df['breed'][i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Normalisation entre 0 et 1\nX = X / 255\nprint(X[0][0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_scores(train) :\n    accuracy = train.history['accuracy']\n    val_accuracy = train.history['val_accuracy']\n    epochs = range(len(accuracy))\n    plt.plot(epochs, accuracy, 'b', label='Score apprentissage')\n    plt.plot(epochs, val_accuracy, 'r', label='Score validation')\n    plt.title('Scores')\n    plt.legend()\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport os\nimport glob","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom keras.models import Sequential, load_model\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom keras.utils.np_utils import to_categorical\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)\n\nX_train1 = np.array(X_train)\nX_test1 = np.array(X_test)\ny_train1 = np.array(y_train)\ny_test1 = np.array(y_test)\n\ny_train1 = to_categorical(y_train1)\ny_comparaison_finale = np.array(y_test1) \ny_test1 = to_categorical(y_test1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train1.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TEST 1"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(32, (5, 5), input_shape=(100, 100, 3), activation='relu')) #attention dim image et b&w ou rgb\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dense(50, activation='relu'))\nmodel.add(Dense(120)) #attention, 120 races de chiens\n\nmodel.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(X_train1.shape)\nprint(X_test1.shape)\nprint(y_train1.shape)\nprint(y_test1.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Apprentissage\ntrain = model.fit(X_train1, y_train1, validation_data=(X_test1, y_test1), epochs=50, batch_size=200, verbose=1)\n\n# Test\nscores = model.evaluate(X_test1, y_test1, verbose=0)\nprint(\"Score : %.2f%%\" % (scores[1]*100))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_scores(train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TEST 2 : vgg16"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import VGG16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vgg16 = VGG16(weights='imagenet', include_top=False, input_shape=(100,100,3))\nvgg16.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vgg16.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(vgg16)\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(120, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = model.fit(X_train1, y_train1, validation_data=(X_test1, y_test1), epochs=20, batch_size=200, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_scores(train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TEST 3 : vgg16 avec dégel"},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in vgg16.layers[10:]:\n    layer.trainable=True\nfor layer in vgg16.layers[0:10]:\n    layer.trainable=False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\ntrain = model.fit(X_train1, y_train1, validation_data=(X_test1, y_test1), epochs=20, batch_size=200, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_scores(train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TEST 4 : inceptionV3"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import InceptionV3, ResNet50V2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"inceptionV3 = InceptionV3(weights='imagenet', include_top=False, input_shape=(100,100,3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"inceptionV3.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(inceptionV3)\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dense(120, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\ntrain = model.fit(X_train1, y_train1, validation_data=(X_test1, y_test1), epochs=20, batch_size=200, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_scores(train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TEST 5 : inceptionV3 avec dégel"},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in inceptionV3.layers[15:]:\n    layer.trainable=True\nfor layer in inceptionV3.layers[0:15]:\n    layer.trainable=False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\ntrain = model.fit(X_train1, y_train1, validation_data=(X_test1, y_test1), epochs=50, batch_size=200, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_scores(train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_hat = model.predict_classes(X_test1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10,20))\ni=0\nj=0\n\nwhile i<20 :\n    if  y_test[j] != y_hat[j] :\n        plt.subplot(10,2,i+1)\n        plt.axis('off')\n        plt.imshow(X[j])\n        plt.title(races[y_comparaison_finale[j]] + \" / \" + races[y_hat[j]])\n        i += 1\n    j+=1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Conclusion \nOn ne dépasse pas les 20% de précision mais c'est relativement satisfaisant vu le nombre de classes différentes et le petit nombre d'échantillons de chaque race."},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}