{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","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":31040,"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":{"iopub.status.busy":"2025-07-04T07:46:23.767748Z","iopub.execute_input":"2025-07-04T07:46:23.768024Z","iopub.status.idle":"2025-07-04T07:46:25.565509Z","shell.execute_reply.started":"2025-07-04T07:46:23.767997Z","shell.execute_reply":"2025-07-04T07:46:25.564625Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 必要なライブラリをインポート","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications.vgg16 import VGG16\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nfrom matplotlib import pyplot as plt\nimport shutil\nimport os\nimport glob","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T07:54:03.29407Z","iopub.execute_input":"2025-07-04T07:54:03.294393Z","iopub.status.idle":"2025-07-04T07:54:03.29942Z","shell.execute_reply.started":"2025-07-04T07:54:03.294368Z","shell.execute_reply":"2025-07-04T07:54:03.298511Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Zipファイルを解凍","metadata":{}},{"cell_type":"code","source":"shutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip', '/kaggle/working')\nshutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip', '/kaggle/working')\n\n\nshutil.copyfile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv','/kaggle/working/sample_submission.csv')\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        \nfiles = glob.glob('/kaggle/working/*')\nfor file in files:\n    print(file)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T07:57:30.077854Z","iopub.execute_input":"2025-07-04T07:57:30.078174Z","iopub.status.idle":"2025-07-04T07:57:45.386419Z","shell.execute_reply.started":"2025-07-04T07:57:30.078148Z","shell.execute_reply":"2025-07-04T07:57:45.385715Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 画像サイズとディレクトリの設定\n","metadata":{}},{"cell_type":"code","source":"img_width, img_height = 150, 150 \ntrain_dir = '/kaggle/working/train' \ntest_dir = '/kaggle/working/test' ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T07:59:06.110859Z","iopub.execute_input":"2025-07-04T07:59:06.111161Z","iopub.status.idle":"2025-07-04T07:59:06.115494Z","shell.execute_reply.started":"2025-07-04T07:59:06.111137Z","shell.execute_reply":"2025-07-04T07:59:06.114669Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## エポック定数の設定","metadata":{}},{"cell_type":"code","source":"epoch = 20","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T07:59:47.020546Z","iopub.execute_input":"2025-07-04T07:59:47.020912Z","iopub.status.idle":"2025-07-04T07:59:47.025612Z","shell.execute_reply.started":"2025-07-04T07:59:47.020881Z","shell.execute_reply":"2025-07-04T07:59:47.024727Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 分類クラス名の設定","metadata":{}},{"cell_type":"code","source":"classes = ['dog','cat']\nnb_classes = len(classes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:01:03.15098Z","iopub.execute_input":"2025-07-04T08:01:03.151295Z","iopub.status.idle":"2025-07-04T08:01:03.157099Z","shell.execute_reply.started":"2025-07-04T08:01:03.15127Z","shell.execute_reply":"2025-07-04T08:01:03.155523Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## VGG16モデルのロード","metadata":{}},{"cell_type":"code","source":"os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"-1\"\nvgg_model = VGG16(include_top = False, weights = 'imagenet', input_shape = (img_height, img_width, 3))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:07:30.338996Z","iopub.execute_input":"2025-07-04T08:07:30.339355Z","iopub.status.idle":"2025-07-04T08:07:30.706333Z","shell.execute_reply.started":"2025-07-04T08:07:30.339325Z","shell.execute_reply":"2025-07-04T08:07:30.705368Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## VGG16モデルの下に全結合層を追加","metadata":{}},{"cell_type":"code","source":"model = Sequential()\nmodel.add(vgg_model)\nmodel.add(Flatten())\nmodel.add(Dense(256, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(nb_classes, activation='softmax'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:09:40.104294Z","iopub.execute_input":"2025-07-04T08:09:40.105265Z","iopub.status.idle":"2025-07-04T08:09:40.156418Z","shell.execute_reply.started":"2025-07-04T08:09:40.105228Z","shell.execute_reply":"2025-07-04T08:09:40.155593Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"VGG16モデルの上位15層のパラメータを凍結(Fine tuning)","metadata":{}},{"cell_type":"code","source":"for layer in vgg_model.layers[:15]:\n layer.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:10:51.655798Z","iopub.execute_input":"2025-07-04T08:10:51.656645Z","iopub.status.idle":"2025-07-04T08:10:51.660582Z","shell.execute_reply.started":"2025-07-04T08:10:51.656619Z","shell.execute_reply":"2025-07-04T08:10:51.6598Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"モデルの詳細を表示","metadata":{}},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:11:25.651471Z","iopub.execute_input":"2025-07-04T08:11:25.651738Z","iopub.status.idle":"2025-07-04T08:11:25.67178Z","shell.execute_reply.started":"2025-07-04T08:11:25.65172Z","shell.execute_reply":"2025-07-04T08:11:25.670812Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"損失関数は交差エントロピー、最適化関数は確率的勾配法","metadata":{}},{"cell_type":"code","source":"model.compile(loss = 'categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:11:54.560411Z","iopub.execute_input":"2025-07-04T08:11:54.560742Z","iopub.status.idle":"2025-07-04T08:11:54.577054Z","shell.execute_reply.started":"2025-07-04T08:11:54.560719Z","shell.execute_reply":"2025-07-04T08:11:54.57627Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"犬・猫の画像を，それぞれ保存するフォルダのパスを定義","metadata":{}},{"cell_type":"code","source":"dog_dir = '/kaggle/working/train/dog'\ncat_dir = '/kaggle/working/train/cat'\n\nos.makedirs(dog_dir, exist_ok = True)\nos.makedirs(cat_dir, exist_ok = True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:12:26.323552Z","iopub.execute_input":"2025-07-04T08:12:26.323863Z","iopub.status.idle":"2025-07-04T08:12:26.329491Z","shell.execute_reply.started":"2025-07-04T08:12:26.32384Z","shell.execute_reply":"2025-07-04T08:12:26.328308Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"犬・猫の画像をそれぞれのフォルダに移動\n訓練用フォルダ内の全ファイルパスを取得","metadata":{}},{"cell_type":"code","source":"files = glob.glob('/kaggle/working/train/*.jpg')\nfor file in files:\n    file_name = os.path.basename(file)\n    if 'cat' in file:\n        shutil.move(file,'/kaggle/working/train/cat/' + file_name)\n    else:\n        shutil.move(file,'/kaggle/working/train/dog/' + file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:13:06.696177Z","iopub.execute_input":"2025-07-04T08:13:06.696523Z","iopub.status.idle":"2025-07-04T08:13:07.401743Z","shell.execute_reply.started":"2025-07-04T08:13:06.696501Z","shell.execute_reply":"2025-07-04T08:13:07.400904Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"学習データのデータ拡張を設定","metadata":{}},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale = 1.0 / 255, rotation_range = 90, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True,\n                vertical_flip = True, fill_mode = 'reflect', validation_split = 0.2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:13:56.095158Z","iopub.execute_input":"2025-07-04T08:13:56.095503Z","iopub.status.idle":"2025-07-04T08:13:56.100076Z","shell.execute_reply.started":"2025-07-04T08:13:56.09548Z","shell.execute_reply":"2025-07-04T08:13:56.099362Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"評価データのデータ拡張を設定","metadata":{}},{"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale = 1.0 / 255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:14:22.704263Z","iopub.execute_input":"2025-07-04T08:14:22.704545Z","iopub.status.idle":"2025-07-04T08:14:22.708854Z","shell.execute_reply.started":"2025-07-04T08:14:22.704525Z","shell.execute_reply":"2025-07-04T08:14:22.707998Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"学習データのジェネレータを生成","metadata":{}},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(train_dir, target_size = (img_height, img_width), classes = classes, batch_size = 32, class_mode = 'categorical', subset = \"training\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:14:50.143308Z","iopub.execute_input":"2025-07-04T08:14:50.143595Z","iopub.status.idle":"2025-07-04T08:14:50.377827Z","shell.execute_reply.started":"2025-07-04T08:14:50.143574Z","shell.execute_reply":"2025-07-04T08:14:50.376927Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"評価データのジェネレータを生成","metadata":{}},{"cell_type":"code","source":"test_generator = train_datagen.flow_from_directory(train_dir, target_size = (img_height, img_width), classes = classes, batch_size = 32, class_mode = 'categorical', subset = \"validation\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:15:18.655655Z","iopub.execute_input":"2025-07-04T08:15:18.655958Z","iopub.status.idle":"2025-07-04T08:15:18.759306Z","shell.execute_reply.started":"2025-07-04T08:15:18.655939Z","shell.execute_reply":"2025-07-04T08:15:18.758628Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"コールバック関数(モデル保存)の設定","metadata":{}},{"cell_type":"code","source":"mc_cb = ModelCheckpoint(filepath = 'finetuning.h5', monitor = 'vol_loss', verbose = 1, save_best_only = True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:16:18.35609Z","iopub.execute_input":"2025-07-04T08:16:18.356751Z","iopub.status.idle":"2025-07-04T08:16:18.360838Z","shell.execute_reply.started":"2025-07-04T08:16:18.356725Z","shell.execute_reply":"2025-07-04T08:16:18.359983Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"ジェネレータを用いたモデル学習","metadata":{}},{"cell_type":"code","source":"history = model.fit(train_generator, epochs=epoch, validation_data = test_generator, callbacks = [mc_cb])\n\nmodel.save('finetuning.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-04T08:16:40.695898Z","iopub.execute_input":"2025-07-04T08:16:40.696347Z","iopub.status.idle":"2025-07-04T08:16:40.717248Z","shell.execute_reply.started":"2025-07-04T08:16:40.696316Z","shell.execute_reply":"2025-07-04T08:16:40.716246Z"}},"outputs":[],"execution_count":null}]}