Skip to content

Commit bf2c120

Browse files
authored
Add files via upload
1 parent 2862a24 commit bf2c120

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
{
2+
"nbformat": 4,
3+
"nbformat_minor": 0,
4+
"metadata": {
5+
"colab": {
6+
"name": "08.Optimizing_AUROC_Loss_with_DenseNet121_on_Melanoma.ipynb",
7+
"provenance": [],
8+
"collapsed_sections": []
9+
},
10+
"kernelspec": {
11+
"name": "python3",
12+
"display_name": "Python 3"
13+
},
14+
"language_info": {
15+
"name": "python"
16+
},
17+
"accelerator": "GPU"
18+
},
19+
"cells": [
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {
23+
"id": "ud6jh8GWr_qT"
24+
},
25+
"source": [
26+
"* Author: Zhuoning Yuan\n",
27+
"* Project: https://github.com/Optimization-AI/LibAUC\n",
28+
"\n"
29+
]
30+
},
31+
{
32+
"cell_type": "markdown",
33+
"metadata": {
34+
"id": "dcqqRTWMsFKY"
35+
},
36+
"source": [
37+
"# **Installing LibAUC**"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"metadata": {
43+
"id": "Ter36EFG2k2g"
44+
},
45+
"source": [
46+
"!pip install libauc"
47+
],
48+
"execution_count": null,
49+
"outputs": []
50+
},
51+
{
52+
"cell_type": "markdown",
53+
"metadata": {
54+
"id": "rZL_V9NutBio"
55+
},
56+
"source": [
57+
"# **Downloading Melanoma Dataset**\n",
58+
" \n",
59+
"* You can download dataset from here: https://www.kaggle.com/cdeotte/jpeg-melanoma-256x256. \n",
60+
"* In this tutorial, I am going to use JPEG Melanoma 256x256.\n",
61+
"\n"
62+
]
63+
},
64+
{
65+
"cell_type": "code",
66+
"metadata": {
67+
"id": "gXlAZOYRs_rf"
68+
},
69+
"source": [
70+
"!cp /content/drive/MyDrive/LibAUC/melanoma_256x256.zip /content/\n",
71+
"!unzip melanoma_224x224.zip -d /content/melanoma/"
72+
],
73+
"execution_count": null,
74+
"outputs": []
75+
},
76+
{
77+
"cell_type": "markdown",
78+
"metadata": {
79+
"id": "SWwE3v_R5Oku"
80+
},
81+
"source": [
82+
"\n",
83+
"# **Importing LibAUC**"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"metadata": {
89+
"id": "fDfVpPkp4o9O"
90+
},
91+
"source": [
92+
"from libauc.losses import AUCMLoss\n",
93+
"from libauc.optimizers import PESG\n",
94+
"from libauc.models import DenseNet121, DenseNet169\n",
95+
"from libauc.datasets import Melanoma\n",
96+
"from libauc.utils import auroc\n",
97+
"\n",
98+
"import torch \n",
99+
"from PIL import Image\n",
100+
"import numpy as np\n",
101+
"import torchvision.transforms as transforms\n",
102+
"from torch.utils.data import Dataset"
103+
],
104+
"execution_count": 1,
105+
"outputs": []
106+
},
107+
{
108+
"cell_type": "markdown",
109+
"metadata": {
110+
"id": "l2swK5Mo7Kca"
111+
},
112+
"source": [
113+
"# **Reproducibility**"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"metadata": {
119+
"id": "OiiT5oEp7J3C"
120+
},
121+
"source": [
122+
"def set_all_seeds(SEED):\n",
123+
" # REPRODUCIBILITY\n",
124+
" torch.manual_seed(SEED)\n",
125+
" np.random.seed(SEED)\n",
126+
" torch.backends.cudnn.deterministic = True\n",
127+
" torch.backends.cudnn.benchmark = False"
128+
],
129+
"execution_count": 2,
130+
"outputs": []
131+
},
132+
{
133+
"cell_type": "markdown",
134+
"metadata": {
135+
"id": "G-StcokOURv9"
136+
},
137+
"source": [
138+
"# **Data Augmentation**"
139+
]
140+
},
141+
{
142+
"cell_type": "code",
143+
"metadata": {
144+
"id": "sQlAJDeoUTtR"
145+
},
146+
"source": [
147+
"import albumentations as A\n",
148+
"from albumentations.pytorch.transforms import ToTensor\n",
149+
"\n",
150+
"def augmentations(image_size=256, is_test=True):\n",
151+
" # https://www.kaggle.com/vishnus/a-simple-pytorch-starter-code-single-fold-93\n",
152+
" imagenet_stats = {'mean':[0.485, 0.456, 0.406], 'std':[0.229, 0.224, 0.225]}\n",
153+
" train_tfms = A.Compose([\n",
154+
" A.Cutout(p=0.5),\n",
155+
" A.RandomRotate90(p=0.5),\n",
156+
" A.Flip(p=0.5),\n",
157+
" A.OneOf([\n",
158+
" A.RandomBrightnessContrast(brightness_limit=0.2,\n",
159+
" contrast_limit=0.2,\n",
160+
" ),\n",
161+
" A.HueSaturationValue(\n",
162+
" hue_shift_limit=20,\n",
163+
" sat_shift_limit=50,\n",
164+
" val_shift_limit=50)\n",
165+
" ], p=0.5),\n",
166+
" A.OneOf([\n",
167+
" A.IAAAdditiveGaussianNoise(),\n",
168+
" A.GaussNoise(),\n",
169+
" ], p=0.5),\n",
170+
" A.OneOf([\n",
171+
" A.MotionBlur(p=0.2),\n",
172+
" A.MedianBlur(blur_limit=3, p=0.1),\n",
173+
" A.Blur(blur_limit=3, p=0.1),\n",
174+
" ], p=0.5),\n",
175+
" A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.5),\n",
176+
" A.OneOf([\n",
177+
" A.OpticalDistortion(p=0.3),\n",
178+
" A.GridDistortion(p=0.1),\n",
179+
" A.IAAPiecewiseAffine(p=0.3),\n",
180+
" ], p=0.5), \n",
181+
" ToTensor(normalize=imagenet_stats)\n",
182+
" ])\n",
183+
" \n",
184+
" test_tfms = A.Compose([ToTensor(normalize=imagenet_stats)])\n",
185+
" if is_test:\n",
186+
" return test_tfms\n",
187+
" else:\n",
188+
" return train_tfms"
189+
],
190+
"execution_count": 3,
191+
"outputs": []
192+
},
193+
{
194+
"cell_type": "markdown",
195+
"metadata": {
196+
"id": "fP4adNO97YBV"
197+
},
198+
"source": [
199+
"# **Optimizing AUCM Loss**\n",
200+
"* Installation of `albumentations` is required!"
201+
]
202+
},
203+
{
204+
"cell_type": "code",
205+
"metadata": {
206+
"colab": {
207+
"base_uri": "https://localhost:8080/",
208+
"height": 519
209+
},
210+
"id": "Xx7j0UYe6V0J",
211+
"outputId": "3bce73dc-ea0a-4639-b3ba-888b276a7d97"
212+
},
213+
"source": [
214+
"# dataset\n",
215+
"trainSet = Melanoma(root='./melanoma/', is_test=False, test_size=0.2, transforms=augmentations)\n",
216+
"testSet = Melanoma(root='./melanoma/', is_test=True, test_size=0.2, transforms=augmentations)\n",
217+
"\n",
218+
"# paramaters\n",
219+
"SEED = 123\n",
220+
"BATCH_SIZE = 64\n",
221+
"lr = 0.1 \n",
222+
"gamma = 500\n",
223+
"imratio = trainSet.imratio\n",
224+
"weight_decay = 1e-5\n",
225+
"margin = 1.0\n",
226+
"\n",
227+
"# model\n",
228+
"set_all_seeds(SEED)\n",
229+
"model = DenseNet121(pretrained=True, last_activation=None, activations='relu', num_classes=1)\n",
230+
"model = model.cuda()\n",
231+
"\n",
232+
"trainloader = torch.utils.data.DataLoader(trainSet, batch_size=BATCH_SIZE, num_workers=2, shuffle=True)\n",
233+
"testloader = torch.utils.data.DataLoader(testSet, batch_size=BATCH_SIZE, num_workers=2, shuffle=False)\n",
234+
"\n",
235+
"# load your own pretrained model here\n",
236+
"# PATH = 'ce_pretrained_model.pth' \n",
237+
"# state_dict = torch.load(PATH)\n",
238+
"# state_dict.pop('classifier.weight', None)\n",
239+
"# state_dict.pop('classifier.bias', None) \n",
240+
"# model.load_state_dict(state_dict, strict=False)\n",
241+
"\n",
242+
"# define loss & optimizer\n",
243+
"Loss = AUCMLoss(imratio=imratio)\n",
244+
"optimizer = PESG(model, \n",
245+
" a=Loss.a, \n",
246+
" b=Loss.b, \n",
247+
" alpha=Loss.alpha, \n",
248+
" lr=lr, \n",
249+
" gamma=gamma, \n",
250+
" margin=margin, \n",
251+
" weight_decay=weight_decay)\n",
252+
"\n",
253+
"total_epochs = 16\n",
254+
"best_val_auc = 0\n",
255+
"for epoch in range(total_epochs):\n",
256+
"\n",
257+
" # reset stages \n",
258+
" if epoch== int(total_epochs*0.5) or epoch== int(total_epochs*0.75):\n",
259+
" optimizer.update_regularizer(decay_factor=10) \n",
260+
"\n",
261+
" # training \n",
262+
" for idx, data in enumerate(trainloader):\n",
263+
" train_data, train_labels = data\n",
264+
" train_data, train_labels = train_data.cuda(), train_labels.cuda()\n",
265+
" y_pred = model(train_data)\n",
266+
" y_pred = torch.sigmoid(y_pred)\n",
267+
" loss = Loss(y_pred, train_labels)\n",
268+
" optimizer.zero_grad()\n",
269+
" loss.backward()\n",
270+
" optimizer.step()\n",
271+
"\n",
272+
" # validation\n",
273+
" model.eval()\n",
274+
" with torch.no_grad(): \n",
275+
" test_pred = []\n",
276+
" test_true = [] \n",
277+
" for jdx, data in enumerate(testloader):\n",
278+
" test_data, test_label = data\n",
279+
" test_data = test_data.cuda()\n",
280+
" y_pred = model(test_data)\n",
281+
" y_pred = torch.sigmoid(y_pred)\n",
282+
" test_pred.append(y_pred.cpu().detach().numpy())\n",
283+
" test_true.append(test_label.numpy())\n",
284+
" \n",
285+
" test_true = np.concatenate(test_true)\n",
286+
" test_pred = np.concatenate(test_pred)\n",
287+
" val_auc = auroc(test_true, test_pred) \n",
288+
" model.train()\n",
289+
"\n",
290+
" if best_val_auc < val_auc:\n",
291+
" best_val_auc = val_auc\n",
292+
" \n",
293+
" print ('Epoch=%s, Loss=%.4f, Val_AUC=%.4f, lr=%.4f'%(epoch, loss, val_auc, optimizer.lr))\n",
294+
"\n",
295+
"print ('Best Val_AUC is %.4f'%best_val_auc)"
296+
],
297+
"execution_count": 7,
298+
"outputs": [
299+
{
300+
"output_type": "stream",
301+
"name": "stdout",
302+
"text": [
303+
"test set split is 0.2\n",
304+
"Found 26134 image in total, 464 postive images, 25670 negative images.\n",
305+
"test set split is 0.2\n",
306+
"Found 6558 image in total, 117 postive images, 6441 negative images.\n",
307+
"Epoch=0, Loss=0.0238, Val_AUC=0.8411, lr=0.1000\n",
308+
"Epoch=1, Loss=0.0245, Val_AUC=0.8697, lr=0.1000\n",
309+
"Epoch=2, Loss=0.0213, Val_AUC=0.8460, lr=0.1000\n",
310+
"Epoch=3, Loss=-0.0234, Val_AUC=0.8783, lr=0.1000\n"
311+
]
312+
},
313+
]
314+
}
315+
]
316+
}

0 commit comments

Comments
 (0)