{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 载入数据集"},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport numpy as np\nfrom tqdm import tqdm\nimport pandas as pd","execution_count":1,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('../input/dog-breed-identification//labels.csv')\ndf.head()","execution_count":4,"outputs":[{"output_type":"execute_result","execution_count":4,"data":{"text/plain":"                                 id             breed\n0  000bec180eb18c7604dcecc8fe0dba07       boston_bull\n1  001513dfcb2ffafc82cccf4d8bbaba97             dingo\n2  001cdf01b096e06d78e9e5112d419397          pekinese\n3  00214f311d5d2247d5dfe4fe24b2303d          bluetick\n4  0021f9ceb3235effd7fcde7f7538ed62  golden_retriever","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>id</th>\n      <th>breed</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>000bec180eb18c7604dcecc8fe0dba07</td>\n      <td>boston_bull</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>001513dfcb2ffafc82cccf4d8bbaba97</td>\n      <td>dingo</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>001cdf01b096e06d78e9e5112d419397</td>\n      <td>pekinese</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>00214f311d5d2247d5dfe4fe24b2303d</td>\n      <td>bluetick</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>0021f9ceb3235effd7fcde7f7538ed62</td>\n      <td>golden_retriever</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"n = len(df)\nbreed = set(df['breed'])\nn_class = len(breed)\nclass_to_num = dict(zip(breed, range(n_class)))\nnum_to_class = dict(zip(range(n_class), breed))\n\nprint(class_to_num)","execution_count":5,"outputs":[{"output_type":"stream","text":"{'basset': 0, 'dingo': 1, 'kelpie': 2, 'standard_poodle': 3, 'appenzeller': 4, 'weimaraner': 5, 'border_collie': 6, 'gordon_setter': 7, 'bloodhound': 8, 'pekinese': 9, 'dandie_dinmont': 10, 'sussex_spaniel': 11, 'west_highland_white_terrier': 12, 'shih-tzu': 13, 'malinois': 14, 'walker_hound': 15, 'lhasa': 16, 'irish_terrier': 17, 'borzoi': 18, 'labrador_retriever': 19, 'black-and-tan_coonhound': 20, 'japanese_spaniel': 21, 'malamute': 22, 'keeshond': 23, 'norwegian_elkhound': 24, 'siberian_husky': 25, 'curly-coated_retriever': 26, 'norwich_terrier': 27, 'bull_mastiff': 28, 'mexican_hairless': 29, 'brabancon_griffon': 30, 'chesapeake_bay_retriever': 31, 'english_setter': 32, 'lakeland_terrier': 33, 'basenji': 34, 'bluetick': 35, 'scotch_terrier': 36, 'bernese_mountain_dog': 37, 'greater_swiss_mountain_dog': 38, 'brittany_spaniel': 39, 'whippet': 40, 'toy_poodle': 41, 'norfolk_terrier': 42, 'redbone': 43, 'great_pyrenees': 44, 'eskimo_dog': 45, 'shetland_sheepdog': 46, 'silky_terrier': 47, 'afghan_hound': 48, 'african_hunting_dog': 49, 'tibetan_terrier': 50, 'komondor': 51, 'irish_wolfhound': 52, 'english_foxhound': 53, 'kuvasz': 54, 'toy_terrier': 55, 'airedale': 56, 'soft-coated_wheaten_terrier': 57, 'pembroke': 58, 'tibetan_mastiff': 59, 'vizsla': 60, 'papillon': 61, 'clumber': 62, 'giant_schnauzer': 63, 'pug': 64, 'affenpinscher': 65, 'leonberg': 66, 'maltese_dog': 67, 'collie': 68, 'golden_retriever': 69, 'yorkshire_terrier': 70, 'chow': 71, 'pomeranian': 72, 'border_terrier': 73, 'groenendael': 74, 'rottweiler': 75, 'cairn': 76, 'staffordshire_bullterrier': 77, 'kerry_blue_terrier': 78, 'miniature_pinscher': 79, 'miniature_schnauzer': 80, 'german_short-haired_pointer': 81, 'saluki': 82, 'dhole': 83, 'doberman': 84, 'rhodesian_ridgeback': 85, 'irish_setter': 86, 'otterhound': 87, 'bedlington_terrier': 88, 'schipperke': 89, 'boxer': 90, 'english_springer': 91, 'flat-coated_retriever': 92, 'bouvier_des_flandres': 93, 'french_bulldog': 94, 'boston_bull': 95, 'italian_greyhound': 96, 'blenheim_spaniel': 97, 'old_english_sheepdog': 98, 'saint_bernard': 99, 'wire-haired_fox_terrier': 100, 'cocker_spaniel': 101, 'australian_terrier': 102, 'entlebucher': 103, 'chihuahua': 104, 'briard': 105, 'beagle': 106, 'german_shepherd': 107, 'newfoundland': 108, 'american_staffordshire_terrier': 109, 'welsh_springer_spaniel': 110, 'miniature_poodle': 111, 'cardigan': 112, 'great_dane': 113, 'ibizan_hound': 114, 'sealyham_terrier': 115, 'scottish_deerhound': 116, 'samoyed': 117, 'standard_schnauzer': 118, 'irish_water_spaniel': 119}\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"width = 299\nX = np.zeros((n, width, width, 3), dtype=np.uint8)\ny = np.zeros((n, n_class), dtype=np.uint8)\nfor i in tqdm(range(n)):\n    X[i] = cv2.resize(cv2.imread('train/%s.jpg' % df['id'][i]), (width, width))\n    y[i][class_to_num[df['breed'][i]]] = 1","execution_count":7,"outputs":[{"output_type":"stream","text":"  0%|          | 0/10222 [00:00<?, ?it/s]\n","name":"stderr"},{"output_type":"error","ename":"error","evalue":"OpenCV(4.0.0) /io/opencv/modules/imgproc/src/resize.cpp:3784: error: (-215:Assertion failed) !ssize.empty() in function 'resize'\n","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31merror\u001b[0m                                     Traceback (most recent call last)","\u001b[0;32m<ipython-input-7-bcd4c841b7ca>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_class\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muint8\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m     \u001b[0mX\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/%s.jpg'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'id'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwidth\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      6\u001b[0m     \u001b[0my\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mclass_to_num\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'breed'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31merror\u001b[0m: OpenCV(4.0.0) /io/opencv/modules/imgproc/src/resize.cpp:3784: error: (-215:Assertion failed) !ssize.empty() in function 'resize'\n"]}]},{"metadata":{},"cell_type":"markdown","source":"# 数据集可视化"},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nimport matplotlib.pyplot as plt\n\n%matplotlib inline\n%config InlineBackend.figure_format = 'retina'\n\nplt.figure(figsize=(12, 6))\nfor i in range(8):\n    random_index = random.randint(0, n-1)\n    plt.subplot(2, 4, i+1)\n    plt.imshow(X[random_index][:,:,::-1])\n    plt.title(num_to_class[y[random_index].argmax()])","execution_count":8,"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 864x432 with 8 Axes>","image/png":"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\n"},"metadata":{"image/png":{"width":712,"height":369}}}]},{"metadata":{},"cell_type":"markdown","source":"# 导出特征"},{"metadata":{"trusted":false},"cell_type":"code","source":"from keras.layers import *\nfrom keras.models import *\nfrom keras.applications import *\nfrom keras.optimizers import *\nfrom keras.regularizers import *\nfrom keras.applications.inception_v3 import preprocess_input","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"def get_features(MODEL, data=X):\n    cnn_model = MODEL(include_top=False, input_shape=(width, width, 3), weights='imagenet')\n    \n    inputs = Input((width, width, 3))\n    x = inputs\n    x = Lambda(preprocess_input, name='preprocessing')(x)\n    x = cnn_model(x)\n    x = GlobalAveragePooling2D()(x)\n    cnn_model = Model(inputs, x)\n\n    features = cnn_model.predict(data, batch_size=64, verbose=1)\n    return features","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"inception_features = get_features(InceptionV3, X)\nxception_features = get_features(Xception, X)\nfeatures = np.concatenate([inception_features, xception_features], axis=-1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 训练模型"},{"metadata":{"trusted":false},"cell_type":"code","source":"inputs = Input(features.shape[1:])\nx = inputs\nx = Dropout(0.5)(x)\nx = Dense(n_class, activation='softmax')(x)\nmodel = Model(inputs, x)\nmodel.compile(optimizer='adam',\n              loss='categorical_crossentropy',\n              metrics=['accuracy'])\nh = model.fit(features, y, batch_size=128, epochs=10, validation_split=0.1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 可视化模型"},{"metadata":{"trusted":false},"cell_type":"code","source":"from IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\n\nSVG(model_to_dot(model, show_shapes=True).create(prog='dot', format='svg'))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 可视化训练过程"},{"metadata":{"trusted":false},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n%matplotlib inline\n%config InlineBackend.figure_format = 'retina'\n\nplt.figure(figsize=(10, 4))\nplt.subplot(1, 2, 1)\nplt.plot(h.history['loss'])\nplt.plot(h.history['val_loss'])\nplt.legend(['loss', 'val_loss'])\nplt.ylabel('loss')\nplt.xlabel('epoch')\n\nplt.subplot(1, 2, 2)\nplt.plot(h.history['acc'])\nplt.plot(h.history['val_acc'])\nplt.legend(['acc', 'val_acc'])\nplt.ylabel('acc')\nplt.xlabel('epoch')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 载入测试集"},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"df2 = pd.read_csv('sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"n_test = len(df2)\nX_test = np.zeros((n_test, width, width, 3), dtype=np.uint8)\nfor i in tqdm(range(n_test)):\n    X_test[i] = cv2.resize(cv2.imread('test/%s.jpg' % df2['id'][i]), (width, width))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 导出测试集特征"},{"metadata":{"trusted":false},"cell_type":"code","source":"inception_features = get_features(InceptionV3, X_test)\nxception_features = get_features(Xception, X_test)\nfeatures_test = np.concatenate([inception_features, xception_features], axis=-1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 预测测试集并输出结果"},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"y_pred = model.predict(features_test, batch_size=128)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"for b in breed:\n    df2[b] = y_pred[:,class_to_num[b]]","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"df2.to_csv('pred.csv', index=None)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"language_info":{"version":"2.7.12","pygments_lexer":"ipython2","mimetype":"text/x-python","codemirror_mode":{"version":2,"name":"ipython"},"file_extension":".py","nbconvert_exporter":"python","name":"python"},"kernelspec":{"display_name":"Python 2","language":"python","name":"python2"}},"nbformat":4,"nbformat_minor":1}