{"cells":[{"metadata":{},"cell_type":"markdown","source":"https://pyy0715.github.io/2020/03/14/Albumentation_Tutorial/"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport cv2\nimport random\nimport matplotlib.pyplot as plt\n\nimport torch\nfrom torch.utils.data import Dataset\n\nimport albumentations","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nclass_map = pd.read_csv(\"../input/bengaliai-cv19/class_map.csv\")\nsample_submission = pd.read_csv(\"../input/bengaliai-cv19/sample_submission.csv\")\ntest = pd.read_csv(\"../input/bengaliai-cv19/test.csv\")\ntrain = pd.read_csv(\"../input/bengaliai-cv19/train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dir = '/kaggle/input/bengaliai-cv19/'\nfiles_train = [f'train_image_data_{fid}.parquet' for fid in range(4)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"F = os.path.join(data_dir, files_train[0])\n\ntrain0 = pd.read_parquet(F)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train0.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Train Image Data{} Shape is : {}'.format(0, train0.shape))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class BengaliDataset(Dataset):\n    def __init__(self, df, img_height, img_width):\n        self.df = df\n        self.img_height = img_height\n        self.img_width = img_width\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        img = self.df.iloc[idx][0:].values.astype(np.uint8)\n        img = img.reshape(self.img_height, self.img_width)\n        img = 255 - img\n        img = (img*(255.0/img.max())).astype(np.uint8)\n\n        return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 137\nWIDTH = 236\n\ntrain0.set_index('image_id', inplace=True)\nimage = BengaliDataset(train0, img_height=HEIGHT, img_width=WIDTH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nrow, ncol = 1, 5\n\nfig, axs = plt.subplots(nrow, ncol, figsize=(20, 10))\naxs = axs.flatten()\n\nfor i, ax in enumerate(axs):\n    img = image[i]\n    ax.imshow(img)\n    ax.set_title(f'label: Original')\n    ax.axis('off')\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import albumentations as A\n\naug = A.IAAPiecewiseAffine(p=1.0)\n\nnrow, ncol = 5, 2\nfig, axs = plt.subplots(nrow, ncol, figsize=(20, 10))\n\nfor n in range(nrow):\n    img = image[n]\n    aug_image = aug(image=img)['image']\n    \n    axs[n,0].imshow(img)\n    axs[n,0].set_title(f'label: Original')\n    axs[n,0].axis('off')\n    \n    axs[n,1].imshow(aug_image)\n    axs[n,1].set_title(f'label: Affine')\n    axs[n,1].axis('off')\n    \nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"AugMix\nAlubumentiation을 기반으로 AugMix가 어떤것인지 알아보겠습니다.\n\n먼저 아래의 사진 4장을 보면서, 대략적인 감을 잡으실 수 있을겁니다.\n\nCutOut - 이미지의 임의의 부분을 제거\n\nMixUp - 이미지 간 확률적으로 두 이미지를 섞습니다.\n\nCutMix - CutOut + MixUp\n\nAugMix - 위에서 소개한 Augmentation기법들을 섞습니다.\n\nAugMix는 이름처럼 여러 data augmentation 방법들을 혼합하여 사용한다.\n\n하지만 기존 방법들과 달리 데이터 변환으로인한 manifold를 벗어나는 일을 방지하였다.\n\n\n![](https://storage.googleapis.com/groundai-web-prod/media/users/user_135639/project_400799/images/x1.png)\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F448347%2Fe9d3259d5b0ef3dadba0238bf3901f1e%2F2020-02-10%2013.50.53.png?generation=1581310282118474&alt=media)\n\n![](https://github.com/google-research/augmix/raw/master/assets/augmix.gif)\n\n\nCIFAR-10 실험결과, AugMix는 다른 기법들보다 우수하게 성적을 냈다고 합니다.\n\nAugmix: https://arxiv.org/abs/1912.02781\n\nAugMix: A Simple Data Processing Method to Improve Robustness and Uncertainty\nhttps://arxiv.org/pdf/1912.02781v2.pdf\n\n\nOfficial implementation: https://github.com/google-research/augmix"},{"metadata":{"trusted":true},"cell_type":"code","source":"from albumentations import HorizontalFlip\nfrom albumentations.core.transforms_interface import ImageOnlyTransform\n\nclass AugMix(ImageOnlyTransform):\n    \"\"\"Augmentations mix to Improve Robustness and Uncertainty.\n    Args:\n        image (np.ndarray): Raw input image of shape (h, w, c)\n        severity (int): Severity of underlying augmentation operators.\n        width (int): Width of augmentation chain\n        depth (int): Depth of augmentation chain. -1 enables stochastic depth uniformly\n          from [1, 3]\n        alpha (float): Probability coefficient for Beta and Dirichlet distributions.\n        augmentations (list of augmentations): Augmentations that need to mix and perform.\n    Targets:\n        image\n    Image types:\n        uint8, float32\n\n    Reference:\n    |  https://arxiv.org/abs/1912.02781\n    |  https://github.com/google-research/augmix\n    \"\"\"\n\n    def __init__(self, width=2, depth=2, alpha=0.5, augmentations=[HorizontalFlip()], always_apply=False, p=0.5):\n        super(AugMix, self).__init__(always_apply, p)\n        self.width = width\n        self.depth = depth\n        self.alpha = alpha\n        self.augmentations = augmentations\n        self.ws = np.float32(np.random.dirichlet([self.alpha] * self.width))\n        self.m = np.float32(np.random.beta(self.alpha, self.alpha))\n\n    def apply_op(self, image, op):\n        image = op(image=image)[\"image\"]\n        return image\n\n    def apply(self, img, **params):\n        mix = np.zeros_like(img)\n        for i in range(self.width):\n            image_aug = img.copy()\n\n            for _ in range(self.depth):\n                op = np.random.choice(self.augmentations)\n                image_aug = self.apply_op(image_aug, op)\n\n            mix = np.add(mix, self.ws[i] * image_aug, out=mix, casting=\"unsafe\")\n\n        mixed = (1 - self.m) * img + self.m * mix\n        if img.dtype in [\"uint8\", \"uint16\", \"uint32\", \"uint64\"]:\n            mixed = np.clip((mixed), 0, 255).astype(np.uint8)\n        return mixed\n\n    def get_transform_init_args_names(self):\n        return (\"width\", \"depth\", \"alpha\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"AugMix는 아래와 같이 여러가지 기법들을 동시에 적용할 수 있으며, 확률값으로 조정이 가능합니다.\n\n또한 OneOf를 사용하여, 기법 중에서 하나의 기법만 선택할 수 있습니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"augs = [A.HorizontalFlip(always_apply=True),\n        A.Blur(always_apply=True),\n        A.ShiftScaleRotate(always_apply=True),\n        A.GaussNoise(always_apply=True),\n        A.Cutout(always_apply=True),\n        A.IAAPiecewiseAffine(always_apply=True)]\n\ntransforms_train = albumentations.Compose([\n    AugMix(width=3, depth=2, alpha=.4, p=1., augmentations=augs),\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Aug_BengaliDataset(Dataset):\n    def __init__(self, df, img_height, img_width, transform=None):\n        self.df = df\n        self.img_height = img_height\n        self.img_width = img_width\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n    \n\n    def __getitem__(self, idx):\n        img = self.df.iloc[idx][0:].values.astype(np.uint8)\n        img = img.reshape(self.img_height, self.img_width)\n        img = 255 - img\n        img = (img*(255.0/img.max())).astype(np.uint8)\n        \n        if self.transform is not None:\n            res = self.transform(image=img)\n            img = res['image']\n        else:\n            img = img\n\n        return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"aug_image = Aug_BengaliDataset(train0, img_height=HEIGHT, img_width=WIDTH, transform=transforms_train)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nrow, ncol = 5, 2\nfig, axs = plt.subplots(nrow, ncol, figsize=(15, 10))\n\nfor n in range(nrow):\n    img = image[n]\n    aug_img = aug_image[n]\n    \n    axs[n,0].imshow(img)\n    axs[n,0].set_title(f'label: Original')\n    axs[n,0].axis('off')\n    \n    axs[n,1].imshow(aug_img)\n    axs[n,1].set_title(f'label: Augmix')\n    axs[n,1].axis('off')\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}