{"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":"gpu","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":82405,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":69220,"modelId":94344}],"dockerImageVersionId":30746,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport time\nfrom torchvision.models import resnet50\nimport torch\nfrom fastai.vision.all import *\nimport zipfile\nimport albumentations as Alb","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-26T04:30:13.541534Z","iopub.execute_input":"2024-07-26T04:30:13.542684Z","iopub.status.idle":"2024-07-26T04:30:13.548815Z","shell.execute_reply.started":"2024-07-26T04:30:13.542632Z","shell.execute_reply":"2024-07-26T04:30:13.547825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# データセットの展開\nwith zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/train.zip', 'r') as zip_ref:\n    zip_ref.extractall('.')\nwith zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/test.zip', 'r') as zip_ref:\n    zip_ref.extractall('.')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:13.550658Z","iopub.execute_input":"2024-07-26T04:30:13.550977Z","iopub.status.idle":"2024-07-26T04:30:28.363645Z","shell.execute_reply.started":"2024-07-26T04:30:13.550951Z","shell.execute_reply":"2024-07-26T04:30:28.362730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 不良画像の削除\nbad_images = [\n    'dog.10797.jpg', 'dog.10747.jpg', 'dog.10237.jpg', 'dog.9517.jpg',\n    'dog.8736.jpg', 'dog.5604.jpg', 'dog.1043.jpg', 'cat.4338.jpg',\n    'dog.10161.jpg', 'dog.10190.jpg'\n]\nfor img in bad_images:\n    os.remove(f'./train/{img}')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:28.364779Z","iopub.execute_input":"2024-07-26T04:30:28.365072Z","iopub.status.idle":"2024-07-26T04:30:28.370296Z","shell.execute_reply.started":"2024-07-26T04:30:28.365048Z","shell.execute_reply":"2024-07-26T04:30:28.369447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# データセットの読み込み\ntpath = \"./train\"\nftrain = get_image_files(tpath)\nprint('Train set size:', len(ftrain))","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:28.371547Z","iopub.execute_input":"2024-07-26T04:30:28.371952Z","iopub.status.idle":"2024-07-26T04:30:28.751587Z","shell.execute_reply.started":"2024-07-26T04:30:28.371922Z","shell.execute_reply":"2024-07-26T04:30:28.750626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# データ拡張の定義\nclass AlbTransform(Transform):\n    def __init__(self, aug): self.aug = aug\n    def encodes(self, img: PILImage):\n        aug_img = self.aug(image=np.array(img))['image']\n        return PILImage.create(aug_img)\n\ndef get_augs():\n    return Alb.Compose([\n        Alb.ShiftScaleRotate(rotate_limit=20, border_mode=0, value=(0,0,0)),\n        Alb.Transpose(),\n        Alb.Flip(),\n        Alb.RandomRotate90(),\n        Alb.RandomBrightnessContrast(),\n        Alb.HueSaturationValue(hue_shift_limit=5, sat_shift_limit=5, val_shift_limit=5),\n        Alb.CoarseDropout()\n    ])\n\n\nitem_tfms = [Resize(224), AlbTransform(get_augs())]\nbatch_tfms = [Normalize.from_stats(*imagenet_stats), *aug_transforms()]","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:28.754082Z","iopub.execute_input":"2024-07-26T04:30:28.754435Z","iopub.status.idle":"2024-07-26T04:30:28.958709Z","shell.execute_reply.started":"2024-07-26T04:30:28.754385Z","shell.execute_reply":"2024-07-26T04:30:28.957872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# データローダーの作成\ndls = ImageDataLoaders.from_name_re(\n    path=tpath, fnames=ftrain, pat=r'(.+)\\.\\d+.jpg$', valid_pct=0.1,\n    item_tfms=item_tfms, batch_tfms=batch_tfms, bs=64, shuffle=True\n)\n\nprint('train items:', len(dls.train.items), 'validation items:', len(dls.valid.items))","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:28.959926Z","iopub.execute_input":"2024-07-26T04:30:28.960209Z","iopub.status.idle":"2024-07-26T04:30:31.514686Z","shell.execute_reply.started":"2024-07-26T04:30:28.960184Z","shell.execute_reply":"2024-07-26T04:30:31.513474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# モデルの作成\n# Kaggleノートブックにアップロードしたファイルのパスを指定\nmodel_path = '/kaggle/input/resnet50/pytorch/default/1/resnet50-11ad3fa6.pth'\n\n# ローカルに保存した重みをロード\nmodel = resnet50()\nmodel.load_state_dict(torch.load(model_path))\n\n# Learnerの作成\nlearn = Learner(dls, model, metrics=[error_rate, accuracy])","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:31.516066Z","iopub.execute_input":"2024-07-26T04:30:31.516467Z","iopub.status.idle":"2024-07-26T04:30:33.214824Z","shell.execute_reply.started":"2024-07-26T04:30:31.516432Z","shell.execute_reply":"2024-07-26T04:30:33.213717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 学習率のスケジューリングを追加\nlearn.fit_one_cycle(5, lr_max=slice(1e-3, 1e-2))","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:30:33.216025Z","iopub.execute_input":"2024-07-26T04:30:33.216339Z","iopub.status.idle":"2024-07-26T04:42:09.187844Z","shell.execute_reply.started":"2024-07-26T04:30:33.216313Z","shell.execute_reply":"2024-07-26T04:42:09.186874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# テストデータの準備\nftest = get_image_files('test')\nprint('Testing', len(ftest), 'items')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:42:09.189277Z","iopub.execute_input":"2024-07-26T04:42:09.189594Z","iopub.status.idle":"2024-07-26T04:42:09.292665Z","shell.execute_reply.started":"2024-07-26T04:42:09.189566Z","shell.execute_reply":"2024-07-26T04:42:09.291797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# テストデータローダーの作成\ntst_dl = dls.test_dl(ftest, with_labels=False, shuffle=False)\ntst_dl.show_batch(max_n=12)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:42:09.293824Z","iopub.execute_input":"2024-07-26T04:42:09.294097Z","iopub.status.idle":"2024-07-26T04:42:10.802657Z","shell.execute_reply.started":"2024-07-26T04:42:09.294073Z","shell.execute_reply":"2024-07-26T04:42:10.801581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 推論の実行\nstartTime = time.time()\npreds = learn.tta(dl=tst_dl, n=5, use_max=False)\nprint('TTA in:', time.time()-startTime, 'secs')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:42:10.803823Z","iopub.execute_input":"2024-07-26T04:42:10.804167Z","iopub.status.idle":"2024-07-26T04:46:41.039054Z","shell.execute_reply.started":"2024-07-26T04:42:10.804140Z","shell.execute_reply":"2024-07-26T04:46:41.037915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 結果の保存\nsubm_df = pd.DataFrame()\nsubm_df['id'] = [item.stem for item in tst_dl.items]\nsubm_df['label'] = preds[0][:,1].clip(0.005, 0.995)\nsubm_df.to_csv('submission.csv', header=True, index=False)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:46:41.040581Z","iopub.execute_input":"2024-07-26T04:46:41.040887Z","iopub.status.idle":"2024-07-26T04:46:41.106228Z","shell.execute_reply.started":"2024-07-26T04:46:41.040859Z","shell.execute_reply":"2024-07-26T04:46:41.105326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ソフトマックスを使用した予測結果の保存\nsubm_df['label'] = torch.softmax(preds[0], dim=1)[:, 1]\nsubm_df.to_csv('submission-softmax.csv', header=True, index=False)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:46:41.107439Z","iopub.execute_input":"2024-07-26T04:46:41.107755Z","iopub.status.idle":"2024-07-26T04:46:41.182310Z","shell.execute_reply.started":"2024-07-26T04:46:41.107729Z","shell.execute_reply":"2024-07-26T04:46:41.181603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 推論結果の可視化\ntst_dl.show_batch(max_n=12)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:46:41.185261Z","iopub.execute_input":"2024-07-26T04:46:41.185617Z","iopub.status.idle":"2024-07-26T04:46:42.982379Z","shell.execute_reply.started":"2024-07-26T04:46:41.185593Z","shell.execute_reply":"2024-07-26T04:46:42.981467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# クリーンアップ\nfrom shutil import rmtree\nrmtree('./train', ignore_errors=True)\nrmtree('./test', ignore_errors=True)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T04:46:42.983706Z","iopub.execute_input":"2024-07-26T04:46:42.984036Z","iopub.status.idle":"2024-07-26T04:46:44.277836Z","shell.execute_reply.started":"2024-07-26T04:46:42.984009Z","shell.execute_reply":"2024-07-26T04:46:44.276932Z"},"trusted":true},"execution_count":null,"outputs":[]}]}