{"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":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30732,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## ライブラリのインポート","metadata":{}},{"cell_type":"code","source":"import json\nimport numpy as np \nimport pandas as pd \nimport os\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import models, optimizers, layers\n\nimport tensorflow.keras.layers as layers\nimport matplotlib.pyplot as plt\nimport shutil\nimport glob\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 画像およびデータの前処理","metadata":{}},{"cell_type":"code","source":"# データの解凍とコピー\nif not os.path.exists('/kaggle/working/train/dog') or not os.path.exists('/kaggle/working/train/cat'):\n    shutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip', '/kaggle/working')\n    shutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip', '/kaggle/working')\n    shutil.copyfile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv', '/kaggle/working/sample_submission.csv')\n\n    # 犬・猫の画像をそれぞれのフォルダに移動\n    dog_dir = '/kaggle/working/train/dog'\n    cat_dir = '/kaggle/working/train/cat'\n    os.makedirs(dog_dir, exist_ok=True)\n    os.makedirs(cat_dir, exist_ok=True)\n\n    files = glob.glob('/kaggle/working/train/*.jpg')\n    for file in files:\n        file_name = os.path.basename(file)\n        if 'cat' in file_name:\n            shutil.move(file, os.path.join(cat_dir, file_name))\n        else:\n            shutil.move(file, os.path.join(dog_dir, file_name))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## モデルの訓練","metadata":{}},{"cell_type":"code","source":"model_path = '/kaggle/working/dog_cat.h5'\nparams_path = '/kaggle/working/params.json'\nepochs = 15\nbatch_size = 32\n\n# パラメータの読み込み\nparams = {}\nif os.path.exists(params_path):\n    with open(params_path, 'r') as f:\n        params = json.load(f)\n\n# モデルが既に存在するかの確認\nif os.path.exists(model_path) and params.get('epochs') == epochs:\n    model = tf.keras.models.load_model(model_path)\n    print(\"Model loaded from disk.\")\nelse:\n    # データ拡張の設定\n    train_datagen = ImageDataGenerator(\n        rescale=1.0 / 255,\n        rotation_range=40,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        fill_mode='nearest',\n        validation_split=0.2\n    )\n\n    # ディレクトリの設定\n    train_dir = '/kaggle/working/train'\n\n    # データジェネレータの設定\n    train_generator = train_datagen.flow_from_directory(\n        train_dir,\n        target_size=(150, 150),\n        batch_size=batch_size,\n        class_mode='binary',\n        subset='training'\n    )\n\n    test_generator = train_datagen.flow_from_directory(\n        train_dir,\n        target_size=(150, 150),\n        batch_size=batch_size,\n        class_mode='binary',\n        subset='validation'\n    )\n\n    # モデルの構築\n    model = models.Sequential([\n        layers.Conv2D(32, (4, 4), activation='relu', input_shape=(150, 150, 3)),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(64, (4, 4), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(128, (4, 4), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(256, (4, 4), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Conv2D(512, (4, 4), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dropout(0.5),\n        layers.Dense(1, activation='sigmoid')\n    ])\n\n    # モデルのコンパイル\n    model.compile(\n        loss='binary_crossentropy',\n        optimizer=optimizers.Adam(learning_rate=1e-5),\n        metrics=['accuracy']\n    )\n\n    # モデルのサマリー表示\n    model.summary()\n    \n    # モデルの早期停止\n    early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n    \n    # モデルの訓練\n    history = model.fit(\n        train_generator,\n        steps_per_epoch=int(20000 / batch_size),\n        epochs=epochs,\n        validation_data=test_generator,\n        validation_steps=int(5000 / batch_size),\n        callbacks=[early_stopping]\n    )\n    \n    # モデルの保存\n    model.save(model_path)\n    print(\"Model trained and saved.\")\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 訓練結果の可視化","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom tabulate import tabulate\n# 訓練結果の可視化\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs_range = range(len(acc))\n\ndata = {\n    'Training Accuracy': acc,\n    'Validation Accuracy': val_acc,\n    'Training Loss': loss,\n    'Validation Loss': val_loss\n}\ndf = pd.DataFrame(data)\n\n# 表を表示\nprint(tabulate(df, headers='keys', tablefmt='grid'))\n\n# 精度のグラフ\nplt.plot(epochs_range, acc, 'bo', label='Training accuracy', color='blue')\nplt.plot(epochs_range, val_acc, 'b', label='Validation accuracy', color='orange')\nplt.title('Training and validation accuracy')\nplt.xlabel('Number of Training')\nplt.ylabel('Training Accuracy')\nplt.tick_params(axis='both', direction='in')\nplt.legend()\nplt.figure()\n\n\n# 損失のグラフ\nplt.plot(epochs_range, loss, 'ro', label='Training loss', color='red')\nplt.plot(epochs_range, val_loss, 'r', label='Validation loss', color='green')\nplt.title('Training and validation loss')\nplt.xlabel('Number of Training')\nplt.ylabel('validation Loss')\nplt.tick_params(axis='both', direction='in')\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# テストデータの画像生成器を作成\ntest_dir = '/kaggle/working/test'\ntest_images = [os.path.join(test_dir, f) for f in os.listdir(test_dir) if f.endswith('.jpg')]\ntest_filenames = [os.path.basename(f) for f in test_images]\n\n# DataFrameを作成\ntest_df = pd.DataFrame({'filename': test_filenames})\n\n# テストデータ用のImageDataGeneratorを作成\ntest_datagen = ImageDataGenerator(rescale=1.0 / 255)\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe=test_df,\n    directory=test_dir,\n    x_col='filename',\n    target_size=(150, 150),\n    batch_size=batch_size,\n    class_mode=None,  \n    shuffle=False\n)\n\n# 予測の実行 (steps パラメータを整数型に変換)\nsteps = int(np.ceil(test_generator.samples / test_generator.batch_size))\npredictions = model.predict(test_generator, steps=steps)\n\n# 予測結果の処理\nfilenames = test_generator.filenames\nids = [int(filename.split('/')[-1].split('.')[0]) for filename in filenames]\nsubmission = pd.DataFrame({'id': ids, 'label': predictions.flatten()})\n\n# 提出ファイルの保存\nsubmission.to_csv('/kaggle/working/submission.csv', index=False)\nprint(\"Submission file saved.\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## テストデータを表示","metadata":{}},{"cell_type":"code","source":"import numpy as np\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport os\nimport random\nimport tensorflow as tf\n\n# モデルのロード\nmodel = tf.keras.models.load_model('/kaggle/working/dog_cat.h5')\n\n# ディレクトリのパスを定義\ndog_dir = '/kaggle/working/train/dog/'\ncat_dir = '/kaggle/working/train/cat/'\n\n# 犬と猫の画像をランダムに選択\ndog_img_files = random.sample(os.listdir(dog_dir), 10)\ncat_img_files = random.sample(os.listdir(cat_dir), 10)\n\n# 予測と表示用の関数\ndef predict_and_display_images(img_files, img_dir):\n    plt.figure(figsize=(20, 10))\n    for i, img_file in enumerate(img_files):\n        img_path = os.path.join(img_dir, img_file)\n        img = Image.open(img_path).resize((150, 150))\n        img_array = np.array(img) / 255.0\n        img_array = np.expand_dims(img_array, axis=0)\n\n        prediction = model.predict(img_array)\n\n        if prediction[0] > 0.5:\n            label = \"dog\"\n        else:\n            label = \"cat\"\n\n        plt.subplot(2, 5, i + 1)\n        plt.imshow(img)\n        plt.title(label)\n        plt.axis('off')\n\n    plt.show()\n\n# 犬の画像の予測と表示\npredict_and_display_images(dog_img_files, dog_dir)\n\n# 猫の画像の予測と表示\npredict_and_display_images(cat_img_files, cat_dir)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}