{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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","execution":{"iopub.status.busy":"2024-07-26T09:43:43.632597Z","iopub.execute_input":"2024-07-26T09:43:43.633058Z","iopub.status.idle":"2024-07-26T09:43:44.636753Z","shell.execute_reply.started":"2024-07-26T09:43:43.633034Z","shell.execute_reply":"2024-07-26T09:43:44.635744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ライブラリのインポート","metadata":{}},{"cell_type":"code","source":"import os\nfrom os import makedirs\nfrom os import listdir\nfrom shutil import copyfile\nfrom random import seed\nfrom random import random\nimport numpy as np\nimport pandas as pd\n\n# 図表\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom matplotlib.image import imread\nfrom PIL import Image\n\n# Scikit-learn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report,confusion_matrix,ConfusionMatrixDisplay\n\n# Tensorflow\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom tensorflow.keras.layers import Dense,MaxPooling2D,Dropout,Flatten,BatchNormalization,Conv2D\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau,EarlyStopping","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:43:44.638629Z","iopub.execute_input":"2024-07-26T09:43:44.639099Z","iopub.status.idle":"2024-07-26T09:43:57.808427Z","shell.execute_reply.started":"2024-07-26T09:43:44.639067Z","shell.execute_reply":"2024-07-26T09:43:57.807439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Zipファイルの解凍","metadata":{}},{"cell_type":"code","source":"train_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip\"\ntest_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\"\n\nfiles = \"/kaggle/working/\"\n\nimport zipfile\n\nwith zipfile.ZipFile(train_path, 'r') as zipp:\n    zipp.extractall(files)\n    \nwith zipfile.ZipFile(test_path, 'r') as zipp:\n    zipp.extractall(files)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:43:57.809740Z","iopub.execute_input":"2024-07-26T09:43:57.810417Z","iopub.status.idle":"2024-07-26T09:44:11.870695Z","shell.execute_reply.started":"2024-07-26T09:43:57.810389Z","shell.execute_reply":"2024-07-26T09:44:11.869879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_dir = \"../working/train/\"\n\n# image_dirのファイル名リスト\"filenames\"の作成\nfilenames = os.listdir(image_dir)\n\n# ファイル名を\".\"で分割し、最初の部分を取り出したリスト\"labels\"を作成\nlabels = [x.split(\".\")[0] for x in filenames]\n\n# 2つのカラム（filenameとlabel）を持つDataFrame\"data\"を作成\ndata = pd.DataFrame({\"filename\": filenames, \"label\": labels})\n\n# DataFrameの最初の5行を表示\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:11.872920Z","iopub.execute_input":"2024-07-26T09:44:11.873229Z","iopub.status.idle":"2024-07-26T09:44:11.918153Z","shell.execute_reply.started":"2024-07-26T09:44:11.873205Z","shell.execute_reply":"2024-07-26T09:44:11.917249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## データの探索","metadata":{}},{"cell_type":"code","source":"# 犬のデータを可視化する\n\n# グリッドサイズを20x20インチに設定\nplt.figure(figsize=(20,20))\n# サブプロット間の垂直方向のスペースを0.4インチに設定\nplt.subplots_adjust(hspace=0.4)\n\n# 犬の画像を10枚表示する\nfor i in range(10):\n    \n    # 1行10列のグリッドのうち、i+1列目にプロット\n    plt.subplot(1,10,i+1)\n    # 'train/dog.i+1.jpg'の名前を指定\n    filename = 'train/' + 'dog.' + str(i) + '.jpg'\n    # 'filename'名の画像を読み込む\n    image = imread(filename)\n    \n    plt.imshow(image)\n    # タイトルとフォントサイズの指定\n    plt.title('Dog',fontsize=12)\n    # サブプロットの軸をオフ\n    plt.axis('off')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:11.919136Z","iopub.execute_input":"2024-07-26T09:44:11.919374Z","iopub.status.idle":"2024-07-26T09:44:12.884671Z","shell.execute_reply.started":"2024-07-26T09:44:11.919354Z","shell.execute_reply":"2024-07-26T09:44:12.883772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 猫のデータを可視化する\n\n# グリッドサイズを20x20インチに設定\nplt.figure(figsize=(20,20))\n# サブプロット間の垂直方向のスペースを0.4インチに設定\nplt.subplots_adjust(hspace=0.4)\n\n# 猫の画像を10枚表示する\n# （犬の時と同様）\nfor i in range(10):\n    \n    plt.subplot(1,10,i+1)\n    filename = 'train/' + 'cat.' + str(i) + '.jpg'\n    image = imread(filename)\n    plt.imshow(image)\n    plt.title('Cat',fontsize=12)\n    plt.axis('off')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:12.885681Z","iopub.execute_input":"2024-07-26T09:44:12.885932Z","iopub.status.idle":"2024-07-26T09:44:13.678604Z","shell.execute_reply.started":"2024-07-26T09:44:12.885910Z","shell.execute_reply":"2024-07-26T09:44:13.677713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## データの分割","metadata":{}},{"cell_type":"code","source":"# データフレーム内のデータを分割する\n\n# データフレーム'data'から犬か猫かのラベル列を抽出し、格納する\nlabels = data['label']\n\n# データフレーム'data'を訓練データ（X_train）と一時データ（X_temp）に分割\n# 'test_size=0.2':全データの20%を一時データ（X_temp）に割り当てる\n# 'stratify=labels':分割時にクラスラベル（犬と猫）の比率を保つようにする\n# 'random_state=42': 再現性を確保するためのランダムシードを設定\nX_train, X_temp = train_test_split(data, test_size=0.2, stratify=labels, random_state = 42)\n\n# 一時データ'X_temp'から犬か猫かのラベル列を抽出し、格納する\nlabel_test_val = X_temp['label']\n\n# 一時データ'X_temp'をテストデータ'X_test'と検証データ'X_val'に分割\n# 'test_size=0.5':一時データの50%をテストデータ'X_test'に、残りの50%を検証データ'X_val'に割り当て\n# 'stratify=labels':分割時にクラスラベル（犬と猫）の比率を保つようにする\n# 'random_state=42': 再現性を確保するためのランダムシードを設定\nX_test, X_val = train_test_split(X_temp, test_size=0.5, stratify=label_test_val, random_state = 42)\n\n#訓練データ、テストデータ、検証データのサンプル数とクラス数を表示\nprint('The shape of train data',X_train.shape)\nprint('The shape of test data',X_test.shape)\nprint('The shape of validation data',X_val.shape)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:13.679812Z","iopub.execute_input":"2024-07-26T09:44:13.680139Z","iopub.status.idle":"2024-07-26T09:44:13.744622Z","shell.execute_reply.started":"2024-07-26T09:44:13.680110Z","shell.execute_reply":"2024-07-26T09:44:13.743792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## グラフによる可視化","metadata":{}},{"cell_type":"code","source":"# データのグラフによる可視化\n\nlabels = ['Cat','Dog']\n\n# 訓練データ、テストデータ、検証データのラベルと数をカウント\nlabel1,count1 = np.unique(X_train.label,return_counts=True)\nlabel2,count2 = np.unique(X_val.label,return_counts=True)\nlabel3,count3 = np.unique(X_test.label,return_counts=True)\n\n# データフレームの作成\nuni1 = pd.DataFrame(data=count1,index=labels,columns=['Count1'])\nuni2 = pd.DataFrame(data=count2,index=labels,columns=['Count2'])\nuni3 = pd.DataFrame(data=count3,index=labels,columns=['Count3'])\n\n# サイズ、解像度、スタイルの指定\nplt.figure(figsize=(20,6),dpi=200)\nsns.set_style('darkgrid')\n\n# 1行3列の1番目\nplt.subplot(131)\nsns.barplot(data=uni1,x=uni1.index,y='Count1',palette='icefire',width=0.2).set_title('Class distribution in Training set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\n# 1行3列の2番目\nplt.subplot(132)\nsns.barplot(data=uni2,x=uni2.index,y='Count2',palette='icefire',width=0.2).set_title('Class distribution in validation set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\n# 1行3列の3番目\nplt.subplot(133)\nsns.barplot(data=uni3,x=uni3.index,y='Count3',palette='icefire',width=0.2).set_title('Class distribution in Testing set',fontsize=15)\nplt.xlabel('Labels',fontsize=12)\nplt.ylabel('Count',fontsize=12)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:13.745663Z","iopub.execute_input":"2024-07-26T09:44:13.745936Z","iopub.status.idle":"2024-07-26T09:44:14.758609Z","shell.execute_reply.started":"2024-07-26T09:44:13.745912Z","shell.execute_reply":"2024-07-26T09:44:14.757688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## パラメータ設定","metadata":{}},{"cell_type":"code","source":"# パラメータ\n\n# リサイズ\nimage_size = 128\n# カラー画像のため、RGBの3チャンネル\nimage_channel = 3\n# バッチサイズ\nbat_size = 32","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:14.759828Z","iopub.execute_input":"2024-07-26T09:44:14.760185Z","iopub.status.idle":"2024-07-26T09:44:14.765109Z","shell.execute_reply.started":"2024-07-26T09:44:14.760156Z","shell.execute_reply":"2024-07-26T09:44:14.764050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## データ拡張","metadata":{}},{"cell_type":"code","source":"# 画像データ生成器の作成（データ拡張）\n# 訓練データのみに実行\ntrain_datagen = ImageDataGenerator(rescale=1./255, #  画像のピクセル値を0から1の範囲にスケーリング\n                                    rotation_range = 15, # 画像を最大15度までランダムに回転させる\n                                    horizontal_flip = True,# 画像をランダムに左右反転させる\n                                    zoom_range = 0.2, # 画像を最大20%までランダムにズームインまたはズームアウトさせる\n                                    shear_range = 0.1, # 画像をランダムに10%までシアー変換する\n                                    fill_mode = 'reflect', # 画像を変換したときに不足するピクセルを反射パディングで埋める\n                                    width_shift_range = 0.1,# 画像を横方向に最大10%までランダムにシフトさせる\n                                    height_shift_range = 0.1) # 画像を縦方向に最大10%までランダムにシフトさせる\n    \n\n# テストデータは、画像のピクセル値を0から1の範囲にスケーリングだけする\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:14.768795Z","iopub.execute_input":"2024-07-26T09:44:14.769137Z","iopub.status.idle":"2024-07-26T09:44:14.775054Z","shell.execute_reply.started":"2024-07-26T09:44:14.769104Z","shell.execute_reply":"2024-07-26T09:44:14.774232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 画像データ生成器を適用させる\n\n\n\n# 訓練データ\ntrain_generator = train_datagen.flow_from_dataframe(X_train,\n                                                    directory = 'train/',\n                                                    x_col= 'filename',\n                                                    y_col= 'label',\n                                                    batch_size = bat_size,\n                                                    target_size = (image_size,image_size)\n                                                   )\n\n\n# 検証用データ\nval_generator = test_datagen.flow_from_dataframe(X_val, \n                                                 directory = 'train/',\n                                                 x_col= 'filename',\n                                                 y_col= 'label',\n                                                 batch_size = bat_size,\n                                                 target_size = (image_size,image_size),\n                                                 shuffle=False\n                                                )\n\n# テストデータ\ntest_generator = test_datagen.flow_from_dataframe(X_test, \n                                                  directory = 'train/',\n                                                  x_col= 'filename',\n                                                  y_col= 'label',\n                                                  batch_size = bat_size,\n                                                  target_size = (image_size,image_size),\n                                                  shuffle=False\n                                                 )","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:14.776380Z","iopub.execute_input":"2024-07-26T09:44:14.776834Z","iopub.status.idle":"2024-07-26T09:44:15.076446Z","shell.execute_reply.started":"2024-07-26T09:44:14.776802Z","shell.execute_reply":"2024-07-26T09:44:15.075599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 拡張前後のデータ比較","metadata":{}},{"cell_type":"code","source":"# グリッドサイズを20x5インチに設定\nplt.figure(figsize=(20, 5))\n# サブプロット間の垂直方向のスペースを0.4インチに設定\nplt.subplots_adjust(hspace=0.4)\n\n# 同じ画像ファイルを元に表示\nfor i in range(10):\n    filename = X_train.iloc[i]['filename']\n    \n    # 元画像を表示\n    img_path = os.path.join(image_dir, filename)\n    img = load_img(img_path, target_size=(128, 128))\n    img_array = img_to_array(img) / 255.0\n    \n    plt.subplot(2, 10, i + 1)\n    plt.imshow(img_array)\n    plt.axis('off')\n    plt.title(\"before\")\n    \n    # 拡張された画像を表示\n    img_array = img_to_array(img)  # データ拡張のために配列に変換\n    img_array = img_array.reshape((1,) + img_array.shape)  # バッチ用に形状を変更\n    aug_iter = train_datagen.flow(img_array, batch_size=1) # データ拡張の適用\n    aug_img = next(aug_iter)[0]  # 拡張された画像を取得\n    \n    plt.subplot(2, 10, i + 11)\n    plt.imshow(aug_img)\n    plt.axis('off')\n    plt.title(\"after\")\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:15.077595Z","iopub.execute_input":"2024-07-26T09:44:15.077946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 深層学習モデル（CNN)\n・入力画像は128x128ピクセルのサイズでRGBチャンネル（3チャンネル）を持ち、各層で特徴抽出と分類を行う。\n\n・畳み込み層とプーリング層を複数組み合わせて、画像から階層的な特徴を抽出し、全結合層でこれらの特徴を分類に活用する。\n\n・バッチ正規化とドロップアウトを用いて学習の安定化を図り、最終的には2つの出力ノードを持つsoftmax層で、画像が犬または猫である確率を出力する。","metadata":{}},{"cell_type":"code","source":"# CNNモデル\n\n# Sequential モデルは、層を順番に積み重ねていくシンプルなモデル\nmodel = Sequential()\n\n# 入力層\n# Conv2Dは32個の3x3のフィルタを使用し、ReLU活性化関数を持つ畳み込み層\nmodel.add(Conv2D(32,(3,3),activation='relu',input_shape = (image_size,image_size,image_channel))) \n# バッチ正規化\nmodel.add(BatchNormalization())\n# 2x2のマックスプーリング層で特徴マップのダウンサンプリングを行う\nmodel.add(MaxPooling2D(pool_size=(2,2)))\n# ドロップアウトを用いて過学習を防ぐ\nmodel.add(Dropout(0.2))\n\n# Bloack 1 \nmodel.add(Conv2D(64,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n# Block 2\nmodel.add(Conv2D(128,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n# Block 3\nmodel.add(Conv2D(256,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.2))\n\n# 全結合層\nmodel.add(Flatten())\nmodel.add(Dense(512,activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.2))\n\n# 出力層\nmodel.add(Dense(2,activation='softmax'))\n\n# 詳細の出力\nmodel.summary()","metadata":{"execution":{"iopub.status.idle":"2024-07-26T09:44:18.647916Z","shell.execute_reply.started":"2024-07-26T09:44:17.577036Z","shell.execute_reply":"2024-07-26T09:44:18.647037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"コールバック","metadata":{}},{"cell_type":"code","source":"# コールバックの定義\n# 特定の条件に基づいて学習率を動的に減少させる'ReduceLROnPlateau'コールバック\nlearning_rate_reduction = ReduceLROnPlateau(monitor = 'val_accuracy',\n                                            patience=2, # 改善が見られないエポック数の許容値\n                                            factor=0.5, # 学習率を減少させる係数\n                                            min_lr = 0.00001, # 学習率の下限値\n                                            verbose = 1) # コールバックのログ出力の詳細度\n\n# 検証データの損失 (val_loss) をモニタリングし、訓練を早期に停止させる'EarlyStopping'コールバック\nearly_stoping = EarlyStopping(monitor='val_loss',patience= 3,restore_best_weights=True,verbose=0)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:18.649015Z","iopub.execute_input":"2024-07-26T09:44:18.649283Z","iopub.status.idle":"2024-07-26T09:44:18.654707Z","shell.execute_reply.started":"2024-07-26T09:44:18.649259Z","shell.execute_reply":"2024-07-26T09:44:18.653791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"コンパイル","metadata":{}},{"cell_type":"code","source":"# モデルのコンパイル\n# optimizer:最適化アルゴリズムの指定\n# loss:損失関数の指定\n# metrics:評価指標の指定。Accuracy=\"精度\"\nmodel.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:18.655909Z","iopub.execute_input":"2024-07-26T09:44:18.656582Z","iopub.status.idle":"2024-07-26T09:44:18.676110Z","shell.execute_reply.started":"2024-07-26T09:44:18.656558Z","shell.execute_reply":"2024-07-26T09:44:18.675225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 学習\n※次から学習のため、右上の3つ丸からAcceleratorを選択するとよい","metadata":{}},{"cell_type":"code","source":"# 学習\ncat_dog = model.fit(train_generator,\n                    validation_data = val_generator, \n                    callbacks=[early_stoping,learning_rate_reduction],\n                    epochs = 30,\n                    # 必要であれば設定\n                    # steps_per_epoch = len(train_generator),\n                    # validation_steps = len(val_generaotor),\n                   )","metadata":{"execution":{"iopub.status.busy":"2024-07-26T09:44:18.677354Z","iopub.execute_input":"2024-07-26T09:44:18.677770Z","iopub.status.idle":"2024-07-26T10:23:14.210086Z","shell.execute_reply.started":"2024-07-26T09:44:18.677739Z","shell.execute_reply":"2024-07-26T10:23:14.209179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 精度と損失をエポック数毎にグラフで表示\n\nerror = pd.DataFrame(cat_dog.history)\n\nplt.figure(figsize=(18,5),dpi=200)\nsns.set_style('darkgrid')\n\nplt.subplot(121)\nplt.title('Cross Entropy Loss',fontsize=15)\nplt.xlabel('Epochs',fontsize=12)\nplt.ylabel('Loss',fontsize=12)\nplt.plot(error['loss'], label='loss')\nplt.plot(error['val_loss'], label='val_loss')\nplt.legend()\n\nplt.subplot(122)\nplt.title('Classification Accuracy',fontsize=15)\nplt.xlabel('Epochs',fontsize=12)\nplt.ylabel('Accuracy',fontsize=12)\nplt.plot(error['accuracy'], label='accuracy')\nplt.plot(error['val_accuracy'], label='val_accuracy')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:23:14.211488Z","iopub.execute_input":"2024-07-26T10:23:14.211788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 評価","metadata":{}},{"cell_type":"code","source":"# 訓練データの評価\nloss,acc = model.evaluate(train_generator,batch_size = bat_size, verbose = 0)\n\n# 精度\nprint('The accuracy of the model for training data is:',acc*100)\n# 損失\nprint('The Loss of the model for training data is:',loss)\n\n# 検証データの評価\nloss,acc = model.evaluate(val_generator,batch_size = bat_size, verbose = 0)\n\n# 精度\nprint('The accuracy of the model for validation data is:',acc*100)\n# 損失\nprint('The Loss of the model for validation data is:',loss)","metadata":{"execution":{"iopub.status.idle":"2024-07-26T10:24:48.351765Z","shell.execute_reply.started":"2024-07-26T10:23:15.002032Z","shell.execute_reply":"2024-07-26T10:24:48.350778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# モデルの保存\nmodel.save(\"model.h5\")","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:24:48.353063Z","iopub.execute_input":"2024-07-26T10:24:48.353425Z","iopub.status.idle":"2024-07-26T10:24:48.520543Z","shell.execute_reply.started":"2024-07-26T10:24:48.353391Z","shell.execute_reply":"2024-07-26T10:24:48.519499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 予測","metadata":{}},{"cell_type":"code","source":"# テストデータによる予測\nresult = model.predict(test_generator,batch_size = bat_size,verbose = 0)\n\n# 各画像の予測されたクラスを示す配列の作成\ny_pred = np.argmax(result, axis = 1)\n# テストデータの正解ラベルを取得\ny_true = test_generator.labels\n\n# テストデータに対するモデルの損失と精度を計算\nloss,acc = model.evaluate(test_generator, batch_size = bat_size, verbose = 0)\n\nprint('The accuracy of the model for testing data is:',acc*100)\nprint('The Loss of the model for testing data is:',loss)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:24:48.522124Z","iopub.execute_input":"2024-07-26T10:24:48.523300Z","iopub.status.idle":"2024-07-26T10:24:56.462249Z","shell.execute_reply.started":"2024-07-26T10:24:48.523262Z","shell.execute_reply":"2024-07-26T10:24:56.461229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"予測結果\n\n\nPrecision（適合率）: 各クラスにおいて、正しく予測されたサンプルの割合。\n\nRecall（再現率）: 各クラスに属するサンプルのうち、正しく予測されたサンプルの割合。\n\nf1-score: 適合率と再現率の調和平均。\n\nsupport: 各クラスに対するサンプル数の合計。\n\nAccuracy: 全体の正解率（全体の正しく予測されたサンプルの割合）。\n\nmacro avg（マクロ平均）: すべてのクラスにおける評価指標（precision、recall、F1-score）を単純に平均した値\n\nweighted avg（加重平均）: 各クラスのsupport（サンプル数）に応じて加重した平均","metadata":{}},{"cell_type":"code","source":"labels =['Cat','Dog']\nprint(classification_report(y_true, y_pred,target_names=labels))","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:24:56.463727Z","iopub.execute_input":"2024-07-26T10:24:56.464159Z","iopub.status.idle":"2024-07-26T10:24:56.481768Z","shell.execute_reply.started":"2024-07-26T10:24:56.464122Z","shell.execute_reply":"2024-07-26T10:24:56.480860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 混同行列の可視化\nconfusion_mtx = confusion_matrix(y_true,y_pred) \n\nf,ax = plt.subplots(figsize = (8,4),dpi=200)\nsns.heatmap(confusion_mtx, annot=True, linewidths=0.1, cmap = \"gist_yarg_r\", linecolor=\"black\", fmt='.0f', ax=ax,cbar=False, xticklabels=labels, yticklabels=labels)\n\nplt.xlabel(\"Predicted Label\",fontsize=10)\nplt.ylabel(\"True Label\",fontsize=10)\nplt.title(\"Confusion Matrix\",fontsize=13)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:24:56.482882Z","iopub.execute_input":"2024-07-26T10:24:56.483187Z","iopub.status.idle":"2024-07-26T10:24:56.684210Z","shell.execute_reply.started":"2024-07-26T10:24:56.483162Z","shell.execute_reply":"2024-07-26T10:24:56.683338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 提出","metadata":{}},{"cell_type":"code","source":"# 提出用のKaggleテストデータを予測する\n\n# size =(128,128)\n\n# データフレームの読み込み\ntest_dir = \"../working/test/\"\nfilenames = os.listdir(test_dir)\ntest_data = pd.DataFrame({\"filename\": filenames})\ntest_data['label'] = 'unknown'\n\n\n# テストデータ用のデータ生成器の作成\ntest_idg =  test_datagen.flow_from_dataframe(test_data, \n                                     directory = \"test/\", \n                                     x_col= \"filename\",\n                                     y_col = 'label',\n                                     batch_size = bat_size,\n                                     target_size = (image_size,image_size), \n                                     class_mode = None,\n                                     shuffle = False)\n\n# テスト予測\ntest_predict = model.predict(test_idg, verbose=0)\n\n# 犬である確率を取得（モデルの出力が2クラスの場合、犬の確率は第2クラスの確率）\ndog_probabilities = test_predict[:, 1]\n\n# 結果をデータフレームに追加\ntest_data['label'] = dog_probabilities\n\n# サンプルサブミッションファイルの読み込み\nsample_submission_path = '/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv'\nsub = pd.read_csv(sample_submission_path)\n\n# ファイル名からidを抽出し、サンプルサブミッションファイルのidと一致させる\ntest_data['id'] = test_data['filename'].str.extract('(\\d+)').astype(int)\ntest_data = test_data.set_index('id')\ntest_data = test_data.sort_index()\n\n# サブミッションファイルに予測結果を追加\nsub['label'] = test_data.loc[sub['id'], 'label'].values\n\n# ラベルを小数点以下7桁にフォーマット\n#sub['label'] = sub['label'].apply(lambda x: f'{x:.7f}')\n\n# csvへの書き出し（小数点以下7桁の固定小数点表記）\nsub.to_csv('submission.csv', index=False, float_format='%.7f')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:29:31.864648Z","iopub.execute_input":"2024-07-26T10:29:31.865304Z","iopub.status.idle":"2024-07-26T10:29:48.341205Z","shell.execute_reply.started":"2024-07-26T10:29:31.865271Z","shell.execute_reply":"2024-07-26T10:29:48.340419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 分類された画像の視覚化\nfig, axes = plt.subplots(1, 10, figsize=(20, 4))\nfor idx in range(10):\n    image_path = os.path.join(test_dir, test_data.iloc[idx]['filename'])\n    image = Image.open(image_path)\n    axes[idx].imshow(image)\n    # 犬である確率をタイトルに設定\n    axes[idx].set_title(f\"{float(test_data.iloc[idx]['label']):.7f}\")\n    axes[idx].axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T10:28:06.406323Z","iopub.execute_input":"2024-07-26T10:28:06.407090Z"},"trusted":true},"execution_count":null,"outputs":[]}]}