{"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"},{"sourceId":279337,"sourceType":"datasetVersion","datasetId":116680}],"dockerImageVersionId":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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\nfor 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","trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-07-28T01:15:08.020398Z","iopub.execute_input":"2024-07-28T01:15:08.020964Z","iopub.status.idle":"2024-07-28T01:15:08.028738Z","shell.execute_reply.started":"2024-07-28T01:15:08.020925Z","shell.execute_reply":"2024-07-28T01:15:08.027135Z"},"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":{"execution":{"iopub.status.busy":"2024-07-28T01:14:44.558865Z","iopub.execute_input":"2024-07-28T01:14:44.559291Z","iopub.status.idle":"2024-07-28T01:14:44.569056Z","shell.execute_reply.started":"2024-07-28T01:14:44.559252Z","shell.execute_reply":"2024-07-28T01:14:44.566962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"## モデル訓練(CNN)","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.\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 訓練結果の表示 (訓練回数と精度および損失の関係)","metadata":{}},{"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\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":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## テストデータの結果表示","metadata":{}},{"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":{"execution":{"iopub.status.busy":"2024-07-25T12:50:26.776868Z","iopub.execute_input":"2024-07-25T12:50:26.777313Z","iopub.status.idle":"2024-07-25T12:52:20.476373Z","shell.execute_reply.started":"2024-07-25T12:50:26.777278Z","shell.execute_reply":"2024-07-25T12:52:20.475057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-07-25T13:19:54.250289Z","iopub.execute_input":"2024-07-25T13:19:54.250773Z","iopub.status.idle":"2024-07-25T13:19:59.390256Z","shell.execute_reply.started":"2024-07-25T13:19:54.250739Z","shell.execute_reply":"2024-07-25T13:19:59.388813Z"},"trusted":true},"execution_count":null,"outputs":[]}]}