{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":7327,"databundleVersionId":861871,"sourceType":"competition"}],"dockerImageVersionId":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport glob\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Input\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# 訓練データの読み込み\ndef load_data(data_dir):\n    df_train = pd.read_csv(os.path.join(data_dir, \"dog-breed-identification/labels.csv\"))\n    return df_train\n\n# 検証データの読み込みとジェネレーターの取得\ndef load_test_images(test_data_dir, img_height, img_width):\n    test_image_paths = glob.glob(os.path.join(test_data_dir, '*.jpg'))\n    num_test_images = len(test_image_paths)\n    print(f\"Number of test images: {num_test_images}\")\n\n    df_test = pd.DataFrame({'filename': [os.path.basename(path) for path in test_image_paths]})\n    return df_test, num_test_images\n\n# CNNモデルの構築\n# KerasのSequentialというモデルを使用する\ndef build_model(input_shape, num_classes):\n    model = Sequential([\n        # Conv2D:畳み込み層\n        # MaxPool2D:プーリング層\n        # Dense:全結合層\n        Input(shape=input_shape),\n        Conv2D(32, kernel_size=(3, 3), activation='relu'),\n        MaxPooling2D(pool_size=(2, 2)),\n        Conv2D(64, kernel_size=(3, 3), activation='relu'),\n        MaxPooling2D(pool_size=(2, 2)),\n        Flatten(),\n        Dense(128, activation='relu'),\n        Dropout(0.5),\n        Dense(num_classes, activation='softmax')\n    ])\n    \n    model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])\n    \n    return model\n\n# モデルのトレーニング\ndef train_model(model, train_data, steps_per_epoch, validation_data, validation_steps, epochs):\n    history = model.fit(\n        train_data,\n        steps_per_epoch=steps_per_epoch,\n        epochs=epochs,\n        validation_data=validation_data,\n        validation_steps=validation_steps\n    )\n    return history\n\n# 結果の保存\ndef save_results(Y_pred, test_image_paths, CLASS_NAMES):\n    submission_df = pd.DataFrame(Y_pred, columns=CLASS_NAMES)\n    test_ids = [os.path.splitext(os.path.basename(path))[0] for path in test_image_paths]\n    submission_df.insert(0, 'id', test_ids)\n    submission_df.to_csv('submission.csv', index=False)\n    print(\"Submission file 'submission.csv' generated successfully.\")\n\n# メイン関数\ndef main():\n    DATA_DIR = \"../input\"\n    TEST_DATA_DIR = os.path.join(DATA_DIR, 'dog-breed-identification/test')\n\n    # データの読み込みと表示\n    df_train = load_data(DATA_DIR)\n\n    # 検証データの読み込みとジェネレーターの取得\n    df_test, num_test_images = load_test_images(TEST_DATA_DIR, img_height=224, img_width=224)\n\n    # 犬種のラベルエンコーディング\n    label_encoder = LabelEncoder()\n    df_train['label'] = label_encoder.fit_transform(df_train['breed'])\n    num_classes = len(label_encoder.classes_)\n\n    # モデルの構築\n    input_shape = (224, 224, 3)\n    model = build_model(input_shape, num_classes)\n\n    # データの準備と分割\n    X_train = np.zeros((len(df_train), 224, 224, 3), dtype=np.float32)\n    Y_train = np.zeros((len(df_train), num_classes), dtype=np.uint8)\n\n    for i, img_path in tqdm(enumerate(df_train['id'])):\n        img = cv2.imread(os.path.join(DATA_DIR, f\"dog-breed-identification/train/{img_path}.jpg\"))\n        img = cv2.resize(img, (224, 224))\n        X_train[i] = img\n        Y_train[i][df_train['label'][i]] = 1\n\n    X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size=0.2, random_state=42)\n    \n    train_datagen = ImageDataGenerator(rescale=1.0/255)\n    validation_datagen = ImageDataGenerator(rescale=1.0/255)\n\n    train_data = train_datagen.flow(X_train, Y_train, batch_size=32)\n    validation_data = validation_datagen.flow(X_val, Y_val, batch_size=32)\n\n    # モデルのトレーニング\n    # epochs:学習回数\n    steps_per_epoch = len(X_train) // 32\n    validation_steps = len(X_val) // 32\n    history = train_model(model, train_data, steps_per_epoch, validation_data, validation_steps, epochs=50)\n\n    # トレーニングと検証の精度をプロット\n    # train accuracy:訓練データに対するモデルの精度\n    # val accuracy:検証データに対するモデルの精度（ここの数値を高くしたい）\n    plt.plot(history.history['accuracy'], label='train accuracy')\n    plt.plot(history.history['val_accuracy'], label='val accuracy')\n    plt.xlabel('Epoch')\n    plt.ylabel('Accuracy')\n    plt.legend(loc='lower right')\n    plt.show()\n\n    # モデルの評価と結果の保存\n    test_datagen = ImageDataGenerator(rescale=1.0/255)\n\n    test_generator = test_datagen.flow_from_dataframe(\n        df_test,\n        directory=TEST_DATA_DIR,\n        x_col='filename',\n        class_mode=None,\n        target_size=(224, 224),\n        batch_size=32,\n        shuffle=False\n    )\n\n    steps = int(np.ceil(num_test_images / 32))  # バッチ数の計算\n    Y_pred = model.predict(test_generator, steps=steps, verbose=1)\n    save_results(Y_pred, df_test['filename'], label_encoder.classes_)\n\nif __name__ == \"__main__\":\n    main()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-14T03:43:17.138573Z","iopub.execute_input":"2024-07-14T03:43:17.139418Z","iopub.status.idle":"2024-07-14T06:45:43.464215Z","shell.execute_reply.started":"2024-07-14T03:43:17.139369Z","shell.execute_reply":"2024-07-14T06:45:43.461291Z"},"trusted":true},"execution_count":null,"outputs":[]}]}