{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Fast.ai\nFast.ai는 Pytorch 상위 Framwork이며 코드 몇 줄만으로 모델을 만들 수 있습니다. 그리고 최신 논문에서 가져온 기술들을 손쉽게 구현해낼 수 있습니다. "},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import fastai\nfrom fastai.vision import *\nfastai.__version__","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = Path('../input/2019-3rd-ml-month-with-kakr/')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load pre-trained model\n이번 Kaggle Korea 3rd Competition은 인터넷 접속을 허용하지만 대부분의 Competition들은 인터넷을 접속을 허용하지 않는 경우가 많아 이 방법을 알고 있으면 좋을 것 같아 소개해드립니다.\n커널 오른쪽 위에 + Add Dataset이라는 버튼을 눌리면 자신이 만든 private 데이터 셋이나 다른 사람들이 만든 public 데이터 셋들을 가져다 사용할 수 있게 됩니다. \n\n아래의 셀은 Imagenet으로 train 되어 있는 model을 불러와 Fast.ai가 읽을 수 있는 형태로 변형해 주었습니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Making pretrained weights work without needing to find the default filename\nfrom torch.utils import model_zoo\nPath('models').mkdir(exist_ok=True)\n!cp '../input/densenet201/densenet201.pth' 'models/'\ndef load_url(*args, **kwargs):\n    model_dir = Path('models')\n    filename  = 'densenet201.pth'\n    if not (model_dir/filename).is_file(): raise FileNotFoundError\n    return torch.load(model_dir/filename)\nmodel_zoo.load_url = load_url","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train / Test Dataframe load"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load train dataframe\ntrain_df = pd.read_csv(path/'train.csv')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load sample submission\ntest_df = pd.read_csv(path/'sample_submission.csv')\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Augmentation\n\n데이터들을 인위적으로 다양한 왜곡을 부여하여 모델에게 다양한 경험들을 하게 도와줍니다. 하지만 너무 과도한 왜곡은 모델이 목적한 것과 다르게 train이 될 수 있으니 유의하셔서 사용하셔야 합니다.\n\nFast.ai에서는 get_transforms라는 함수를 이용하여 사용하고 싶은 옵션들을 추가하여 data Augmetation을 할 수 있습니다.\n\n- do_flip : 이미지들을 좌우 / 상하 대칭으로 flip을 하는 옵션입니다.\n- flip_vert : 상하 대칭을 하거나 하지 않을 수 있게 하는 옵션입니다.\n- max_rotate : 이미지를 회전시키는 옵션이며 부여한 [-max_rotate ~ max_rotate ] 범위에서 랜덤하게 회전합니다.\n- max_zoom : 랜덤하게 zoom 하는 옵션입니다.\n- max_lighting : 랜덤하게 밝기 조절을 해줄 수 있는 옵션입니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"tfms = get_transforms(do_flip=True, flip_vert=False, max_rotate=0.10, max_zoom=1.5, max_lighting=0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train, test = [ImageList.from_df(df, path=path, cols='img_file', folder=folder) \n               for df, folder in zip([train_df, test_df], ['train', 'test'])]\ndata = (train.split_by_rand_pct(0.2, seed=42)\n        .label_from_df(cols='class')\n        .add_test(test)\n        .transform(tfms, size=224)\n        .databunch(path=Path('.'), bs=64).normalize(imagenet_stats))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch() # data에서 하나의 배치를 확인하게 할 수 있게 합니다.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.classes # data가 갖는 class들을 볼 수 있게 합니다.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model define\n\n사용할 model과 metric을 cnn_learner로 정의해 줍니다. cnn_learner의 pretrained는 default로 True로 들어가 있어 pretrain model을 사용하지 않는다면 False로 주시면 됩니다. 위에서 pretrain model을 업로드 하지 않았다면 자동으로 다운로드 받습니다.(다운로드를 받으려면 settings에 internet 옵션이 on이 되어야 가능합니다.)"},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = cnn_learner(data, base_arch=models.densenet201, metrics=accuracy)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Learning Rate Find\n\nFast.ai에는 hyper paramter인 learning rate를 찾아주는 함수가 있습니다. \n\n정확한 구동 원리는 [논문](https://arxiv.org/abs/1506.01186) 에서 설명하고 있으니 참고 하시면 좋을 것 같아요\n\n\n## Model Learning"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Find a good learning rate\nlearn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 7e-02\nlearn.fit_one_cycle(3, slice(lr))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 7e-4\nlearn.fit_one_cycle(21, slice(lr/10, lr))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test predictions\ntest_preds = learn.TTA(ds_type=DatasetType.Test)\ntest_df['class'] = np.argmax(test_preds[0], axis=1) + 1\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False) ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"[Fast.ai Documentation](https://docs.fast.ai/)에는 다양한 옵션들이 많아 참고하세요"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}