{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"%matplotlib inline\n#這是juoyter notebook的magic word˙\n\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom IPython import display","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-17T07:05:36.369664Z","iopub.execute_input":"2022-01-17T07:05:36.370268Z","iopub.status.idle":"2022-01-17T07:05:36.385933Z","shell.execute_reply.started":"2022-01-17T07:05:36.370166Z","shell.execute_reply":"2022-01-17T07:05:36.384687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# iWildCam2020 revised3","metadata":{}},{"cell_type":"code","source":"import os\n#判斷是否在jupyter notebook上\ndef is_in_ipython():\n    \"Is the code running in the ipython environment (jupyter including)\"\n    program_name = os.path.basename(os.getenv('_', ''))\n\n    if ('jupyter-notebook' in program_name or # jupyter-notebook\n        'ipython'          in program_name or # ipython\n        'jupyter' in program_name or  # jupyter\n        'JPY_PARENT_PID'   in os.environ):    # ipython-notebook\n        return True\n    else:\n        return False\n\n\n#判斷是否在colab上\ndef is_in_colab():\n    if not is_in_ipython(): return False\n    try:\n        from google import colab\n        return True\n    except: return False\n\n#判斷是否在kaggke_kernal上\ndef is_in_kaggle_kernal():\n    if 'kaggle' in os.environ['PYTHONPATH']:\n        return True\n    else:\n        return False\n\nif is_in_colab():\n    from google.colab import drive\n    drive.mount('/content/gdrive')","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:36.388485Z","iopub.execute_input":"2022-01-17T07:05:36.389307Z","iopub.status.idle":"2022-01-17T07:05:36.401188Z","shell.execute_reply.started":"2022-01-17T07:05:36.389258Z","shell.execute_reply":"2022-01-17T07:05:36.399989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.environ['TRIDENT_BACKEND'] = 'pytorch'\n\nif is_in_kaggle_kernal():\n    os.environ['TRIDENT_HOME'] = './trident'\n    \nelif is_in_colab():\n    os.environ['TRIDENT_HOME'] = '/content/gdrive/My Drive/trident'\n\n#為確保安裝最新版 \n!pip uninstall tridentx -y\n!pip install ../input/trident/tridentx-0.7.4.1-py3-none-any.whl --upgrade\nimport json\nimport copy\nimport numpy as np\n#調用trident api\nimport trident as T\nfrom trident import *\nfrom trident.models import resnet,efficientnet","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:36.405536Z","iopub.execute_input":"2022-01-17T07:05:36.406173Z","iopub.status.idle":"2022-01-17T07:05:51.256967Z","shell.execute_reply.started":"2022-01-17T07:05:36.406126Z","shell.execute_reply":"2022-01-17T07:05:51.255654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntry:\n    import gdown\nexcept ImportError as e:\n    !pip install -U gdown\n    import gdown\n\n#以我們課程第一天的卷積示意的excel檔為例，在谷哥硬碟ui上可以獲得分享連結如下\n#https://drive.google.com/file/d/1fjz57gP49bF990XueaaMJFobbqch5KuY/view?usp=sharing\n#請將中間的文件編號擷取出來    1fjz57gP49bF990XueaaMJFobbqch5KuY\n#將它置換為下列url格式   https://drive.google.com/uc?id={}\nurl = 'https://drive.google.com/uc?id=1Cv3gMMYKaBfcFIlSv1fO9Ufi3XpWPdoU'\n\noutput = 'result.zip'\n\ngdown.download(url, output, quiet=False)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:51.259458Z","iopub.execute_input":"2022-01-17T07:05:51.260103Z","iopub.status.idle":"2022-01-17T07:05:56.288163Z","shell.execute_reply.started":"2022-01-17T07:05:51.260051Z","shell.execute_reply":"2022-01-17T07:05:56.286933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\nwith open('../input/iwildcam-2020-fgvc7/iwildcam2020_train_annotations.json') as json_file:\n    train_data = json.load(json_file)\n\n\nwith open('../input/iwildcam-2020-fgvc7/iwildcam2020_test_information.json') as test_json_file:\n    test_data = json.load(test_json_file)\n\n    \ndf_train = pd.DataFrame({'id': [item['id'] for item in train_data['annotations']],\n                         'category_id': [item['category_id'] for item in train_data['annotations']],\n                         'image_id': [item['image_id'] for item in train_data['annotations']],\n                         'location': [item['location'] for item in train_data['images']],\n                         'file_name': [item['file_name'] for item in train_data['images']]})\ndf_test = pd.DataFrame({'image_id': [item['id'] for item in train_data['images']],\n                         'location': [item['location'] for item in train_data['images']],\n                         'file_name': [item['file_name'] for item in train_data['images']]})\n\n\n\ndf_train","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:56.289935Z","iopub.execute_input":"2022-01-17T07:05:56.291048Z","iopub.status.idle":"2022-01-17T07:05:58.880883Z","shell.execute_reply.started":"2022-01-17T07:05:56.290967Z","shell.execute_reply":"2022-01-17T07:05:58.879582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_category_train=pd.DataFrame({'id': [item['id'] for item in train_data['categories']],\n                         'name': [item['name'] for item in train_data['categories']],\n                         'count': [item['count'] for item in train_data['categories']]})\n\ndf_category_test=pd.DataFrame({'id': [item['id'] for item in test_data['categories']],\n                         'name': [item['name'] for item in test_data['categories']],\n                         'count': [item['count'] for item in test_data['categories']]})\n\ndf_category_train=df_category_train.sort_values(['count'],ascending=False) \nprint(df_category_train)\ndf_category_test=df_category_test.sort_values(['count'],ascending=False) \nprint(df_category_test)\n\n#基於標註檔，產生有在標註檔內的所有圖片的清單，進行去重複(set)、排序(sorted)以及轉換成清單(list)\nanimal_category_lists=list(sorted(set([item['category_id'] for item in train_data['annotations']])))\n\n\n#進行篩選\ndf_category_train=df_category_train[df_category_train['id'].isin(animal_category_lists)]\nprint(df_category_train)\n\ndf_category_test=df_category_test[df_category_test['count']>0]\nprint(df_category_test)\n\nanimal_category_lists_train=[category_id.item() for category_id in df_category_train[['id']].to_numpy().astype(np.int64)]\nprint(animal_category_lists_train[:5])\n\nanimal_category_lists_test=[category_id.item() for category_id in df_category_test[['id']].to_numpy().astype(np.int64)]\nprint(animal_category_lists_test[:5])\n\n#檢查是不是所有df_category_test數量不為零的動物都有出現在df_category_train的類別代號中\ncategory_missing_list=[category_id for category_id in animal_category_lists_test if category_id not in animal_category_lists_train]\nprint(category_missing_list)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:58.882573Z","iopub.execute_input":"2022-01-17T07:05:58.882978Z","iopub.status.idle":"2022-01-17T07:05:58.958408Z","shell.execute_reply.started":"2022-01-17T07:05:58.882947Z","shell.execute_reply":"2022-01-17T07:05:58.957195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"除了數量外，我們也要注意到，出現最多的動物以及出現最少的動物，其圖片數量相差了1.6萬倍，由於有許多動物只出現一次，為了避免包含只有出現過一次的動物的圖片因為數據增強或是其他因素意外的沒有呈現出該動物特徵而讓整個動物類別都無法識別，因此，我打算先把所有出現頻率超低的動物先列出來，然後將包含這些動物的圖片多複製幾分與原圖片集融合，這樣就比較不會有前述的問題。","metadata":{}},{"cell_type":"code","source":"label2category=OrderedDict()\ncategory2label=OrderedDict()\n#產生能將category_id轉label的字典\nfor i in range(len(animal_category_lists_train)):\n    category2label[animal_category_lists_train[i]]=i\n    label2category[i]=animal_category_lists_train[i]\n\n#建構出轉成標籤id\nlabel_idxes=[category2label[item['category_id']] for item in train_data['annotations']]\nimage_pathes=['../input/iwildcam-2020-fgvc7/train/'+item['file_name'] for item in train_data['images']]\n\nprint('label_idxes',label_idxes[:5])\nprint('image_pathes',image_pathes[:5])\nprint('label2category',list(label2category.items())[:5])\nprint('category2label',list(category2label.items())[:5])","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:58.960387Z","iopub.execute_input":"2022-01-17T07:05:58.960915Z","iopub.status.idle":"2022-01-17T07:05:59.097657Z","shell.execute_reply.started":"2022-01-17T07:05:58.960871Z","shell.execute_reply":"2022-01-17T07:05:59.096226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rare_animals=OrderedDict()\ncommon_animals=OrderedDict()\ndf_animal_frequency=df_train['category_id'].value_counts()\n\ndf_rare_animal_frequency=df_animal_frequency[df_animal_frequency<=10]\ndf_common_animal_frequency=df_animal_frequency[df_animal_frequency>1000]\n\nfor item in  df_rare_animal_frequency.iteritems() :\n    rare_animals[item[0]]=item[1]\n    \nfor item in  df_common_animal_frequency.iteritems() :\n    common_animals[item[0]]=item[1]\n    \nprint('rare_animals',len(rare_animals))\nprint('common_animals',len(common_animals))","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:59.099462Z","iopub.execute_input":"2022-01-17T07:05:59.099970Z","iopub.status.idle":"2022-01-17T07:05:59.118770Z","shell.execute_reply.started":"2022-01-17T07:05:59.099921Z","shell.execute_reply":"2022-01-17T07:05:59.117131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import glob\n#透過glob所全部train資料夾中所有可用圖片\nimgs=glob.glob('../input/iwildcam-2020-fgvc7/train/*.jpg')\nprint(len(imgs))\nprint(imgs[:5])\n\n#將圖檔路徑去除資料夾部分後進行去重複\nimg_pathes=[img.split('/')[-1] for img in imgs]\nimg_pathes=list(sorted(set(img_pathes)))\nprint(len(img_pathes))\nprint(img_pathes[:5])\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:05:59.123746Z","iopub.execute_input":"2022-01-17T07:05:59.124152Z","iopub.status.idle":"2022-01-17T07:06:00.373177Z","shell.execute_reply.started":"2022-01-17T07:05:59.124116Z","shell.execute_reply":"2022-01-17T07:06:00.371411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rare_images=[]\nrare_labels=[]\nfor i in range(len(image_pathes)):\n    img=image_pathes[i]\n    label=label_idxes[i]\n    if label2category[label] in rare_animals:\n        cnt=rare_animals[label2category[label]]\n        for n in range(int(20.0/cnt)):\n             rare_images.append(img) \n             rare_labels.append(label) \n        \nprint(len(rare_images))\nprint(len(rare_labels))\nprint(rare_images[:5])\nprint(rare_labels[:5])","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:00.376279Z","iopub.execute_input":"2022-01-17T07:06:00.376914Z","iopub.status.idle":"2022-01-17T07:06:00.514543Z","shell.execute_reply.started":"2022-01-17T07:06:00.376864Z","shell.execute_reply":"2022-01-17T07:06:00.513253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimg_ds=ImageDataset(image_pathes+rare_images,symbol='image')\nlabel_ds=LabelDataset(label_idxes+rare_labels,symbol='label')\n\n#非常見動物的全部+常見動物基於頻率調整成為1000\nsample_filter=lambda x:label2category[x[-1]] not in common_animals.key_list or random.random()<(1000.0/common_animals[label2category[x[-1]]])\n\n\n#與Iterator構成data provider\ndata_provider=DataProvider(traindata=Iterator(data=img_ds,label=label_ds))\n\ndata_provider.image_transform_funcs=[\n    Resize((224,224)),\n    CLAHE(),\n    RandomAdjustGamma(scale=(0.8,1.2)),#調整明暗\n    RandomAdjustHue(scale=(-0.2,0.2)),#調整色相\n    RandomAdjustSaturation(scale=(0.8,1.2)),#調整飽和度\n    SaltPepperNoise(0.005, keep_prob=0.5),#加入胡椒鹽噪音\n    RandomErasing(size_range=(0.05, 0.2), transparency_range=(0.4, 0.8), transparancy_ratio=1.0, keep_prob=0.5), #加入隨機擦去\n    RandomTransformAffine(rotation_range=45, zoom_range=0.00, shift_range=0.00, shear_range=0.2, random_flip=0.15),#隨機仿射變換\n    Normalize(127.5,127.5)] #標準化\n\n\ndata,labels=data_provider.next()\nprint(data.shape)\nprint(labels)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:00.516500Z","iopub.execute_input":"2022-01-17T07:06:00.516961Z","iopub.status.idle":"2022-01-17T07:06:05.210328Z","shell.execute_reply.started":"2022-01-17T07:06:00.516914Z","shell.execute_reply":"2022-01-17T07:06:05.209311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ndata_provider.preview_images()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:05.212700Z","iopub.execute_input":"2022-01-17T07:06:05.213398Z","iopub.status.idle":"2022-01-17T07:06:06.320088Z","shell.execute_reply.started":"2022-01-17T07:06:05.213338Z","shell.execute_reply":"2022-01-17T07:06:06.318249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from trident.models import efficientnet\n\nnet1=efficientnet.EfficientNetB0(pretrained=True,include_top=False,classes=len(animal_category_lists_train),input_shape=(3,224,224),freeze_features=True)\nnet1.model.add_module('last_conv',Conv2d_Block((3,3),num_filters=len(animal_category_lists_train),use_bias=False,activation=None, normalization='l2'))\ncam=ShortCut(\n    Identity(),\n    Sequential(\n    GlobalAvgPool2d(),\n    Reshape((len(animal_category_lists_train),1,1)),\n    Conv2d((1,1),num_filters=len(animal_category_lists_train),use_bias=False,activation=None)\n    )\n,mode='dot'\n)\n\nnet1.model.add_module('cam',cam)\nnet1.model.add_module('aggregate1',Aggregation('sum',axis=2))\nnet1.model.add_module('aggregate2',Aggregation('sum',axis=3))\nnet1.model.add_module('reshape',Reshape((len(animal_category_lists_train))))\nnet1.model.add_module('sigmoid',Sigmoid())\nnet1.model.add_module('fc',Dense((len(animal_category_lists_train))))\nnet1.model.add_module('softmax',SoftMax(axis=-1,add_noise=True,noise_intensity=0.12))\nnet1.summary()\n\nnet1.model.block7a.trainable=True","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:06.321433Z","iopub.execute_input":"2022-01-17T07:06:06.321871Z","iopub.status.idle":"2022-01-17T07:06:07.797302Z","shell.execute_reply.started":"2022-01-17T07:06:06.321830Z","shell.execute_reply":"2022-01-17T07:06:07.796169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"這次我們增加的一個新的網路，看起來跟net1幾乎一樣，但是在最後全連接層之前加入了L2NORM，最後全連接層也加入了weights_norm='l2'，以及不再加入Softmax，這到底是在做甚麼呢。基本上應該要跟後面的新的損失函數ArcMarginProductLoss放在一起看才會有意義。","metadata":{}},{"cell_type":"code","source":"net2=efficientnet.EfficientNetB0(pretrained=True,include_top=False,classes=len(animal_category_lists_train),input_shape=(3,224,224),freeze_features=True)\nnet2.model.add_module('output_layer', \n    Sequential(\n        Dropout(dropout_rate=0.4),\n        Flatten(),\n        Dense((512),use_bias=False),\n    ))\nnet2.model.add_module('l2norm',L2Norm())\nnet2.model.add_module('fc',Dense((len(animal_category_lists_train)),use_bias=False,weights_norm='l2'))\nnet2.summary()\nnet2.model.block7a.trainable=True","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:07.800400Z","iopub.execute_input":"2022-01-17T07:06:07.800796Z","iopub.status.idle":"2022-01-17T07:06:09.484497Z","shell.execute_reply.started":"2022-01-17T07:06:07.800752Z","shell.execute_reply":"2022-01-17T07:06:09.483197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from trident.models import visual_transformer\nvit=visual_transformer.VisionTransformer_small(input_shape=(3,224,224),patch_size=16,num_classes=len(animal_category_lists_train))\nvit.model[-1].add_noise=True\nvit.model[-1].noise_intensity=0.12\nvit.model.trainable=True\nvit.summary()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:09.486245Z","iopub.execute_input":"2022-01-17T07:06:09.486671Z","iopub.status.idle":"2022-01-17T07:06:10.221039Z","shell.execute_reply.started":"2022-01-17T07:06:09.486636Z","shell.execute_reply":"2022-01-17T07:06:10.219794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"ArcMarginProductLoss是跟ARCFACE借來的概念。為什麼人臉識別模型可以處理全球70億人口的人臉識別?而且可能公司只索取我們一張照片就可以做人臉識別使用。那又是決策邊界的概念，要如何設置一個可以處理區辨70億人口人臉的決策邊界的，那唯一的方法就是要讓大家排排站在一個高維的「超球」，人跟人之間至少要間隔多少度以上的夾角，但是同個人的不同樣貌則是位於很窄的局部區域中。這樣就有機會用少量圖片處理大量人口。我們借這概念來到野生動物識別，有的動物數量很多，有的動物數量極少，我們藉由超球的概念來區辨動物們。\n\n<img src='https://docs.google.com/uc?export=download&id=17OrPMDGXom4aVpWZRQm93RbhtEHxsVs1'/>\n","metadata":{}},{"cell_type":"code","source":"class ArcMarginProductLoss(Layer):\n    def __init__(self, scale=32.0, margin=0.50, easy_margin=False, name='ArcMarginProductLoss'):\n        super(ArcMarginProductLoss, self).__init__()\n        self._name=name\n        self.scale = scale\n        self.m = margin\n        self.easy_margin = easy_margin\n        self.cos_m = math.cos(margin)\n        self.sin_m = math.sin(margin)\n\n        # make the function cos(theta+m) monotonic decreasing while theta in [0°,180°]\n        self.th = math.cos(math.pi - margin)\n        self.mm = math.sin(math.pi - margin) * margin\n    \n        self.base_loss=CrossEntropyLoss(reduction='mean',axis=1)\n\n\n    def forward(self, output, target,**kwargs):\n        # cos(theta)\n        try:\n            cosine=output\n            # cos(theta + m)\n            sine = sqrt(1.0 - pow(cosine, 2))\n            phi = (cosine * self.cos_m - sine * self.sin_m).to(output.dtype)\n\n            if self.easy_margin:\n                phi = where(cosine > 0, phi, cosine)\n            else:\n                phi = where((cosine - self.th) > 0, phi, cosine - self.mm)\n\n            one_hot = zeros_like(cosine,requires_grad=True)\n            one_hot.scatter(1, target.view(-1, 1), 1)\n\n            output = (one_hot * phi) + ((1.0 - one_hot) * cosine)\n            output = output * self.scale\n        except Exception as e:\n            print(e)\n            PrintException()\n\n        loss = self.base_loss(output, target)\n        return loss","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:10.222471Z","iopub.execute_input":"2022-01-17T07:06:10.222927Z","iopub.status.idle":"2022-01-17T07:06:10.235229Z","shell.execute_reply.started":"2022-01-17T07:06:10.222884Z","shell.execute_reply":"2022-01-17T07:06:10.233594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nis_resume=False  #是否接續訓練\n\n#如果是接續訓練且存在歷史存檔，則載入之\nif is_resume:\n    if os.path.exists('./Models/revised3_net1.pth'):\n        net1.load_model('./Models/revised3_net1.pth')\n        net1.model.block7a.trainable=True\n        print('net1 loaded!!')\n    if os.path.exists('./Models/revised3_net2.pth'):\n        net2.load_model('./Models/revised3_net2.pth')\n        net2.model.block7a.trainable=True\n        print('net1 loaded!!')\n    if os.path.exists('./Models/revised3_vit.pth'):\n        vit.load_model('./Models/revised3_vit.pth')\n        print('vit loaded!!')","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:10.236739Z","iopub.execute_input":"2022-01-17T07:06:10.237567Z","iopub.status.idle":"2022-01-17T07:06:10.252236Z","shell.execute_reply.started":"2022-01-17T07:06:10.237495Z","shell.execute_reply":"2022-01-17T07:06:10.250830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net1.with_optimizer(optimizer=DiffGrad,lr=1e-3,betas=(0.9, 0.999),gradient_centralization='all')\\\n.with_loss(CrossEntropyLoss(auto_balance=True,label_smooth=True))\\\n.with_loss(FocalLoss,loss_weight=0.5)\\\n.with_metric(accuracy,name='accuracy')\\\n.with_metric(accuracy,topk=5,name='top5_accuracy',print_only=True)\\\n.with_regularizer('l2',reg_weight=5e-5)\\\n.adjust_learning_rate_scheduling(1000,unit='batch',new_value=5e-4)\\\n.with_accumulate_grads(4)\\\n.with_callbacks(MixupCallback(alpha= 1,loss_criterion=CrossEntropyLoss,loss_weight=0.5))\\\n.with_learning_rate_scheduler(StepLR(frequency=1000,unit='batch',gamma=0.5))\\\n.with_model_save_path('./Models/revised3_net1.pth')\\\n.with_automatic_mixed_precision_training()\n\n\nnet2.with_optimizer(optimizer=DiffGrad,lr=1e-3,betas=(0.9, 0.999),gradient_centralization='all')\\\n.with_loss(ArcMarginProductLoss(scale=32.0, margin=0.50, easy_margin=False)) \\\n.with_metric(accuracy,name='accuracy')\\\n.with_metric(accuracy,topk=5,name='top5_accuracy',print_only=True)\\\n.with_regularizer('l2',reg_weight=5e-5)\\\n.adjust_learning_rate_scheduling(1000,unit='batch',new_value=5e-4)\\\n.with_accumulate_grads(4)\\\n.with_grad_clipping(3)\\\n.with_learning_rate_scheduler(StepLR(frequency=1000,unit='batch',gamma=0.5))\\\n.with_model_save_path('./Models/revised3_net2.pth')\\\n.with_automatic_mixed_precision_training()\n\n\n#transformer一樣也是可以使用mixup的\nvit.with_optimizer(optimizer=Lamb,lr=5e-4,betas=(0.9, 0.999),gradient_centralization='all')\\\n.with_loss(CrossEntropyLoss(auto_balance=True,label_smooth=True))\\\n.with_loss(FocalLoss,loss_weight=0.5)\\\n.with_metric(accuracy,name='accuracy')\\\n.with_metric(accuracy,topk=5,name='top5_accuracy',print_only=True)\\\n.with_regularizer('l2',reg_weight=5e-5)\\\n.with_accumulate_grads(4)\\\n.with_grad_clipping(3)\\\n.with_callbacks(MixupCallback(alpha= 1,loss_criterion=CrossEntropyLoss,loss_weight=0.5))\\\n.with_learning_rate_scheduler(StepLR(frequency=1000,unit='batch',gamma=0.5))\\\n.with_model_save_path('./Models/revised3_vit.pth')\\\n.with_automatic_mixed_precision_training()\n\n\n#如果兩個模型都做mixup，批次設定到64，gpu會爆掉\nplan=TrainingPlan()\\\n    .add_training_item(net1,name='net1')\\\n    .add_training_item(net2,name='net2')\\\n    .add_training_item(vit,name='vit')\\\n    .with_data_loader(data_provider)\\\n    .with_batch_size(24)\\\n    .print_gradients_scheduling(200,unit='batch') \\\n    .print_progress_scheduling(10,unit='batch') \\\n    .display_loss_metric_curve_scheduling(200)\\\n    .save_model_scheduling(100,unit='batch')\n\n\nplan.only_steps(num_steps=10000, collect_data_inteval=5)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T07:06:10.254378Z","iopub.execute_input":"2022-01-17T07:06:10.255519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bad_images=['86994b3e-21bc-11ea-a13a-137349068a90.jpg',\n'882a533a-21bc-11ea-a13a-137349068a90.jpg',\n'88a28616-21bc-11ea-a13a-137349068a90.jpg',\n'88b99aae-21bc-11ea-a13a-137349068a90.jpg',\n'89362ed4-21bc-11ea-a13a-137349068a90.jpg',\n'8985bb98-21bc-11ea-a13a-137349068a90.jpg',\n'89e09b26-21bc-11ea-a13a-137349068a90.jpg',\n'8a804608-21bc-11ea-a13a-137349068a90.jpg',\n'8b8e02a6-21bc-11ea-a13a-137349068a90.jpg',\n'8b91394e-21bc-11ea-a13a-137349068a90.jpg',\n'8cc46b6a-21bc-11ea-a13a-137349068a90.jpg',\n'8d705d8a-21bc-11ea-a13a-137349068a90.jpg',\n'8e930668-21bc-11ea-a13a-137349068a90.jpg',\n'8e940310-21bc-11ea-a13a-137349068a90.jpg',\n'8ea6a768-21bc-11ea-a13a-137349068a90.jpg',\n'8fff9dc2-21bc-11ea-a13a-137349068a90.jpg',\n'9044a3b8-21bc-11ea-a13a-137349068a90.jpg',\n'920ee4c4-21bc-11ea-a13a-137349068a90.jpg',\n'950ed288-21bc-11ea-a13a-137349068a90.jpg',\n'9522d4fe-21bc-11ea-a13a-137349068a90.jpg',\n'96bacf06-21bc-11ea-a13a-137349068a90.jpg',\n'98552f5a-21bc-11ea-a13a-137349068a90.jpg',\n'98da656c-21bc-11ea-a13a-137349068a90.jpg',\n'9955d012-21bc-11ea-a13a-137349068a90.jpg']\n\n\n\ntest_imgs=glob.glob('../input/iwildcam-2020-fgvc7/test/*.jpg')\nprint(len(test_imgs))\ntest_imgs=[img_path for img_path in test_imgs if img_path.split('/')[-1] not in bad_images]\nprint(len(test_imgs))\n\n\nimg_ds=ImageDataset(test_imgs,symbol='image')\n#請注意，要設定object_type=ObjectType.image_path，這樣就可以確保輸出為stype=np.string_的numpy array\nimgpath_ds=ImageDataset(test_imgs,object_type=ObjectType.image_path,symbol='img_path')\n\n#與Iterator構成data provider\n#設定is_shuffle=False表示不隨機打亂\ntest_data_provider=DataProvider(traindata=Iterator(data=img_ds,label=imgpath_ds,is_shuffle=False))\n\n#保留有意義的數據清洗\ntest_data_provider.image_transform_funcs=[\n    Resize((224,224)),\n    CLAHE(),\n    Normalize(127.5,127.5)] #標準化\n\n\ndata,labels=test_data_provider.next()\nprint(data.shape)\nprint(labels)\nprint(labels[0].decode())\ntest_data_provider.preview_images()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f=open('../input/iwildcam-2020-fgvc7/sample_submission.csv','r',encoding='utf-8-sig')\nrows=f.readlines()\n#檢視一下大會給的提交範例\nprint(rows[:5])\nprint(rows[-5:])\n\nsubmission_dict=OrderedDict()\nfor row in rows[1:]:\n    cols=row.strip().split(',')\n    #排除大會公告壞掉的圖片\n    if  cols[0]+'.jpg' not in bad_images:\n        #塞入應有的KEY，value先放None\n        submission_dict[cols[0]]=None\nprint(len(submission_dict))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#清除gpu快取\nimport torch\nif is_gpu_available():\n    torch.cuda.synchronize()\n    torch.cuda.empty_cache()\n    gc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net1.eval()\nnet2.eval()\nvit.eval()\n#設定批次為64\ntest_data_provider.batch_size=64\n#這步驟是將generator歸零\ntest_data_provider.traindata.batch_sampler.reset()\n\n\nfor i,(img,img_path) in tqdm(enumerate(test_data_provider)):\n    out1=net1(img)\n    out2=net2(img)\n    out3=vit(img)\n    #基於輸出平均值\n    out4=np.argmax((out1+1.5*out2+out3)/3.5,axis=1)\n    #基於兩個模型評估的最大機率\n    #out3=np.argmax(np.where(out1>out2,out1,out2),axis=1)\n    for k in range(len(out4)):\n        _,image_id,_=split_path(img_path[k].decode())\n        if i==0 and k==0:\n            print(image_id)\n        #將預測的標籤透過label2category轉回大會的類別\n        category_id=label2category[out4[k]]\n        if image_id in submission_dict and image_id+'.jpg' not in bad_images:\n            submission_dict[image_id]=category_id\n        #當submission_dict的值不再有空值則停止\n        if None not in submission_dict.value_list:\n            break\n  ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_rows=['Id,Category\\n']\nfor k,v in submission_dict.items():\n    submission_rows.append('{0},{1}\\n'.format(k,v))\n#確認提交檔筆數\nprint(len(submission_rows))\n#寫入提交檔\nmake_dir_if_need('./results')\nwith open('./results/submission.csv','w',encoding='utf-8-sig') as f:\n    f.writelines(submission_rows)\n#再讀取一次確認何大會給的範例格式是否一致\nfr=open('./results/submission.csv','r',encoding='utf-8-sig')\nrows=fr.readlines()\nprint(rows[:3])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"api_token={\"username\":\"your_username\",\"key\":\"your_token\"} #請換成你自己的kaggle認證#請換成你自己的kaggle認證\nimport json\nimport zipfile\nimport os\n\nif not os.path.exists(\"/root/.kaggle\"):\n    os.makedirs(\"/root/.kaggle\")\n \nwith open('/root/.kaggle/kaggle.json', 'w') as file:\n    json.dump(api_token, file)\n!chmod 600 /root/.kaggle/kaggle.json\n \nif not os.path.exists(\"/kaggle\"):\n    os.makedirs(\"/kaggle\")\n!kaggle competitions submit -c iwildcam-2020-fgvc7 -f './results/submission.csv' -m 'transformer/CAM_EfficientNetB0 ensembles'","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}