{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Начало, загружаем библиотеки","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"im_resize = 64 # Размер изображения\nnum_class = 120 # Кол-во классов\nBatch_Size = 256 # Размер минибатча \nEpochs=50 # Кол-во эпох","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n%matplotlib inline\nimport matplotlib.pyplot as plt\n\nimport tensorflow.keras as keras\nfrom keras import regularizers\nfrom keras.models import Model, Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom tensorflow.keras.metrics import categorical_accuracy, top_k_categorical_accuracy, categorical_crossentropy\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nimport os\nfrom tqdm import tqdm\nfrom sklearn import preprocessing\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# для отрисовки результатов\ndef gen_graph(history, title):\n    plt.plot(history.history['categorical_accuracy'])\n    plt.plot(history.history['val_categorical_accuracy'])\n    plt.title('Accuracy ' + title)\n    plt.ylabel('Accuracy')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()\n    plt.plot(history.history['fbeta'])\n    plt.plot(history.history['fbeta'])\n    plt.title('fbeta ' + title)\n    plt.ylabel('MLogfbeta')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Метрика Fbeta","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import backend\ndef fbeta(y_true, y_pred, beta=2):\n    # clip predictions\n    y_pred = backend.clip(y_pred, 0, 1)\n    # calculate elements\n    tp = backend.sum(backend.round(backend.clip(y_true * y_pred, 0, 1)), axis=1)\n    fp = backend.sum(backend.round(backend.clip(y_pred - y_true, 0, 1)), axis=1)\n    fn = backend.sum(backend.round(backend.clip(y_true - y_pred, 0, 1)), axis=1)\n    # calculate precision\n    p = tp / (tp + fp + backend.epsilon())\n    # calculate recall\n    r = tp / (tp + fn + backend.epsilon())\n    # calculate fbeta, averaged across each class\n    bb = beta ** 2\n    fbeta_score = backend.mean((1 + bb) * (p * r) / (bb * p + r + backend.epsilon()))\n    return fbeta_score\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/dog-breed-identification/labels.csv') \ndf_test = pd.read_csv('../input/dog-breed-identification/sample_submission.csv') \njpg_train='../input/dog-breed-identification/train/{}.jpg'\njpg_test='../input/dog-breed-identification/test/{}.jpg'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = df_train['breed']\none_hot = pd.get_dummies(labels, sparse = True)\n#one_hot","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"one_hot_labels = np.asarray(one_hot)\none_hot_labels","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Считываем изображения и меняем размер","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train = []\ny_train = []\nx_test = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i = 0 \nfor f, breed in tqdm(df_train.values):\n    img = load_img(jpg_train.format(f), target_size=(im_resize, im_resize))\n    img_resized = img_to_array(img)\n    x_train.append(img_resized)\n    label = one_hot_labels[i]\n    y_train.append(label)\n    i += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for f in tqdm(df_test['id'].values):\n    img = load_img(jpg_test.format(f), target_size=(im_resize, im_resize))\n    img_resized = img_to_array(img)\n    x_test.append(img_resized)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train, X_valid, Y_train, Y_valid = train_test_split(x_train, y_train, shuffle=True,  test_size=0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del x_train, y_train, df_train","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Преобразовываем изображения","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(rotation_range=20,#поворот\n                            rescale=1./255, #нормализация\n                            horizontal_flip=True\n                            )#разворот картинок\ntest_datagen = ImageDataGenerator(rescale=1./255) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator =train_datagen.flow(np.array(X_train), np.array(Y_train), \n                               batch_size=Batch_Size)\ntest_generator =test_datagen.flow(np.array(X_valid), np.array(Y_valid),\n                              batch_size=Batch_Size)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Создаем нейронную сеть","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#Создаем последовательную модель\nmodel = Sequential()\n\n# сверточный слой\nmodel.add(Conv2D(32, (3, 3), padding='same',input_shape=(im_resize, im_resize, 3), activation='relu', kernel_initializer='he_uniform'))\n# сверточный слой\nmodel.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))\n# Второй слой подвыборки\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\n\n# сверточный слой\nmodel.add(Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))\n# сверточный слой\nmodel.add(Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))\n# Третий слой подвыборки\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\n\n# сверточный слой\nmodel.add(Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))\n# сверточный слой\nmodel.add(Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))\n# Третий слой подвыборки\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.2))\n\n# Слой преобразования данных из 2D представления в плоское\nmodel.add(Flatten())\n# Полносвязный слой для классификации\nmodel.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))\nmodel.add(Dropout(0.5))\n\n# Выходной полносвязный слой\nmodel.add(Dense(num_class, activation='sigmoid'))\n\nmodel.compile(optimizer='adam',\n          loss='binary_crossentropy', \n           metrics=[categorical_accuracy,fbeta])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(model.summary())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Задаём callback функции и автосохранение лучших весов","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint, EarlyStopping\n\nearlystop=EarlyStopping(monitor='val_categorical_accuracy', min_delta=0, patience=5)\n\ncheckpoint_callback = ModelCheckpoint('model_best.hdf5',\n                                      monitor='val_categorical_accuracy', \n                                      save_best_only=True,\n                                      verbose=1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Обучаем нейросеть","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    callbacks=[earlystop, checkpoint_callback],\n    epochs=Epochs,\n    steps_per_epoch=len(train_generator),  \n    validation_data=test_generator,\n    validation_steps=len(test_generator))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#График точности на валидационной и обучающей выборке\ngen_graph(history,\n          \"график точности\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del history","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Загружаем лучшую модель и обучаем на тестовой выборке","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.models import load_model\nfrom keras.utils.generic_utils import get_custom_objects\nget_custom_objects().update({\"fbeta\": fbeta})\nmodel=load_model(\"model_best.hdf5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = model.predict(np.array(x_test), verbose=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.DataFrame(preds)\ncol_names = one_hot.columns.values\nsub.columns = col_names\nsub.insert(0, 'id', df_test['id'])\nsub.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.to_csv(\"output_rmsprop_aug.csv\", index=False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}