{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\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 read-only \"../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\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-09T12:43:12.327168Z","iopub.execute_input":"2021-07-09T12:43:12.327572Z","iopub.status.idle":"2021-07-09T12:43:12.339215Z","shell.execute_reply.started":"2021-07-09T12:43:12.327474Z","shell.execute_reply":"2021-07-09T12:43:12.337962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport time \n\nimport matplotlib.pyplot as plt\n\nfrom keras import Sequential\nfrom keras.layers import Dense, Dropout, InputLayer, Lambda, Input, Flatten\nfrom keras.models import Sequential\nfrom keras.constraints import maxnorm\nfrom keras.optimizers import SGD\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom keras.preprocessing.image import load_img, img_to_array\n\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:43:16.684141Z","iopub.execute_input":"2021-07-09T12:43:16.684491Z","iopub.status.idle":"2021-07-09T12:43:21.434820Z","shell.execute_reply.started":"2021-07-09T12:43:16.684459Z","shell.execute_reply":"2021-07-09T12:43:21.433920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"读取数据集标签和测试集样例","metadata":{}},{"cell_type":"code","source":"labels_di = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nsamples = pd.read_csv('/kaggle/input/dog-breed-identification/sample_submission.csv')\n\nprint('Num of images in train dataset: {}'.format(len(labels_di)))\nprint('Num of images in test dataset: {}'.format(len(samples)))","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:44:04.820610Z","iopub.execute_input":"2021-07-09T12:44:04.821055Z","iopub.status.idle":"2021-07-09T12:44:05.366187Z","shell.execute_reply.started":"2021-07-09T12:44:04.821010Z","shell.execute_reply":"2021-07-09T12:44:05.365240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"规格化图像数据集，返回图像数据集与对应的标签","metadata":{}},{"cell_type":"code","source":"def images_to_array(directory, label_dataframe, target_size = (331, 331, 3)):\n    images = np.zeros([len(label_dataframe), target_size[0], target_size[1], target_size[2]], dtype=np.uint8)\n    img = ''\n    for ix, image_name in enumerate(label_dataframe['id'].values):\n        img_dir = os.path.join(directory, image_name + '.jpg')\n        img = load_img(img_dir, target_size = target_size)\n        images[ix] = img_to_array(img)\n    del img\n    label_dict = dict(enumerate(label_dataframe['breed'].unique()))\n    return images, label_dict","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:44:07.229487Z","iopub.execute_input":"2021-07-09T12:44:07.229926Z","iopub.status.idle":"2021-07-09T12:44:07.243543Z","shell.execute_reply.started":"2021-07-09T12:44:07.229890Z","shell.execute_reply":"2021-07-09T12:44:07.242555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"规格化训练集数据","metadata":{}},{"cell_type":"code","source":"train_images, labels = images_to_array('/kaggle/input/dog-breed-identification/train', labels_di[:])","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:45:20.613409Z","iopub.execute_input":"2021-07-09T12:45:20.613780Z","iopub.status.idle":"2021-07-09T12:46:33.619650Z","shell.execute_reply.started":"2021-07-09T12:45:20.613742Z","shell.execute_reply":"2021-07-09T12:46:33.618637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"查看前八张图片","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize = (10, 10))\nfor ix, image in enumerate(train_images[:8]):\n    plt.subplot(2, 4, ix + 1)\n    plt.imshow(image / 255.0)\n    plt.xticks([])\n    plt.yticks([]) ","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:46:33.621224Z","iopub.execute_input":"2021-07-09T12:46:33.621592Z","iopub.status.idle":"2021-07-09T12:46:34.149106Z","shell.execute_reply.started":"2021-07-09T12:46:33.621548Z","shell.execute_reply":"2021-07-09T12:46:34.148226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"定义预测模型","metadata":{}},{"cell_type":"code","source":"def get_feature(model_name, preprocess_input, images, target_size = (331,331,3)):\n    base_model = model_name(input_shape = target_size, include_top=False, pooling = 'avg')\n\n    model = Sequential()\n    model.add(InputLayer(input_shape = target_size))\n    model.add(Lambda(preprocess_input))\n    model.add(base_model)\n\n    feature = model.predict(images)\n    \n    print('feature-map shape: {}'.format(feature.shape))\n    return feature","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:46:48.241095Z","iopub.execute_input":"2021-07-09T12:46:48.241450Z","iopub.status.idle":"2021-07-09T12:46:48.247088Z","shell.execute_reply.started":"2021-07-09T12:46:48.241417Z","shell.execute_reply":"2021-07-09T12:46:48.246040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"定义ResNetV2模型","metadata":{}},{"cell_type":"code","source":"from keras.applications.inception_resnet_v2 import InceptionResNetV2, preprocess_input\n\nresnet_preprocess = preprocess_input\nresnet_feature = get_feature(InceptionResNetV2, resnet_preprocess, train_images)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:46:51.783165Z","iopub.execute_input":"2021-07-09T12:46:51.783604Z","iopub.status.idle":"2021-07-09T12:48:17.457031Z","shell.execute_reply.started":"2021-07-09T12:46:51.783561Z","shell.execute_reply":"2021-07-09T12:48:17.455853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"定义NASNetLarge模型","metadata":{}},{"cell_type":"code","source":"from keras.applications.nasnet import NASNetLarge, preprocess_input\nnasnet_preprocessor = preprocess_input\nnasnet_features = get_feature(NASNetLarge, nasnet_preprocessor, train_images)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:48:17.459286Z","iopub.execute_input":"2021-07-09T12:48:17.459839Z","iopub.status.idle":"2021-07-09T12:51:26.986603Z","shell.execute_reply.started":"2021-07-09T12:48:17.459793Z","shell.execute_reply":"2021-07-09T12:51:26.985612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"联合两个模型来进行图像分类","metadata":{}},{"cell_type":"code","source":"final_features = np.concatenate([nasnet_features, resnet_feature], axis = 1)\nprint('final features shape: {}'.format(final_features.shape))\ndel train_images, nasnet_features, resnet_feature","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:51:49.885082Z","iopub.execute_input":"2021-07-09T12:51:49.885457Z","iopub.status.idle":"2021-07-09T12:51:49.965941Z","shell.execute_reply.started":"2021-07-09T12:51:49.885424Z","shell.execute_reply":"2021-07-09T12:51:49.964726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"将标签转换为字典类型","metadata":{}},{"cell_type":"code","source":"class_to_index = dict({labels[ix]:ix for ix in labels.keys()})\nindex_to_class = labels","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:51:51.923649Z","iopub.execute_input":"2021-07-09T12:51:51.924051Z","iopub.status.idle":"2021-07-09T12:51:51.930365Z","shell.execute_reply.started":"2021-07-09T12:51:51.924019Z","shell.execute_reply":"2021-07-09T12:51:51.929398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = labels_di['breed'].map(class_to_index)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:51:54.259142Z","iopub.execute_input":"2021-07-09T12:51:54.259496Z","iopub.status.idle":"2021-07-09T12:51:54.269310Z","shell.execute_reply.started":"2021-07-09T12:51:54.259463Z","shell.execute_reply":"2021-07-09T12:51:54.268427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"定义模型","metadata":{}},{"cell_type":"code","source":"def create_model(features_shape = 1024):\n    model = Sequential()\n    model.add(InputLayer(input_shape = (features_shape, )))\n    #model.add(Dense(4096, activation = 'relu'))\n    model.add(Dropout(0.8))\n    model.add(Dense(len(class_to_index), activation = 'softmax'))\n    \n    model.compile(loss = 'sparse_categorical_crossentropy', optimizer ='Adam', metrics = ['accuracy'])\n    return model\n","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:51:57.367914Z","iopub.execute_input":"2021-07-09T12:51:57.368258Z","iopub.status.idle":"2021-07-09T12:51:57.373867Z","shell.execute_reply.started":"2021-07-09T12:51:57.368227Z","shell.execute_reply":"2021-07-09T12:51:57.372792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"查看模型","metadata":{}},{"cell_type":"code","source":"model = create_model(final_features.shape[1])\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:52:00.499168Z","iopub.execute_input":"2021-07-09T12:52:00.499505Z","iopub.status.idle":"2021-07-09T12:52:00.536181Z","shell.execute_reply.started":"2021-07-09T12:52:00.499470Z","shell.execute_reply":"2021-07-09T12:52:00.535344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"对模型进行训练","metadata":{}},{"cell_type":"code","source":"model.fit(final_features, labels, epochs = 64, validation_split = 0.1)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:52:02.771474Z","iopub.execute_input":"2021-07-09T12:52:02.771855Z","iopub.status.idle":"2021-07-09T12:52:50.984035Z","shell.execute_reply.started":"2021-07-09T12:52:02.771820Z","shell.execute_reply":"2021-07-09T12:52:50.983180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"将测试图片转换为固定形状","metadata":{}},{"cell_type":"code","source":"def images_to_array(directory, label_dataframe, target_size = (331, 331,3)):\n    images = np.zeros([len(label_dataframe), target_size[0], target_size[1], target_size[2]], dtype=np.uint8)\n    img = ''\n    for ix, image_name in enumerate(label_dataframe['id'].values):\n        img_dir = os.path.join(directory, image_name + '.jpg')\n        img = load_img(img_dir, target_size = target_size)\n        images[ix] = img_to_array(img)\n    del img\n    return images","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:53:48.588476Z","iopub.execute_input":"2021-07-09T12:53:48.588900Z","iopub.status.idle":"2021-07-09T12:53:48.595863Z","shell.execute_reply.started":"2021-07-09T12:53:48.588861Z","shell.execute_reply":"2021-07-09T12:53:48.594707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images = images_to_array('/kaggle/input/dog-breed-identification/test', samples)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:53:50.587842Z","iopub.execute_input":"2021-07-09T12:53:50.588222Z","iopub.status.idle":"2021-07-09T12:55:05.570026Z","shell.execute_reply.started":"2021-07-09T12:53:50.588191Z","shell.execute_reply":"2021-07-09T12:55:05.565040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet_feature = get_feature(InceptionResNetV2, resnet_preprocess, test_images)\nnasnet_features = get_feature(NASNetLarge, nasnet_preprocessor, test_images)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T12:56:03.226235Z","iopub.execute_input":"2021-07-09T12:56:03.226639Z","iopub.status.idle":"2021-07-09T13:00:32.495370Z","shell.execute_reply.started":"2021-07-09T12:56:03.226604Z","shell.execute_reply":"2021-07-09T13:00:32.492289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_features = np.concatenate([nasnet_features, resnet_feature], axis = 1)\nprint('final features shape: {}'.format(final_features.shape))","metadata":{"execution":{"iopub.status.busy":"2021-07-09T13:00:32.500583Z","iopub.execute_input":"2021-07-09T13:00:32.500886Z","iopub.status.idle":"2021-07-09T13:00:32.692412Z","shell.execute_reply.started":"2021-07-09T13:00:32.500854Z","shell.execute_reply":"2021-07-09T13:00:32.691433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"进行预测","metadata":{}},{"cell_type":"code","source":"prediction = model.predict(final_features)\nsubmission = pd.DataFrame({'id':samples.id})\nprediction = pd.DataFrame(prediction)\nprediction.columns = class_to_index.keys()","metadata":{"execution":{"iopub.status.busy":"2021-07-09T13:02:14.983522Z","iopub.execute_input":"2021-07-09T13:02:14.983937Z","iopub.status.idle":"2021-07-09T13:02:15.562431Z","shell.execute_reply.started":"2021-07-09T13:02:14.983901Z","shell.execute_reply":"2021-07-09T13:02:15.561060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"将结果进行保存","metadata":{}},{"cell_type":"code","source":"submission = pd.concat([submission, prediction], axis = 1)\nsubmission.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2021-07-09T13:02:19.955419Z","iopub.execute_input":"2021-07-09T13:02:19.955790Z","iopub.status.idle":"2021-07-09T13:02:21.625993Z","shell.execute_reply.started":"2021-07-09T13:02:19.955754Z","shell.execute_reply":"2021-07-09T13:02:21.625057Z"},"trusted":true},"execution_count":null,"outputs":[]}]}