{"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":"2021-06-27T05:25:41.505344Z","iopub.execute_input":"2021-06-27T05:25:41.506058Z","iopub.status.idle":"2021-06-27T05:25:41.519975Z","shell.execute_reply.started":"2021-06-27T05:25:41.505924Z","shell.execute_reply":"2021-06-27T05:25:41.518920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":"2021-06-27T05:25:41.615114Z","iopub.execute_input":"2021-06-27T05:25:41.615506Z","iopub.status.idle":"2021-06-27T05:25:41.623808Z","shell.execute_reply.started":"2021-06-27T05:25:41.615470Z","shell.execute_reply":"2021-06-27T05:25:41.622763Z"},"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 tridentx --upgrade\n\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":"2021-06-27T05:25:41.634929Z","iopub.execute_input":"2021-06-27T05:25:41.635235Z","iopub.status.idle":"2021-06-27T05:25:58.995219Z","shell.execute_reply.started":"2021-06-27T05:25:41.635206Z","shell.execute_reply":"2021-06-27T05:25:58.994068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import glob\n#透過glob所全部train資料夾中所有可用圖片\nimgs=glob.glob('../input/histopathologic-cancer-detection/train/*.tif')\nprint(len(imgs))\n\n#ImageDatset(imgs,symbol='image')\nf=open('../input/histopathologic-cancer-detection/train_labels.csv','r',encoding='utf-8-sig')\nrows=f.readlines()\nprint(rows[:3])\nimage_path=[]\nlabels=[]\ntest_image_path=[]\ntest_labels=[]\n\nrows=rows[1:] #拿掉第一筆標頭\nrandom.shuffle(rows)#隨機洗牌\nfor row in rows:\n    cols=row.strip().split(',') #移除\\n然後逗號分割\n    if random.random()<=0.3:\n        test_image_path.append('../input/histopathologic-cancer-detection/train/{0}.tif'.format(cols[0]))\n        test_labels.append(int(cols[1]))\n    else:\n        image_path.append('../input/histopathologic-cancer-detection/train/{0}.tif'.format(cols[0]))\n        labels.append(int(cols[1]))\nprint(len(image_path))\nprint(len(labels))\nprint(len(test_image_path))\nprint(len(test_labels))\n","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:25:58.996860Z","iopub.execute_input":"2021-06-27T05:25:58.997178Z","iopub.status.idle":"2021-06-27T05:26:05.141765Z","shell.execute_reply.started":"2021-06-27T05:25:58.997145Z","shell.execute_reply":"2021-06-27T05:26:05.140814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#資料集\nds1=ImageDataset(image_path,symbol='image')\nds2=LabelDataset(labels,symbol='label')\n\nds1_t=ImageDataset(test_image_path,symbol='image')\nds2_t=LabelDataset(test_labels,symbol='label')\n\n#與Iterator構成data provider\ndata_provider=DataProvider(traindata=Iterator(data=ds1,label=ds2),testdata=Iterator(data=ds1_t,label=ds2_t))\n\n#設定DataProvider的預處理流程\ndata_provider.image_transform_funcs=[Normalize(127.5,127.5)]\n\n#即可完成設定，可以透過next()來確認數據是否正常拋出，以及是否有正確產生輸出數據的signature\nimg_data,label_data=data_provider.next()\nprint(data_provider.signature)\nprint(img_data.shape)\nprint(label_data.shape)\n\ndata_provider.image_transform_funcs=[\n    RandomAdjustGamma(scale=(0.6,1.4)),#調整明暗\n    RandomAdjustHue(scale=(-0.5,0.5)),#調整色相\n    RandomAdjustSaturation(scale=(0.6,1.4)),#調整飽和度\n    SaltPepperNoise(0.05),#加入胡椒鹽噪音\n    RandomErasing(), #加入隨機擦去\n    Normalize(127.5,127.5)] #標準化\n\n#測試集數據不需要做數據增強\ndata_provider.testdata.data.image_transform_funcs=[\n    Normalize(127.5,127.5)] #標準化\n\nimg_data,label_data=data_provider.next()\nprint(img_data.shape)\nprint(label_data.shape)\ntest_img_data,test_label_data=data_provider.next_test()\nprint(test_img_data.shape)\nprint(test_label_data.shape)\ndata_provider.preview_images()","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:05.143660Z","iopub.execute_input":"2021-06-27T05:26:05.143966Z","iopub.status.idle":"2021-06-27T05:26:05.725103Z","shell.execute_reply.started":"2021-06-27T05:26:05.143939Z","shell.execute_reply":"2021-06-27T05:26:05.724147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from trident.models import efficientnet,densenet,resnet\nnet1=efficientnet.EfficientNetB0(pretrained=True,include_top=True,freeze_features=True,input_shape=(3,96,96),classes=2)\nnet1.model[-1].add_noise=True\nnet1.model[-1].noise_intensity=0.12\n","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:05.726924Z","iopub.execute_input":"2021-06-27T05:26:05.727340Z","iopub.status.idle":"2021-06-27T05:26:09.674276Z","shell.execute_reply.started":"2021-06-27T05:26:05.727300Z","shell.execute_reply":"2021-06-27T05:26:09.673510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"如果你仔細競賽規則，裡面有對圖像的標註作明確的說明，每張96x96的圖像所謂的陽性，是指在圖像中心點的32x32區域中是否有癌症細胞，在此區域外即使有癌症細胞也算是陰性，這個規則可以說是頗奇葩，而我在討論中看起來沒有太多人討論這個，只有少部分的人說它改成切出中心32x32區域跑結果很爛，其實不用做就知道會很爛。  \n- 現在預訓練模型基本上都是基於224*224，32x32這尺寸太小  \n- 直接使用32x32，周圍區域會被0填滿的行為所影響，若改其他padding又會讓預訓練模型失效  \n- 如果切32x32，很多看起來是白白的純黑的一片，因為它可能位於一個大的腫瘤內部，反而喪失了識別能力，它需要外圍圖像的上下文信息。  \n\n所以為了解決這問題，我自己設計了一個自定義層CustomCropFlatten，傳統卷積層切換至全連接層，多半是使用Flattened攤平，但是在這題中，我們就會把32x32跟外圍區域的信息混再一起。由於我希望鎖定32x32區域有無腫瘤，但我又要上下文信息，所以我首先檢查一下如果我用96*96，丟到預訓練模型到底圖片會縮多小，由於32是96的三分之一，所以我想要找到會把它縮成6x6的位置，這樣六個像素分別為  \\[padding區\\]-\\[周圍區\\]-\\[觀測區\\]-\\[觀測區\\]-\\[周圍區\\]-\\[padding區\\]。\n\n首先我假設padding效果應該不至於占掉左右總和1/3，所以上述的padding區是我要丟棄的，而周圍區才是我關心的上下文信息，而觀測區已經從32*32變成2*2，所以這個字定義層先把2*2區域挖出來攤平，接著把觀測區的上下左右四塊周圍區取出來，每塊各自取逐通道的極大值(取出特徵的極大值)，等於空間上這是四個點而非一大塊面積，這樣在重要性上會被抑制，但是特徵還是可以供後續分類器參考","metadata":{}},{"cell_type":"code","source":"class CustomCropFlatten(Layer):\n    \"\"\"\n  \n    \"\"\"\n    def __init__(self,name='CustomCropFlatten'):\n        super(CustomCropFlatten, self).__init__()\n        self.name = name\n\n    def forward(self, x, **kwargs):\n        #(None, 112, 6, 6)\n        #target_area=2x2\n        target=x[:,:,2:4,2:4]\n        B,C,H,W=int_shape(target)\n        outside1=reduce_max(x[:,:,1,1:5],axis=-1)\n        outside2=reduce_max(x[:,:,4,1:5],axis=-1)\n        outside3=reduce_max(x[:,:,1:5,1],axis=-1)\n        outside4=reduce_max(x[:,:,1:5,4],axis=-1)\n        outside=stack([outside1,outside2,outside3,outside4],axis=-1)\n        target=reshape(target,(B,C,-1))\n        return reshape(concate([target,outside],axis=-1),(B,-1))\n\nnet2=efficientnet.EfficientNetB0(pretrained=True,include_top=False,freeze_features=True,input_shape=(3,96,96),classes=2)\nnet2.model.remove_at(-1)\nnet2.model.remove_at(-1)\nnet2.model.remove_at(-1)\nnet2.model.remove_at(-1)\nnet2.model.remove_at(-1)\nnet2.model.remove_at(-1)\nnet2.model.add_module('custom',CustomCropFlatten())\nnet2.model.add_module('fc',Dense(2,activation=None))\nnet2.model.add_module('softmax',SoftMax(-1,add_noise=True,noise_intensity=0.12))\nnet2.summary()\n","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:09.675315Z","iopub.execute_input":"2021-06-27T05:26:09.675718Z","iopub.status.idle":"2021-06-27T05:26:10.610878Z","shell.execute_reply.started":"2021-06-27T05:26:09.675690Z","shell.execute_reply":"2021-06-27T05:26:10.610012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net3=resnet.ResNet50(pretrained=True,include_top=False,freeze_features=True,input_shape=(3,96,96),classes=2)\nnet3.model.remove_at(-1)\nnet3.model.add_module('custom',CustomCropFlatten())\nnet3.model.add_module('fc',Dense(2,activation=None))\nnet3.model.add_module('softmax',SoftMax(axis=-1,add_noise=True,noise_intensity=0.12))\nnet3.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:10.612345Z","iopub.execute_input":"2021-06-27T05:26:10.612759Z","iopub.status.idle":"2021-06-27T05:26:14.287732Z","shell.execute_reply.started":"2021-06-27T05:26:10.612719Z","shell.execute_reply":"2021-06-27T05:26:14.287000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import roc_curve, auc, roc_auc_score\n# make a prediction\n\ndef auc(output,target):\n    \n    output_np=to_numpy(exp(output))[:,1]\n    target_np=to_numpy(target)\n    return roc_auc_score(target_np, output_np)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.288658Z","iopub.execute_input":"2021-06-27T05:26:14.289013Z","iopub.status.idle":"2021-06-27T05:26:14.475695Z","shell.execute_reply.started":"2021-06-27T05:26:14.288977Z","shell.execute_reply":"2021-06-27T05:26:14.474769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def punishment(output,target):\n    mask=target==1\n    mask_neg=target==0\n    output=where(is_abnormal_number(output),zeros_like(output),output.copy())#如果出現異常值，則補零\n    masked_positive=exp(output)[:,1][mask]\n    masked_negative=exp(output)[:,1][mask_neg]\n    return 1-clip(masked_positive.mean()-masked_negative.mean(),0.0,1.0)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.477656Z","iopub.execute_input":"2021-06-27T05:26:14.477977Z","iopub.status.idle":"2021-06-27T05:26:14.485833Z","shell.execute_reply.started":"2021-06-27T05:26:14.477947Z","shell.execute_reply":"2021-06-27T05:26:14.484922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"在這邊我們的cross entropy加上了auto_balace的選項，這是我的api一個比較獨特的功能，它會自動計算個標籤的樣本分布(就像之前介紹過的label statistics)，然後根據特樣本數量差異，進行自動的平衡權重計算，自動讓所有類別的影響力均等。至於label smooth則是要解決答案非1即0的問題，隨機把1變成0.9~1這樣有助於緩解相似圖像卻必須被softmax分很開的限制。  \n\n此外我們還加入了F1ScoreLoss，從公式上看來它融合了準確率與召回率，其中的beta引數，當beta>1，則模型會更關注召回率，若是小於1則更關注準確率，所以我打算先不動這個數字讓他跑一下，到時看正確率與召回率數字再決定如何調整它。\n\n    f1 score = (1 + beta ** 2) * precision * recall / (beta ** 2 * precision + recall)\n","metadata":{}},{"cell_type":"code","source":"#challenger1 使用DiffGrad優化器、累積梯度\nnet1.with_optimizer(AdaBelief,lr=2e-3,gradient_centralization='all')\\\n.with_loss(CrossEntropyLoss(auto_balance=True, label_smooth=True))\\\n.with_loss(F1ScoreLoss,loss_weight=0.5)\\\n.with_loss(punishment,loss_weight=0.01)\\\n.with_metric(accuracy,ignore_index=0)\\\n.with_metric(recall,ignore_index=0)\\\n.with_metric(auc)\\\n.with_regularizer('l2',1e-3)\\\n.with_model_save_path('./Models/eff_1.pth')\\\n.with_callbacks(CosineLR(max_lr=2e-3, min_lr=1e-7,period=5000))\\\n.unfreeze_model_scheduling(300,unit='batch',module_name='block7a')\\\n\n\n#challenger1 使用DiffGrad優化器、累積梯度\nnet2.with_optimizer(AdaBelief,lr=2e-3,gradient_centralization='all')\\\n.with_loss(CrossEntropyLoss(auto_balance=True, label_smooth=True))\\\n.with_loss(F1ScoreLoss,loss_weight=0.5)\\\n.with_loss(punishment,loss_weight=0.01)\\\n.with_metric(accuracy,ignore_index=0)\\\n.with_metric(recall,ignore_index=0)\\\n.with_metric(auc)\\\n.with_regularizer('l2',1e-3)\\\n.with_model_save_path('./Models/eff_2.pth')\\\n.with_callbacks(CosineLR(max_lr=2e-3, min_lr=1e-7,period=5000))\\\n.unfreeze_model_scheduling(300,unit='batch',module_name='block5c')\n\n\n\n#challenger1 使用DiffGrad優化器、累積梯度\nnet3.with_optimizer(AdaBelief,lr=2e-3,gradient_centralization='all')\\\n.with_loss(CrossEntropyLoss(auto_balance=True, label_smooth=True))\\\n.with_loss(F1ScoreLoss,loss_weight=0.5)\\\n.with_loss(punishment,loss_weight=0.01)\\\n.with_metric(accuracy,ignore_index=0)\\\n.with_metric(recall,ignore_index=0)\\\n.with_metric(auc)\\\n.with_regularizer('l2',1e-3)\\\n.with_model_save_path('./Models/resnet_1.pth')\\\n.with_callbacks(CosineLR(max_lr=2e-3, min_lr=1e-7,period=5000))\\\n.unfreeze_model_scheduling(300,unit='batch',module_name='layer3.5')","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.487491Z","iopub.execute_input":"2021-06-27T05:26:14.487981Z","iopub.status.idle":"2021-06-27T05:26:14.636002Z","shell.execute_reply.started":"2021-06-27T05:26:14.487860Z","shell.execute_reply":"2021-06-27T05:26:14.635064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#使用outsample驗證\ndef draw_roc(training_context): #建模訓練階段都靠training_context通訊，傳遞所有需要的訊息\n    if training_context['steps']==10 or (training_context['steps']+1)%100==0:\n        model=training_context['current_model']\n        model.eval()  #切換為推論模式\n        traindata=training_context['train_data'] #取出測試數據\n        input_data=traindata['image'].copy()#複製一份避免與損失函數計算時干擾\n        target_data=traindata['label'].copy() #複製一份避免與損失函數計算時干擾\n        \n       \n        if not any_abnormal_number(input_data):#確認輸入數據沒有nan與inf\n            target_np=to_numpy(target_data)\n            \n            output=model(input_data)\n            output=where(is_abnormal_number(output),zeros_like(output),output.copy())#如果出現異常值，則補零\n            output_np=to_numpy(output) #推論階段softmax就會是一般softmax(訓練階段是log_softmax)，所以不必再做處理，而且所有noise, dropout都會消失\n            model.train()#計算完切回訓練模式\n            fpr, tpr,_=roc_curve(target_np, output_np[:,1])\n            if not any_abnormal_number(fpr) and not any_abnormal_number(tpr):\n                plt.figure(1)\n                plt.plot([0, 1], [0, 1], 'k--')\n                plt.plot(fpr, tpr, label='area = {:.3f}'.format(roc_auc_score(target_np, output_np[:,1])))\n                plt.xlabel('False positive rate')\n                plt.ylabel('True positive rate')\n                plt.title('ROC curve')\n                plt.legend(loc='best')\n                plt.show()\n        \nnet1.trigger_when('on_batch_end', frequency=1, action=draw_roc)\nnet2.trigger_when('on_batch_end', frequency=1, action=draw_roc)\nnet3.trigger_when('on_batch_end', frequency=1, action=draw_roc)","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.637322Z","iopub.execute_input":"2021-06-27T05:26:14.637588Z","iopub.status.idle":"2021-06-27T05:26:14.652544Z","shell.execute_reply.started":"2021-06-27T05:26:14.637564Z","shell.execute_reply":"2021-06-27T05:26:14.651756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plan=TrainingPlan()\\\n    .add_training_item(net1,name='net1')\\\n    .add_training_item(net2,name='net2')\\\n    .add_training_item(net3,name='net3')\\\n    .with_data_loader(data_provider)\\\n    .with_batch_size(256)\\\n    .repeat_epochs(1)\\\n    .out_sample_evaluation_scheduling(100)\\\n    .print_gradients_scheduling(100,unit='batch')\\\n    .print_progress_scheduling(10,unit='batch')\\\n    .display_loss_metric_curve_scheduling(200)\\\n    .save_model_scheduling(20,unit='batch')","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.653633Z","iopub.execute_input":"2021-06-27T05:26:14.654125Z","iopub.status.idle":"2021-06-27T05:26:14.671684Z","shell.execute_reply.started":"2021-06-27T05:26:14.654046Z","shell.execute_reply":"2021-06-27T05:26:14.670790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plan.start_now(collect_data_inteval=10)","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:26:14.672923Z","iopub.execute_input":"2021-06-27T05:26:14.673245Z","iopub.status.idle":"2021-06-27T05:26:34.411113Z","shell.execute_reply.started":"2021-06-27T05:26:14.673219Z","shell.execute_reply":"2021-06-27T05:26:34.410076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"然後我們示範一下如何產出要提交的內容，我們做兩個示範，第一種是我們根據效度指標看起來最高的模型為基礎，第二種是基於幾個模型的綜合評比","metadata":{}},{"cell_type":"code","source":"for dirname, _, filenames in os.walk('.'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n#取回你的模型的最簡單方法\nfrom IPython.display import FileLink\nFileLink('./Models/net3.pth')","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:01:20.071195Z","iopub.status.idle":"2021-06-27T05:01:20.071639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f=open('../input/histopathologic-cancer-detection/sample_submission.csv','r',encoding='utf-8-sig')\nrows=f.readlines()\nprint(rows[:5])","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:01:20.072702Z","iopub.status.idle":"2021-06-27T05:01:20.073150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nsummit_imgs=glob.glob('../input/histopathologic-cancer-detection/test/*.tif')\nbest_model=net3\n#這句超極重要，忘記了就一切白做了\nbest_model.eval()\nbest_model.class_names=[]\nbest_model.preprocess_flow=[Normalize(127.5,127.5)]\n\nresults=OrderedDict()\nsubmission_rows=[]\nsubmission_rows.append('id,label\\n')\n\nfor i in tqdm(range(len(summit_imgs))):\n    summit_key=summit_imgs[i].split('/')[-1].replace('.tif','')#從圖檔位置取出圖檔編號\n    infer_results=best_model.infer_single_image(summit_imgs[i])#冒號是指取所有批次軸，1是指取陽性的機率  \n    results[summit_key]=infer_results[1].item() #以key-value形式寫入\n    submission_rows.append('{0},{1}\\n'.format(summit_key,results[summit_key]))\n    if len(submission_rows)<=10:\n        print('submission_rows',submission_rows[-1],len(submission_rows))\n    \n   \n\nprint(len(results),len(submission_rows)-1)#比一下兩邊數字應該一樣\n\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":{"execution":{"iopub.status.busy":"2021-06-27T05:01:20.074065Z","iopub.status.idle":"2021-06-27T05:01:20.074501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\n#這句超極重要，忘記了就一切白做了\nnet1.eval()\nnet2.eval()\nnet3.eval()\nnet1.class_names=[]\nnet2.class_names=[]\nnet3.class_names=[]\nnet1.preprocess_flow=[Normalize(127.5,127.5)]\nnet2.preprocess_flow=[Normalize(127.5,127.5)]\nnet3.preprocess_flow=[Normalize(127.5,127.5)]\n\n\nresults=OrderedDict()\nsubmission_rows=[]\nsubmission_rows.append('id,label\\n')\n\nfor i in tqdm(range(len(summit_imgs))):\n    summit_key=summit_imgs[i].split('/')[-1].replace('.tif','')#從圖檔位置取出圖檔編號\n    infer_results=(net1.infer_single_image(summit_imgs[i])[1]+net2.infer_single_image(summit_imgs[i])[1]+net3.infer_single_image(summit_imgs[i])[1])/3.0#冒號是指取所有批次軸，1是指取陽性的機率  \n    results[summit_key]=infer_results.item() #以key-value形式寫入\n    submission_rows.append('{0},{1}\\n'.format(summit_key,results[summit_key]))\n    if len(submission_rows)<=10:\n        print('submission_rows',submission_rows[-1],len(submission_rows))\n\n\nprint(len(results),len(submission_rows)-1)#比一下兩邊數字應該一樣\n\nwith open('results/submission1.csv','w',encoding='utf-8-sig') as f:\n    f.writelines(submission_rows)\n\nfr=open('results/submission1.csv','r',encoding='utf-8-sig')\nrows=fr.readlines()\nprint(rows[:3])","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:01:20.075588Z","iopub.status.idle":"2021-06-27T05:01:20.076024Z"},"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 histopathologic-cancer-detection -f 'results/submission1.csv' -m 'Resnet50+/EfficientNetB0 ensembles custom layer for 32x32 handling'","metadata":{"execution":{"iopub.status.busy":"2021-06-27T05:01:20.076960Z","iopub.status.idle":"2021-06-27T05:01:20.077390Z"},"trusted":true},"execution_count":null,"outputs":[]}]}