{"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"}],"isInternetEnabled":true,"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 fastai.vision.all import *\nimport zipfile\nimport albumentations as Alb","metadata":{"execution":{"iopub.status.busy":"2024-07-26T03:58:18.048598Z","iopub.execute_input":"2024-07-26T03:58:18.049084Z","iopub.status.idle":"2024-07-26T03:58:27.878359Z","shell.execute_reply.started":"2024-07-26T03:58:18.049057Z","shell.execute_reply":"2024-07-26T03:58:27.877556Z"},"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-26T03:58:27.880279Z","iopub.execute_input":"2024-07-26T03:58:27.880895Z","iopub.status.idle":"2024-07-26T03:58:42.721880Z","shell.execute_reply.started":"2024-07-26T03:58:27.880863Z","shell.execute_reply":"2024-07-26T03:58:42.720868Z"},"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-26T03:58:42.725464Z","iopub.execute_input":"2024-07-26T03:58:42.725825Z","iopub.status.idle":"2024-07-26T03:58:42.731382Z","shell.execute_reply.started":"2024-07-26T03:58:42.725800Z","shell.execute_reply":"2024-07-26T03:58:42.730138Z"},"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-26T03:58:42.733788Z","iopub.execute_input":"2024-07-26T03:58:42.734206Z","iopub.status.idle":"2024-07-26T03:58:42.948539Z","shell.execute_reply.started":"2024-07-26T03:58:42.734175Z","shell.execute_reply":"2024-07-26T03:58:42.947608Z"},"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\nitem_tfms = [Resize(224), AlbTransform(get_augs())] \nbatch_tfms = [Normalize.from_stats(*imagenet_stats), *aug_transforms()]","metadata":{"execution":{"iopub.status.busy":"2024-07-26T03:58:42.949707Z","iopub.execute_input":"2024-07-26T03:58:42.950062Z","iopub.status.idle":"2024-07-26T03:58:43.145301Z","shell.execute_reply.started":"2024-07-26T03:58:42.950031Z","shell.execute_reply":"2024-07-26T03:58:43.144328Z"},"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-26T03:58:43.146874Z","iopub.execute_input":"2024-07-26T03:58:43.147398Z","iopub.status.idle":"2024-07-26T03:58:45.669468Z","shell.execute_reply.started":"2024-07-26T03:58:43.147364Z","shell.execute_reply":"2024-07-26T03:58:45.668539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# モデルの作成\nlearn = cnn_learner(dls, resnet50, metrics=[error_rate, accuracy])","metadata":{"execution":{"iopub.status.busy":"2024-07-26T03:58:45.670639Z","iopub.execute_input":"2024-07-26T03:58:45.670939Z","iopub.status.idle":"2024-07-26T03:58:47.143343Z","shell.execute_reply.started":"2024-07-26T03:58:45.670914Z","shell.execute_reply":"2024-07-26T03:58:47.142240Z"},"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-26T03:58:47.144851Z","iopub.execute_input":"2024-07-26T03:58:47.145241Z","iopub.status.idle":"2024-07-26T04:09:45.593766Z","shell.execute_reply.started":"2024-07-26T03:58:47.145205Z","shell.execute_reply":"2024-07-26T04:09:45.592661Z"},"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:09:45.595368Z","iopub.execute_input":"2024-07-26T04:09:45.595692Z","iopub.status.idle":"2024-07-26T04:09:45.698542Z","shell.execute_reply.started":"2024-07-26T04:09:45.595662Z","shell.execute_reply":"2024-07-26T04:09:45.697662Z"},"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:09:45.701501Z","iopub.execute_input":"2024-07-26T04:09:45.701803Z","iopub.status.idle":"2024-07-26T04:09:47.195881Z","shell.execute_reply.started":"2024-07-26T04:09:45.701778Z","shell.execute_reply":"2024-07-26T04:09:47.194686Z"},"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:09:47.197074Z","iopub.execute_input":"2024-07-26T04:09:47.197403Z","iopub.status.idle":"2024-07-26T04:14:10.396310Z","shell.execute_reply.started":"2024-07-26T04:09:47.197373Z","shell.execute_reply":"2024-07-26T04:14:10.395313Z"},"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:14:10.397931Z","iopub.execute_input":"2024-07-26T04:14:10.398534Z","iopub.status.idle":"2024-07-26T04:14:10.454613Z","shell.execute_reply.started":"2024-07-26T04:14:10.398506Z","shell.execute_reply":"2024-07-26T04:14:10.453843Z"},"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:14:10.455660Z","iopub.execute_input":"2024-07-26T04:14:10.455944Z","iopub.status.idle":"2024-07-26T04:14:10.487523Z","shell.execute_reply.started":"2024-07-26T04:14:10.455920Z","shell.execute_reply":"2024-07-26T04:14:10.486732Z"},"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:14:10.488477Z","iopub.execute_input":"2024-07-26T04:14:10.488735Z","iopub.status.idle":"2024-07-26T04:14:12.008570Z","shell.execute_reply.started":"2024-07-26T04:14:10.488714Z","shell.execute_reply":"2024-07-26T04:14:12.007677Z"},"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:14:12.009864Z","iopub.execute_input":"2024-07-26T04:14:12.010197Z","iopub.status.idle":"2024-07-26T04:14:13.310053Z","shell.execute_reply.started":"2024-07-26T04:14:12.010169Z","shell.execute_reply":"2024-07-26T04:14:13.309197Z"},"trusted":true},"execution_count":null,"outputs":[]}]}