├── DN4_2019_Version
├── DN4_Test_5way1shot.py
├── DN4_Test_5way5shot.py
├── DN4_Train_5way1shot.py
├── DN4_Train_5way1shot_DA.py
├── DN4_Train_5way1shot_Resnet.py
├── DN4_Train_5way5shot.py
├── DN4_Train_5way5shot_DA.py
├── DN4_Train_5way5shot_Resnet.py
├── LICENSE
├── README.md
├── dataset
│ ├── CubBird_prepare_csv.py
│ ├── CubBirds
│ │ ├── test.csv
│ │ ├── train.csv
│ │ └── val.csv
│ ├── StanforCar_prepare_csv.py
│ ├── StanfordCars
│ │ ├── test.csv
│ │ ├── train.csv
│ │ └── val.csv
│ ├── StanfordDog_prepare_csv.py
│ ├── StanfordDogs
│ │ ├── test.csv
│ │ ├── train.csv
│ │ └── val.csv
│ ├── datasets_csv.py
│ └── miniImageNet
│ │ ├── test.csv
│ │ ├── train.csv
│ │ └── val.csv
├── imgs
│ ├── Flowchart.bmp
│ ├── Results_finegrained.bmp
│ └── Results_miniImageNet2.bmp
├── models
│ └── network.py
└── results
│ ├── DN4_miniImageNet_Conv64F_5Way_1Shot_K3
│ ├── Test_resutls.txt
│ ├── model_best.pth.tar
│ └── opt_resutls.txt
│ ├── DN4_miniImageNet_Conv64F_5Way_5Shot_K3
│ ├── Test_resutls.txt
│ ├── model_best.pth.tar
│ └── opt_resutls.txt
│ ├── DN4_miniImageNet_ResNet256F_5Way_1Shot_K3
│ ├── Test_resutls.txt
│ └── opt_resutls.txt
│ └── DN4_miniImageNet_ResNet256F_5Way_5Shot_K3
│ ├── Test_resutls.txt
│ └── opt_resutls.txt
├── LICENSE
├── README.md
├── Test_DN4.py
├── Train_DN4.py
├── dataset
├── CubBirds
│ ├── test.csv
│ ├── train.csv
│ └── val.csv
├── Prepare_csv_CubBird.py
├── Prepare_csv_StanfordCar.py
├── Prepare_csv_StanfordDog.py
├── StanfordCars
│ ├── test.csv
│ ├── train.csv
│ └── val.csv
├── StanfordDogs
│ ├── test.csv
│ ├── train.csv
│ └── val.csv
├── general_dataloader.py
└── miniImageNet
│ ├── test.csv
│ ├── train.csv
│ └── val.csv
├── models
├── backbone.py
├── classifier.py
└── network.py
├── results
├── SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot
│ ├── Loss.png
│ ├── Test_results.txt
│ ├── opt_results.txt
│ ├── test_loss.txt
│ ├── train_loss.txt
│ └── val_loss.txt
├── SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot
│ ├── Loss.png
│ ├── Test_results.txt
│ ├── opt_results.txt
│ ├── test_loss.txt
│ ├── train_loss.txt
│ └── val_loss.txt
├── SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot
│ ├── Loss.png
│ ├── Test_results.txt
│ ├── Test_results_New.txt
│ ├── model_best.pth.tar
│ ├── opt_results.txt
│ ├── test_loss.txt
│ ├── train_loss.txt
│ └── val_loss.txt
├── SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot
│ ├── Loss.png
│ ├── Test_results.txt
│ ├── model_best.pth.tar
│ ├── opt_results.txt
│ ├── test_loss.txt
│ ├── train_loss.txt
│ └── val_loss.txt
└── test
└── utils.py
/DN4_2019_Version/DN4_Test_5way1shot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Author: Wenbin Li (liwenbin.nju@gmail.com)
6 | Date: April 9, 2019
7 | Version: V0
8 |
9 | Citation:
10 | @inproceedings{li2019DN4,
11 | title={Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning},
12 | author={Li, Wenbin and Wang, Lei and Xu, Jinglin and Huo, Jing and Gao Yang and Luo, Jiebo},
13 | booktitle={CVPR},
14 | year={2019}
15 | }
16 | """
17 |
18 |
19 | from __future__ import print_function
20 | import argparse
21 | import os
22 | import random
23 | import shutil
24 | import numpy as np
25 | import torch
26 | import torch.nn as nn
27 | import torch.nn.parallel
28 | import torch.backends.cudnn as cudnn
29 | import torch.optim as optim
30 | import torch.utils.data
31 | import torchvision.datasets as dset
32 | import torchvision.transforms as transforms
33 | import torchvision.utils as vutils
34 | from torch.autograd import grad
35 | import time
36 | from torch import autograd
37 | from PIL import ImageFile
38 | import scipy as sp
39 | import scipy.stats
40 | import pdb
41 |
42 |
43 | # ============================ Data & Networks =====================================
44 | from dataset.datasets_csv import Imagefolder_csv
45 | import models.network as DN4Net
46 | # ==================================================================================
47 |
48 |
49 | ImageFile.LOAD_TRUNCATED_IMAGES = True
50 | os.environ['CUDA_DEVICE_ORDER']='PCI_BUS_ID'
51 | os.environ['CUDA_VISIBLE_DEVICES']='0'
52 |
53 |
54 | # Load the pre-trained model
55 | model_trained = './results/DN4_miniImageNet_Conv64F_5Way_1Shot_K3/model_best.pth.tar'
56 |
57 |
58 | parser = argparse.ArgumentParser()
59 | parser.add_argument('--dataset_dir', default='/Datasets/miniImageNet--ravi', help='/miniImageNet')
60 | parser.add_argument('--data_name', default='miniImageNet', help='miniImageNet|StanfordDog|StanfordCar|CubBird')
61 | parser.add_argument('--mode', default='test', help='train|val|test')
62 | parser.add_argument('--outf', default='./results/DN4')
63 | parser.add_argument('--resume', default=model_trained, type=str, help='path to the lastest checkpoint (default: none)')
64 | parser.add_argument('--basemodel', default='Conv64F', help='Conv64F|ResNet256F')
65 | parser.add_argument('--workers', type=int, default=8)
66 | # Few-shot parameters #
67 | parser.add_argument('--imageSize', type=int, default=84)
68 | parser.add_argument('--episodeSize', type=int, default=1, help='the mini-batch size of training')
69 | parser.add_argument('--testepisodeSize', type=int, default=1, help='one episode is taken as a mini-batch')
70 | parser.add_argument('--epochs', type=int, default=30, help='the total number of training epoch')
71 | parser.add_argument('--episode_train_num', type=int, default=10000, help='the total number of training episodes')
72 | parser.add_argument('--episode_val_num', type=int, default=1000, help='the total number of evaluation episodes')
73 | parser.add_argument('--episode_test_num', type=int, default=600, help='the total number of testing episodes')
74 | parser.add_argument('--way_num', type=int, default=5, help='the number of way/class')
75 | parser.add_argument('--shot_num', type=int, default=1, help='the number of shot')
76 | parser.add_argument('--query_num', type=int, default=15, help='the number of queries')
77 | parser.add_argument('--neighbor_k', type=int, default=3, help='the number of k-nearest neighbors')
78 | parser.add_argument('--lr', type=float, default=0.005, help='learning rate, default=0.005')
79 | parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
80 | parser.add_argument('--cuda', action='store_true', default=True, help='enables cuda')
81 | parser.add_argument('--ngpu', type=int, default=1, help='the number of gpus')
82 | parser.add_argument('--nc', type=int, default=3, help='input image channels')
83 | parser.add_argument('--clamp_lower', type=float, default=-0.01)
84 | parser.add_argument('--clamp_upper', type=float, default=0.01)
85 | parser.add_argument('--print_freq', '-p', default=100, type=int, metavar='N', help='print frequency (default: 100)')
86 | opt = parser.parse_args()
87 | opt.cuda = True
88 | cudnn.benchmark = True
89 |
90 |
91 |
92 | # ======================================= Define functions =============================================
93 | def validate(val_loader, model, criterion, epoch_index, F_txt):
94 | batch_time = AverageMeter()
95 | losses = AverageMeter()
96 | top1 = AverageMeter()
97 |
98 |
99 | # switch to evaluate mode
100 | model.eval()
101 | accuracies = []
102 |
103 |
104 | end = time.time()
105 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(val_loader):
106 |
107 | # Convert query and support images
108 | query_images = torch.cat(query_images, 0)
109 | input_var1 = query_images.cuda()
110 |
111 |
112 | input_var2 = []
113 | for i in range(len(support_images)):
114 | temp_support = support_images[i]
115 | temp_support = torch.cat(temp_support, 0)
116 | temp_support = temp_support.cuda()
117 | input_var2.append(temp_support)
118 |
119 |
120 | # Deal with the targets
121 | target = torch.cat(query_targets, 0)
122 | target = target.cuda()
123 |
124 | # Calculate the output
125 | output = model(input_var1, input_var2)
126 | loss = criterion(output, target)
127 |
128 |
129 | # measure accuracy and record loss
130 | prec1, _ = accuracy(output, target, topk=(1, 3))
131 | losses.update(loss.item(), query_images.size(0))
132 | top1.update(prec1[0], query_images.size(0))
133 | accuracies.append(prec1)
134 |
135 |
136 | # measure elapsed time
137 | batch_time.update(time.time() - end)
138 | end = time.time()
139 |
140 |
141 | #============== print the intermediate results ==============#
142 | if episode_index % opt.print_freq == 0 and episode_index != 0:
143 |
144 | print('Test-({0}): [{1}/{2}]\t'
145 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
146 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
147 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
148 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1))
149 |
150 | print('Test-({0}): [{1}/{2}]\t'
151 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
152 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
153 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
154 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1), file=F_txt)
155 |
156 |
157 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1))
158 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1), file=F_txt)
159 |
160 | return top1.avg, accuracies
161 |
162 |
163 | class AverageMeter(object):
164 | """Computes and stores the average and current value"""
165 | def __init__(self):
166 | self.reset()
167 |
168 | def reset(self):
169 | self.val = 0
170 | self.avg = 0
171 | self.sum = 0
172 | self.count = 0
173 |
174 | def update(self, val, n=1):
175 | self.val = val
176 | self.sum += val * n
177 | self.count += n
178 | self.avg = self.sum / self.count
179 |
180 |
181 |
182 | def accuracy(output, target, topk=(1,)):
183 | """Computes the precision@k for the specified values of k"""
184 | with torch.no_grad():
185 | maxk = max(topk)
186 | batch_size = target.size(0)
187 |
188 | _, pred = output.topk(maxk, 1, True, True)
189 | pred = pred.t()
190 | correct = pred.eq(target.view(1, -1).expand_as(pred))
191 |
192 | res = []
193 | for k in topk:
194 | correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
195 | res.append(correct_k.mul_(100.0 / batch_size))
196 | return res
197 |
198 |
199 | def mean_confidence_interval(data, confidence=0.95):
200 | a = [1.0*np.array(data[i].cpu()) for i in range(len(data))]
201 | n = len(a)
202 | m, se = np.mean(a), scipy.stats.sem(a)
203 | h = se * sp.stats.t._ppf((1+confidence)/2., n-1)
204 | return m,h
205 |
206 |
207 |
208 | # ======================================== Settings of path ============================================
209 | # saving path
210 | opt.outf = opt.outf+'_'+opt.data_name+'_'+str(opt.basemodel)+'_'+str(opt.way_num)+'Way_'+str(opt.shot_num)+'Shot'+'_K'+str(opt.neighbor_k)
211 |
212 | if not os.path.exists(opt.outf):
213 | os.makedirs(opt.outf)
214 |
215 | if torch.cuda.is_available() and not opt.cuda:
216 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
217 |
218 | # save the opt and results to a txt file
219 | txt_save_path = os.path.join(opt.outf, 'Test_resutls.txt')
220 | F_txt = open(txt_save_path, 'a+')
221 | print(opt)
222 | print(opt, file=F_txt)
223 |
224 |
225 |
226 | # ========================================== Model Config ===============================================
227 | ngpu = int(opt.ngpu)
228 | global best_prec1, epoch_index
229 | best_prec1 = 0
230 | epoch_index = 0
231 |
232 | model = DN4Net.define_DN4Net(which_model=opt.basemodel, num_classes=opt.way_num, neighbor_k=opt.neighbor_k, norm='batch',
233 | init_type='normal', use_gpu=opt.cuda)
234 |
235 | # define loss function (criterion) and optimizer
236 | criterion = nn.CrossEntropyLoss().cuda()
237 | optimizer = optim.Adam(model.parameters(), lr=opt.lr, betas=(opt.beta1, 0.9))
238 |
239 |
240 | # optionally resume from a checkpoint
241 | if opt.resume:
242 | if os.path.isfile(opt.resume):
243 | print("=> loading checkpoint '{}'".format(opt.resume))
244 | checkpoint = torch.load(opt.resume)
245 | epoch_index = checkpoint['epoch_index']
246 | best_prec1 = checkpoint['best_prec1']
247 | model.load_state_dict(checkpoint['state_dict'])
248 | optimizer.load_state_dict(checkpoint['optimizer'])
249 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']))
250 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']), file=F_txt)
251 | else:
252 | print("=> no checkpoint found at '{}'".format(opt.resume))
253 | print("=> no checkpoint found at '{}'".format(opt.resume), file=F_txt)
254 |
255 | if opt.ngpu > 1:
256 | model = nn.DataParallel(model, range(opt.ngpu))
257 |
258 | # print the architecture of the network
259 | print(model)
260 | print(model, file=F_txt)
261 |
262 |
263 |
264 |
265 | # ============================================ Testing phase ========================================
266 | print('\n............Start testing............')
267 | start_time = time.time()
268 | repeat_num = 5 # repeat running the testing code several times
269 |
270 |
271 | total_accuracy = 0.0
272 | total_h = np.zeros(repeat_num)
273 | total_accuracy_vector = []
274 | for r in range(repeat_num):
275 | print('===================================== Round %d =====================================' %r)
276 | print('===================================== Round %d =====================================' %r, file=F_txt)
277 |
278 | # ======================================= Folder of Datasets =======================================
279 |
280 | # image transform & normalization
281 | ImgTransform = transforms.Compose([
282 | transforms.Resize((opt.imageSize, opt.imageSize)),
283 | transforms.ToTensor(),
284 | transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
285 | ])
286 |
287 | testset = Imagefolder_csv(
288 | data_dir=opt.dataset_dir, mode=opt.mode, image_size=opt.imageSize, transform=ImgTransform,
289 | episode_num=opt.episode_test_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
290 | )
291 | print('Testset: %d-------------%d' %(len(testset), r), file=F_txt)
292 |
293 |
294 |
295 | # ========================================== Load Datasets =========================================
296 | test_loader = torch.utils.data.DataLoader(
297 | testset, batch_size=opt.testepisodeSize, shuffle=True,
298 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
299 | )
300 |
301 |
302 | # =========================================== Evaluation ==========================================
303 | prec1, accuracies = validate(test_loader, model, criterion, epoch_index, F_txt)
304 |
305 |
306 | test_accuracy, h = mean_confidence_interval(accuracies)
307 | print("Test accuracy", test_accuracy, "h", h[0])
308 | print("Test accuracy", test_accuracy, "h", h[0], file=F_txt)
309 | total_accuracy += test_accuracy
310 | total_accuracy_vector.extend(accuracies)
311 | total_h[r] = h
312 |
313 |
314 | aver_accuracy, _ = mean_confidence_interval(total_accuracy_vector)
315 | print("Aver_accuracy:", aver_accuracy, "Aver_h", total_h.mean())
316 | print("Aver_accuracy:", aver_accuracy, "Aver_h", total_h.mean(), file=F_txt)
317 | F_txt.close()
318 |
319 | # ============================================== Testing End ==========================================
320 |
--------------------------------------------------------------------------------
/DN4_2019_Version/DN4_Test_5way5shot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Author: Wenbin Li (liwenbin.nju@gmail.com)
6 | Date: April 9, 2019
7 | Version: V0
8 |
9 | Citation:
10 | @inproceedings{li2019DN4,
11 | title={Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning},
12 | author={Li, Wenbin and Wang, Lei and Xu, Jinglin and Huo, Jing and Gao Yang and Luo, Jiebo},
13 | booktitle={CVPR},
14 | year={2019}
15 | }
16 | """
17 |
18 |
19 | from __future__ import print_function
20 | import argparse
21 | import os
22 | import random
23 | import shutil
24 | import numpy as np
25 | import torch
26 | import torch.nn as nn
27 | import torch.nn.parallel
28 | import torch.backends.cudnn as cudnn
29 | import torch.optim as optim
30 | import torch.utils.data
31 | import torchvision.datasets as dset
32 | import torchvision.transforms as transforms
33 | import torchvision.utils as vutils
34 | from torch.autograd import grad
35 | import time
36 | from torch import autograd
37 | from PIL import ImageFile
38 | import scipy as sp
39 | import scipy.stats
40 | import pdb
41 |
42 |
43 | # ============================ Data & Networks =====================================
44 | from dataset.datasets_csv import Imagefolder_csv
45 | import models.network as DN4Net
46 | # ==================================================================================
47 |
48 |
49 | ImageFile.LOAD_TRUNCATED_IMAGES = True
50 | os.environ['CUDA_DEVICE_ORDER']='PCI_BUS_ID'
51 | os.environ['CUDA_VISIBLE_DEVICES']='0'
52 |
53 |
54 | # Load the pre-trained model
55 | model_trained = './results/DN4_miniImageNet_Conv64F_5Way_5Shot_K3/model_best.pth.tar'
56 |
57 |
58 | parser = argparse.ArgumentParser()
59 | parser.add_argument('--dataset_dir', default='/Datasets/miniImageNet--ravi', help='/miniImageNet')
60 | parser.add_argument('--data_name', default='miniImageNet', help='miniImageNet|StanfordDog|StanfordCar|CubBird')
61 | parser.add_argument('--mode', default='test', help='train|val|test')
62 | parser.add_argument('--outf', default='./results/DN4')
63 | parser.add_argument('--resume', default=model_trained, type=str, help='path to the lastest checkpoint (default: none)')
64 | parser.add_argument('--basemodel', default='Conv64F', help='Conv64F|ResNet256F')
65 | parser.add_argument('--workers', type=int, default=8)
66 | # Few-shot parameters #
67 | parser.add_argument('--imageSize', type=int, default=84)
68 | parser.add_argument('--episodeSize', type=int, default=1, help='the mini-batch size of training')
69 | parser.add_argument('--testepisodeSize', type=int, default=1, help='one episode is taken as a mini-batch')
70 | parser.add_argument('--epochs', type=int, default=30, help='the total number of training epoch')
71 | parser.add_argument('--episode_train_num', type=int, default=10000, help='the total number of training episodes')
72 | parser.add_argument('--episode_val_num', type=int, default=1000, help='the total number of evaluation episodes')
73 | parser.add_argument('--episode_test_num', type=int, default=600, help='the total number of testing episodes')
74 | parser.add_argument('--way_num', type=int, default=5, help='the number of way/class')
75 | parser.add_argument('--shot_num', type=int, default=5, help='the number of shot')
76 | parser.add_argument('--query_num', type=int, default=15, help='the number of queries')
77 | parser.add_argument('--neighbor_k', type=int, default=3, help='the number of k-nearest neighbors')
78 | parser.add_argument('--lr', type=float, default=0.005, help='learning rate, default=0.005')
79 | parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
80 | parser.add_argument('--cuda', action='store_true', default=True, help='enables cuda')
81 | parser.add_argument('--ngpu', type=int, default=1, help='the number of gpus')
82 | parser.add_argument('--nc', type=int, default=3, help='input image channels')
83 | parser.add_argument('--clamp_lower', type=float, default=-0.01)
84 | parser.add_argument('--clamp_upper', type=float, default=0.01)
85 | parser.add_argument('--print_freq', '-p', default=100, type=int, metavar='N', help='print frequency (default: 100)')
86 | opt = parser.parse_args()
87 | opt.cuda = True
88 | cudnn.benchmark = True
89 |
90 |
91 |
92 | # ======================================= Define functions =============================================
93 | def validate(val_loader, model, criterion, epoch_index, F_txt):
94 | batch_time = AverageMeter()
95 | losses = AverageMeter()
96 | top1 = AverageMeter()
97 |
98 |
99 | # switch to evaluate mode
100 | model.eval()
101 | accuracies = []
102 |
103 |
104 | end = time.time()
105 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(val_loader):
106 |
107 | # Convert query and support images
108 | query_images = torch.cat(query_images, 0)
109 | input_var1 = query_images.cuda()
110 |
111 |
112 | input_var2 = []
113 | for i in range(len(support_images)):
114 | temp_support = support_images[i]
115 | temp_support = torch.cat(temp_support, 0)
116 | temp_support = temp_support.cuda()
117 | input_var2.append(temp_support)
118 |
119 |
120 | # Deal with the target
121 | target = torch.cat(query_targets, 0)
122 | target = target.cuda()
123 |
124 | # Calculate the output
125 | output = model(input_var1, input_var2)
126 | loss = criterion(output, target)
127 |
128 |
129 | # measure accuracy and record loss
130 | prec1, _ = accuracy(output, target, topk=(1, 3))
131 | losses.update(loss.item(), query_images.size(0))
132 | top1.update(prec1[0], query_images.size(0))
133 | accuracies.append(prec1)
134 |
135 |
136 | # measure elapsed time
137 | batch_time.update(time.time() - end)
138 | end = time.time()
139 |
140 |
141 | #============== print the intermediate results ==============#
142 | if episode_index % opt.print_freq == 0 and episode_index != 0:
143 |
144 | print('Test-({0}): [{1}/{2}]\t'
145 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
146 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
147 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
148 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1))
149 |
150 | print('Test-({0}): [{1}/{2}]\t'
151 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
152 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
153 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
154 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1), file=F_txt)
155 |
156 |
157 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1))
158 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1), file=F_txt)
159 |
160 | return top1.avg, accuracies
161 |
162 |
163 | class AverageMeter(object):
164 | """Computes and stores the average and current value"""
165 | def __init__(self):
166 | self.reset()
167 |
168 | def reset(self):
169 | self.val = 0
170 | self.avg = 0
171 | self.sum = 0
172 | self.count = 0
173 |
174 | def update(self, val, n=1):
175 | self.val = val
176 | self.sum += val * n
177 | self.count += n
178 | self.avg = self.sum / self.count
179 |
180 |
181 |
182 | def accuracy(output, target, topk=(1,)):
183 | """Computes the precision@k for the specified values of k"""
184 | with torch.no_grad():
185 | maxk = max(topk)
186 | batch_size = target.size(0)
187 |
188 | _, pred = output.topk(maxk, 1, True, True)
189 | pred = pred.t()
190 | correct = pred.eq(target.view(1, -1).expand_as(pred))
191 |
192 | res = []
193 | for k in topk:
194 | correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
195 | res.append(correct_k.mul_(100.0 / batch_size))
196 | return res
197 |
198 |
199 | def mean_confidence_interval(data, confidence=0.95):
200 | a = [1.0*np.array(data[i].cpu()) for i in range(len(data))]
201 | n = len(a)
202 | m, se = np.mean(a), scipy.stats.sem(a)
203 | h = se * sp.stats.t._ppf((1+confidence)/2., n-1)
204 | return m,h
205 |
206 |
207 |
208 | # ======================================== Settings of path ============================================
209 | # saving path
210 | opt.outf = opt.outf+'_'+opt.data_name+'_'+str(opt.basemodel)+'_'+str(opt.way_num)+'Way_'+str(opt.shot_num)+'Shot'+'_K'+str(opt.neighbor_k)
211 |
212 | if not os.path.exists(opt.outf):
213 | os.makedirs(opt.outf)
214 |
215 | if torch.cuda.is_available() and not opt.cuda:
216 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
217 |
218 | # save the opt and results to a txt file
219 | txt_save_path = os.path.join(opt.outf, 'Test_resutls.txt')
220 | F_txt = open(txt_save_path, 'a+')
221 | print(opt)
222 | print(opt, file=F_txt)
223 |
224 |
225 |
226 | # ========================================== Model Config ===============================================
227 | ngpu = int(opt.ngpu)
228 | global best_prec1, epoch_index
229 | best_prec1 = 0
230 | epoch_index = 0
231 |
232 | model = DN4Net.define_DN4Net(which_model=opt.basemodel, num_classes=opt.way_num, neighbor_k=opt.neighbor_k, norm='batch',
233 | init_type='normal', use_gpu=opt.cuda)
234 |
235 | # define loss function (criterion) and optimizer
236 | criterion = nn.CrossEntropyLoss().cuda()
237 | optimizer = optim.Adam(model.parameters(), lr=opt.lr, betas=(opt.beta1, 0.9))
238 |
239 |
240 | # optionally resume from a checkpoint
241 | if opt.resume:
242 | if os.path.isfile(opt.resume):
243 | print("=> loading checkpoint '{}'".format(opt.resume))
244 | checkpoint = torch.load(opt.resume)
245 | epoch_index = checkpoint['epoch_index']
246 | best_prec1 = checkpoint['best_prec1']
247 | model.load_state_dict(checkpoint['state_dict'])
248 | optimizer.load_state_dict(checkpoint['optimizer'])
249 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']))
250 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']), file=F_txt)
251 | else:
252 | print("=> no checkpoint found at '{}'".format(opt.resume))
253 | print("=> no checkpoint found at '{}'".format(opt.resume), file=F_txt)
254 |
255 | if opt.ngpu > 1:
256 | model = nn.DataParallel(model, range(opt.ngpu))
257 |
258 | # print the architecture of the network
259 | print(model)
260 | print(model, file=F_txt)
261 |
262 |
263 |
264 |
265 | # ============================================ Testing phase ========================================
266 | print('\n............Start testing............')
267 | start_time = time.time()
268 | repeat_num = 5 # repeat running the testing code several times
269 |
270 |
271 | total_accuracy = 0.0
272 | total_h = np.zeros(repeat_num)
273 | total_accuracy_vector = []
274 | for r in range(repeat_num):
275 | print('===================================== Round %d =====================================' %r)
276 | print('===================================== Round %d =====================================' %r, file=F_txt)
277 |
278 | # ======================================= Folder of Datasets =======================================
279 |
280 | # image transform & normalization
281 | ImgTransform = transforms.Compose([
282 | transforms.Resize((opt.imageSize, opt.imageSize)),
283 | transforms.ToTensor(),
284 | transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
285 | ])
286 |
287 | testset = Imagefolder_csv(
288 | data_dir=opt.dataset_dir, mode=opt.mode, image_size=opt.imageSize, transform=ImgTransform,
289 | episode_num=opt.episode_test_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
290 | )
291 | print('Testset: %d-------------%d' %(len(testset), r), file=F_txt)
292 |
293 |
294 |
295 | # ========================================== Load Datasets =========================================
296 | test_loader = torch.utils.data.DataLoader(
297 | testset, batch_size=opt.testepisodeSize, shuffle=True,
298 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
299 | )
300 |
301 |
302 | # =========================================== Evaluation ==========================================
303 | prec1, accuracies = validate(test_loader, model, criterion, epoch_index, F_txt)
304 |
305 |
306 | test_accuracy, h = mean_confidence_interval(accuracies)
307 | print("Test accuracy", test_accuracy, "h", h[0])
308 | print("Test accuracy", test_accuracy, "h", h[0], file=F_txt)
309 | total_accuracy += test_accuracy
310 | total_accuracy_vector.extend(accuracies)
311 | total_h[r] = h
312 |
313 |
314 | aver_accuracy, _ = mean_confidence_interval(total_accuracy_vector)
315 | print("Aver_accuracy:", aver_accuracy, "Aver_h", total_h.mean())
316 | print("Aver_accuracy:", aver_accuracy, "Aver_h", total_h.mean(), file=F_txt)
317 | F_txt.close()
318 |
319 | # ============================================== Testing End ==========================================
320 |
--------------------------------------------------------------------------------
/DN4_2019_Version/DN4_Train_5way1shot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Author: Wenbin Li (liwenbin.nju@gmail.com)
6 | Date: April 9, 2019
7 | Version: V0
8 |
9 | Citation:
10 | @inproceedings{li2019DN4,
11 | title={Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning},
12 | author={Li, Wenbin and Wang, Lei and Xu, Jinglin and Huo, Jing and Gao Yang and Luo, Jiebo},
13 | booktitle={CVPR},
14 | year={2019}
15 | }
16 | """
17 |
18 |
19 | from __future__ import print_function
20 | import argparse
21 | import os
22 | import random
23 | import shutil
24 | import numpy as np
25 | import torch
26 | import torch.nn as nn
27 | import torch.nn.parallel
28 | import torch.backends.cudnn as cudnn
29 | import torch.optim as optim
30 | import torch.utils.data
31 | import torchvision.datasets as dset
32 | import torchvision.transforms as transforms
33 | import torchvision.utils as vutils
34 | from torch.autograd import grad
35 | import time
36 | from torch import autograd
37 | from PIL import ImageFile
38 | import pdb
39 | import sys
40 | sys.dont_write_bytecode = True
41 |
42 |
43 | # ============================ Data & Networks =====================================
44 | from dataset.datasets_csv import Imagefolder_csv
45 | import models.network as DN4Net
46 | # ==================================================================================
47 |
48 |
49 | ImageFile.LOAD_TRUNCATED_IMAGES = True
50 | os.environ['CUDA_DEVICE_ORDER']='PCI_BUS_ID'
51 | os.environ['CUDA_VISIBLE_DEVICES']='0'
52 |
53 |
54 | parser = argparse.ArgumentParser()
55 | parser.add_argument('--dataset_dir', default='/Datasets/miniImageNet--ravi', help='/miniImageNet')
56 | parser.add_argument('--data_name', default='miniImageNet', help='miniImageNet|StanfordDog|StanfordCar|CubBird')
57 | parser.add_argument('--mode', default='train', help='train|val|test')
58 | parser.add_argument('--outf', default='./results/DN4')
59 | parser.add_argument('--resume', default='', type=str, help='path to the lastest checkpoint (default: none)')
60 | parser.add_argument('--basemodel', default='Conv64F', help='Conv64F|ResNet256F')
61 | parser.add_argument('--workers', type=int, default=8)
62 | # Few-shot parameters #
63 | parser.add_argument('--imageSize', type=int, default=84)
64 | parser.add_argument('--episodeSize', type=int, default=1, help='the mini-batch size of training')
65 | parser.add_argument('--testepisodeSize', type=int, default=1, help='one episode is taken as a mini-batch')
66 | parser.add_argument('--epochs', type=int, default=30, help='the total number of training epoch')
67 | parser.add_argument('--episode_train_num', type=int, default=10000, help='the total number of training episodes')
68 | parser.add_argument('--episode_val_num', type=int, default=1000, help='the total number of evaluation episodes')
69 | parser.add_argument('--episode_test_num', type=int, default=1000, help='the total number of testing episodes')
70 | parser.add_argument('--way_num', type=int, default=5, help='the number of way/class')
71 | parser.add_argument('--shot_num', type=int, default=1, help='the number of shot')
72 | parser.add_argument('--query_num', type=int, default=15, help='the number of queries')
73 | parser.add_argument('--neighbor_k', type=int, default=3, help='the number of k-nearest neighbors')
74 | parser.add_argument('--lr', type=float, default=0.005, help='learning rate, default=0.005')
75 | parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
76 | parser.add_argument('--cuda', action='store_true', default=True, help='enables cuda')
77 | parser.add_argument('--ngpu', type=int, default=1, help='the number of gpus')
78 | parser.add_argument('--nc', type=int, default=3, help='input image channels')
79 | parser.add_argument('--clamp_lower', type=float, default=-0.01)
80 | parser.add_argument('--clamp_upper', type=float, default=0.01)
81 | parser.add_argument('--print_freq', '-p', default=100, type=int, metavar='N', help='print frequency (default: 100)')
82 | opt = parser.parse_args()
83 | opt.cuda = True
84 | cudnn.benchmark = True
85 |
86 |
87 |
88 | # ======================================= Define functions =============================================
89 |
90 | def adjust_learning_rate(optimizer, epoch_num):
91 | """Sets the learning rate to the initial LR decayed by 0.05 every 10 epochs"""
92 | lr = opt.lr * (0.05 ** (epoch_num // 10))
93 | for param_group in optimizer.param_groups:
94 | param_group['lr'] = lr
95 |
96 |
97 | def train(train_loader, model, criterion, optimizer, epoch_index, F_txt):
98 | batch_time = AverageMeter()
99 | data_time = AverageMeter()
100 | losses = AverageMeter()
101 | top1 = AverageMeter()
102 |
103 |
104 | end = time.time()
105 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(train_loader):
106 |
107 | # Measure data loading time
108 | data_time.update(time.time() - end)
109 |
110 | # Convert query and support images
111 | query_images = torch.cat(query_images, 0)
112 | input_var1 = query_images.cuda()
113 |
114 | input_var2 = []
115 | for i in range(len(support_images)):
116 | temp_support = support_images[i]
117 | temp_support = torch.cat(temp_support, 0)
118 | temp_support = temp_support.cuda()
119 | input_var2.append(temp_support)
120 |
121 | # Deal with the targets
122 | target = torch.cat(query_targets, 0)
123 | target = target.cuda()
124 |
125 | # Calculate the output
126 | output = model(input_var1, input_var2)
127 | loss = criterion(output, target)
128 |
129 | # Compute gradients and do SGD step
130 | optimizer.zero_grad()
131 | loss.backward()
132 | optimizer.step()
133 |
134 |
135 | # Measure accuracy and record loss
136 | prec1, _ = accuracy(output, target, topk=(1,3))
137 | losses.update(loss.item(), query_images.size(0))
138 | top1.update(prec1[0], query_images.size(0))
139 |
140 |
141 | # Measure elapsed time
142 | batch_time.update(time.time() - end)
143 | end = time.time()
144 |
145 |
146 | #============== print the intermediate results ==============#
147 | if episode_index % opt.print_freq == 0 and episode_index != 0:
148 |
149 | print('Eposide-({0}): [{1}/{2}]\t'
150 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
151 | 'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
152 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
153 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
154 | epoch_index, episode_index, len(train_loader), batch_time=batch_time, data_time=data_time, loss=losses, top1=top1))
155 |
156 | print('Eposide-({0}): [{1}/{2}]\t'
157 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
158 | 'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
159 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
160 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
161 | epoch_index, episode_index, len(train_loader), batch_time=batch_time, data_time=data_time, loss=losses, top1=top1), file=F_txt)
162 |
163 |
164 |
165 | def validate(val_loader, model, criterion, epoch_index, best_prec1, F_txt):
166 | batch_time = AverageMeter()
167 | losses = AverageMeter()
168 | top1 = AverageMeter()
169 |
170 |
171 | # switch to evaluate mode
172 | model.eval()
173 | accuracies = []
174 |
175 |
176 | end = time.time()
177 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(val_loader):
178 |
179 | # Convert query and support images
180 | query_images = torch.cat(query_images, 0)
181 | input_var1 = query_images.cuda()
182 |
183 |
184 | input_var2 = []
185 | for i in range(len(support_images)):
186 | temp_support = support_images[i]
187 | temp_support = torch.cat(temp_support, 0)
188 | temp_support = temp_support.cuda()
189 | input_var2.append(temp_support)
190 |
191 |
192 | # Deal with the targets
193 | target = torch.cat(query_targets, 0)
194 | target = target.cuda()
195 |
196 | # Calculate the output
197 | output = model(input_var1, input_var2)
198 | loss = criterion(output, target)
199 |
200 |
201 | # measure accuracy and record loss
202 | prec1, _ = accuracy(output, target, topk=(1, 3))
203 | losses.update(loss.item(), query_images.size(0))
204 | top1.update(prec1[0], query_images.size(0))
205 | accuracies.append(prec1)
206 |
207 |
208 | # measure elapsed time
209 | batch_time.update(time.time() - end)
210 | end = time.time()
211 |
212 |
213 | #============== print the intermediate results ==============#
214 | if episode_index % opt.print_freq == 0 and episode_index != 0:
215 |
216 | print('Test-({0}): [{1}/{2}]\t'
217 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
218 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
219 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
220 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1))
221 |
222 | print('Test-({0}): [{1}/{2}]\t'
223 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
224 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
225 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
226 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1), file=F_txt)
227 |
228 |
229 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1))
230 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1), file=F_txt)
231 |
232 | return top1.avg, accuracies
233 |
234 |
235 |
236 | def save_checkpoint(state, filename='checkpoint.pth.tar'):
237 | torch.save(state, filename)
238 |
239 |
240 | class AverageMeter(object):
241 | """Computes and stores the average and current value"""
242 | def __init__(self):
243 | self.reset()
244 |
245 | def reset(self):
246 | self.val = 0
247 | self.avg = 0
248 | self.sum = 0
249 | self.count = 0
250 |
251 | def update(self, val, n=1):
252 | self.val = val
253 | self.sum += val * n
254 | self.count += n
255 | self.avg = self.sum / self.count
256 |
257 |
258 | def accuracy(output, target, topk=(1,)):
259 | """Computes the precision@k for the specified values of k"""
260 | with torch.no_grad():
261 | maxk = max(topk)
262 | batch_size = target.size(0)
263 |
264 | _, pred = output.topk(maxk, 1, True, True)
265 | pred = pred.t()
266 | correct = pred.eq(target.view(1, -1).expand_as(pred))
267 |
268 | res = []
269 | for k in topk:
270 | correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
271 | res.append(correct_k.mul_(100.0 / batch_size))
272 | return res
273 |
274 |
275 |
276 | # ======================================== Settings of path ============================================
277 | # saving path
278 | opt.outf = opt.outf+'_'+opt.data_name+'_'+str(opt.basemodel)+'_'+str(opt.way_num)+'Way_'+str(opt.shot_num)+'Shot'+'_K'+str(opt.neighbor_k)
279 |
280 | if not os.path.exists(opt.outf):
281 | os.makedirs(opt.outf)
282 |
283 | if torch.cuda.is_available() and not opt.cuda:
284 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
285 |
286 | # save the opt and results to a txt file
287 | txt_save_path = os.path.join(opt.outf, 'opt_resutls.txt')
288 | F_txt = open(txt_save_path, 'a+')
289 | print(opt)
290 | print(opt, file=F_txt)
291 |
292 |
293 |
294 | # ========================================== Model Config ===============================================
295 | ngpu = int(opt.ngpu)
296 | global best_prec1, epoch_index
297 | best_prec1 = 0
298 | epoch_index = 0
299 |
300 | model = DN4Net.define_DN4Net(which_model=opt.basemodel, num_classes=opt.way_num, neighbor_k=opt.neighbor_k, norm='batch',
301 | init_type='normal', use_gpu=opt.cuda)
302 |
303 | # define loss function (criterion) and optimizer
304 | criterion = nn.CrossEntropyLoss().cuda()
305 | optimizer = optim.Adam(model.parameters(), lr=opt.lr, betas=(opt.beta1, 0.9))
306 |
307 |
308 | # optionally resume from a checkpoint
309 | if opt.resume:
310 | if os.path.isfile(opt.resume):
311 | print("=> loading checkpoint '{}'".format(opt.resume))
312 | checkpoint = torch.load(opt.resume)
313 | epoch_index = checkpoint['epoch_index']
314 | best_prec1 = checkpoint['best_prec1']
315 | model.load_state_dict(checkpoint['state_dict'])
316 | optimizer.load_state_dict(checkpoint['optimizer'])
317 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']))
318 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']), file=F_txt)
319 | else:
320 | print("=> no checkpoint found at '{}'".format(opt.resume))
321 | print("=> no checkpoint found at '{}'".format(opt.resume), file=F_txt)
322 |
323 | if opt.ngpu > 1:
324 | model = nn.DataParallel(model, range(opt.ngpu))
325 |
326 | # print the architecture of the network
327 | print(model)
328 | print(model, file=F_txt)
329 |
330 |
331 |
332 |
333 | # ======================================== Training phase ===============================================
334 | print('\n............Start training............\n')
335 | start_time = time.time()
336 |
337 |
338 | for epoch_item in range(opt.epochs):
339 | print('===================================== Epoch %d =====================================' %epoch_item)
340 | print('===================================== Epoch %d =====================================' %epoch_item, file=F_txt)
341 | adjust_learning_rate(optimizer, epoch_item)
342 |
343 |
344 | # ======================================= Folder of Datasets =======================================
345 | # image transform & normalization
346 | ImgTransform = transforms.Compose([
347 | transforms.Resize((opt.imageSize, opt.imageSize)),
348 | transforms.ToTensor(),
349 | transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
350 | ])
351 |
352 | trainset = Imagefolder_csv(
353 | data_dir=opt.dataset_dir, mode=opt.mode, image_size=opt.imageSize, transform=ImgTransform,
354 | episode_num=opt.episode_train_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
355 | )
356 | valset = Imagefolder_csv(
357 | data_dir=opt.dataset_dir, mode='val', image_size=opt.imageSize, transform=ImgTransform,
358 | episode_num=opt.episode_val_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
359 | )
360 | testset = Imagefolder_csv(
361 | data_dir=opt.dataset_dir, mode='test', image_size=opt.imageSize, transform=ImgTransform,
362 | episode_num=opt.episode_test_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
363 | )
364 |
365 | print('Trainset: %d' %len(trainset))
366 | print('Valset: %d' %len(valset))
367 | print('Testset: %d' %len(testset))
368 | print('Trainset: %d' %len(trainset), file=F_txt)
369 | print('Valset: %d' %len(valset), file=F_txt)
370 | print('Testset: %d' %len(testset), file=F_txt)
371 |
372 |
373 |
374 | # ========================================== Load Datasets =========================================
375 | train_loader = torch.utils.data.DataLoader(
376 | trainset, batch_size=opt.episodeSize, shuffle=True,
377 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
378 | )
379 | val_loader = torch.utils.data.DataLoader(
380 | valset, batch_size=opt.testepisodeSize, shuffle=True,
381 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
382 | )
383 | test_loader = torch.utils.data.DataLoader(
384 | testset, batch_size=opt.testepisodeSize, shuffle=True,
385 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
386 | )
387 |
388 |
389 | # ============================================ Training ===========================================
390 | # Fix the parameters of Batch Normalization after 10000 episodes (1 epoch)
391 | if epoch_item < 1:
392 | model.train()
393 | else:
394 | model.eval()
395 |
396 | # Train for 10000 episodes in each epoch
397 | train(train_loader, model, criterion, optimizer, epoch_item, F_txt)
398 |
399 |
400 | # =========================================== Evaluation ==========================================
401 | print('============ Validation on the val set ============')
402 | print('============ validation on the val set ============', file=F_txt)
403 | prec1, _ = validate(val_loader, model, criterion, epoch_item, best_prec1, F_txt)
404 |
405 |
406 | # record the best prec@1 and save checkpoint
407 | is_best = prec1 > best_prec1
408 | best_prec1 = max(prec1, best_prec1)
409 |
410 | # save the checkpoint
411 | if is_best:
412 | save_checkpoint(
413 | {
414 | 'epoch_index': epoch_item,
415 | 'arch': opt.basemodel,
416 | 'state_dict': model.state_dict(),
417 | 'best_prec1': best_prec1,
418 | 'optimizer' : optimizer.state_dict(),
419 | }, os.path.join(opt.outf, 'model_best.pth.tar'))
420 |
421 |
422 | if epoch_item % 10 == 0:
423 | filename = os.path.join(opt.outf, 'epoch_%d.pth.tar' %epoch_item)
424 | save_checkpoint(
425 | {
426 | 'epoch_index': epoch_item,
427 | 'arch': opt.basemodel,
428 | 'state_dict': model.state_dict(),
429 | 'best_prec1': best_prec1,
430 | 'optimizer' : optimizer.state_dict(),
431 | }, filename)
432 |
433 |
434 | # Testing Prase
435 | print('============ Testing on the test set ============')
436 | print('============ Testing on the test set ============', file=F_txt)
437 | prec1, _ = validate(test_loader, model, criterion, epoch_item, best_prec1, F_txt)
438 |
439 |
440 | F_txt.close()
441 | print('............Training is end............')
442 |
443 | # ============================================ Training End ==============================================================
444 |
--------------------------------------------------------------------------------
/DN4_2019_Version/DN4_Train_5way5shot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Author: Wenbin Li (liwenbin.nju@gmail.com)
6 | Date: April 9, 2019
7 | Version: V0
8 |
9 | Citation:
10 | @inproceedings{li2019DN4,
11 | title={Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning},
12 | author={Li, Wenbin and Wang, Lei and Xu, Jinglin and Huo, Jing and Gao Yang and Luo, Jiebo},
13 | booktitle={CVPR},
14 | year={2019}
15 | }
16 | """
17 |
18 |
19 | from __future__ import print_function
20 | import argparse
21 | import os
22 | import random
23 | import shutil
24 | import numpy as np
25 | import torch
26 | import torch.nn as nn
27 | import torch.nn.parallel
28 | import torch.backends.cudnn as cudnn
29 | import torch.optim as optim
30 | import torch.utils.data
31 | import torchvision.datasets as dset
32 | import torchvision.transforms as transforms
33 | import torchvision.utils as vutils
34 | from torch.autograd import grad
35 | import time
36 | from torch import autograd
37 | from PIL import ImageFile
38 | import pdb
39 | import sys
40 | sys.dont_write_bytecode = True
41 |
42 |
43 | # ============================ Data & Networks =====================================
44 | from dataset.datasets_csv import Imagefolder_csv
45 | import models.network as DN4Net
46 | # ==================================================================================
47 |
48 |
49 | ImageFile.LOAD_TRUNCATED_IMAGES = True
50 | os.environ['CUDA_DEVICE_ORDER']='PCI_BUS_ID'
51 | os.environ['CUDA_VISIBLE_DEVICES']='0'
52 |
53 |
54 | parser = argparse.ArgumentParser()
55 | parser.add_argument('--dataset_dir', default='/Datasets/miniImageNet--ravi', help='/miniImageNet')
56 | parser.add_argument('--data_name', default='miniImageNet', help='miniImageNet|StanfordDog|StanfordCar|CubBird')
57 | parser.add_argument('--mode', default='train', help='train|val|test')
58 | parser.add_argument('--outf', default='./results/DN4')
59 | parser.add_argument('--resume', default='', type=str, help='path to the lastest checkpoint (default: none)')
60 | parser.add_argument('--basemodel', default='Conv64F', help='Conv64F|ResNet256F')
61 | parser.add_argument('--workers', type=int, default=8)
62 | # Few-shot parameters #
63 | parser.add_argument('--imageSize', type=int, default=84)
64 | parser.add_argument('--episodeSize', type=int, default=1, help='the mini-batch size of training')
65 | parser.add_argument('--testepisodeSize', type=int, default=1, help='one episode is taken as a mini-batch')
66 | parser.add_argument('--epochs', type=int, default=30, help='the total number of training epoch')
67 | parser.add_argument('--episode_train_num', type=int, default=10000, help='the total number of training episodes')
68 | parser.add_argument('--episode_val_num', type=int, default=1000, help='the total number of evaluation episodes')
69 | parser.add_argument('--episode_test_num', type=int, default=1000, help='the total number of testing episodes')
70 | parser.add_argument('--way_num', type=int, default=5, help='the number of way/class')
71 | parser.add_argument('--shot_num', type=int, default=5, help='the number of shot')
72 | parser.add_argument('--query_num', type=int, default=10, help='the number of queries')
73 | parser.add_argument('--neighbor_k', type=int, default=3, help='the number of k-nearest neighbors')
74 | parser.add_argument('--lr', type=float, default=0.005, help='learning rate, default=0.005')
75 | parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
76 | parser.add_argument('--cuda', action='store_true', default=True, help='enables cuda')
77 | parser.add_argument('--ngpu', type=int, default=1, help='the number of gpus')
78 | parser.add_argument('--nc', type=int, default=3, help='input image channels')
79 | parser.add_argument('--clamp_lower', type=float, default=-0.01)
80 | parser.add_argument('--clamp_upper', type=float, default=0.01)
81 | parser.add_argument('--print_freq', '-p', default=100, type=int, metavar='N', help='print frequency (default: 100)')
82 | opt = parser.parse_args()
83 | opt.cuda = True
84 | cudnn.benchmark = True
85 |
86 |
87 |
88 | # ======================================= Define functions =============================================
89 |
90 | def adjust_learning_rate(optimizer, epoch_num):
91 | """Sets the learning rate to the initial LR decayed by 0.05 every 10 epochs"""
92 | lr = opt.lr * (0.05 ** (epoch_num // 10))
93 | for param_group in optimizer.param_groups:
94 | param_group['lr'] = lr
95 |
96 |
97 | def train(train_loader, model, criterion, optimizer, epoch_index, F_txt):
98 | batch_time = AverageMeter()
99 | data_time = AverageMeter()
100 | losses = AverageMeter()
101 | top1 = AverageMeter()
102 |
103 |
104 | end = time.time()
105 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(train_loader):
106 |
107 | # Measure data loading time
108 | data_time.update(time.time() - end)
109 |
110 | # Convert query and support images
111 | query_images = torch.cat(query_images, 0)
112 | input_var1 = query_images.cuda()
113 |
114 | input_var2 = []
115 | for i in range(len(support_images)):
116 | temp_support = support_images[i]
117 | temp_support = torch.cat(temp_support, 0)
118 | temp_support = temp_support.cuda()
119 | input_var2.append(temp_support)
120 |
121 | # Deal with the targets
122 | target = torch.cat(query_targets, 0)
123 | target = target.cuda()
124 |
125 | # Calculate the output
126 | output = model(input_var1, input_var2)
127 | loss = criterion(output, target)
128 |
129 | # Compute gradients and do SGD step
130 | optimizer.zero_grad()
131 | loss.backward()
132 | optimizer.step()
133 |
134 |
135 | # Measure accuracy and record loss
136 | prec1, _ = accuracy(output, target, topk=(1,3))
137 | losses.update(loss.item(), query_images.size(0))
138 | top1.update(prec1[0], query_images.size(0))
139 |
140 |
141 | # Measure elapsed time
142 | batch_time.update(time.time() - end)
143 | end = time.time()
144 |
145 |
146 | #============== print the intermediate results ==============#
147 | if episode_index % opt.print_freq == 0 and episode_index != 0:
148 |
149 | print('Eposide-({0}): [{1}/{2}]\t'
150 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
151 | 'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
152 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
153 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
154 | epoch_index, episode_index, len(train_loader), batch_time=batch_time, data_time=data_time, loss=losses, top1=top1))
155 |
156 | print('Eposide-({0}): [{1}/{2}]\t'
157 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
158 | 'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
159 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
160 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
161 | epoch_index, episode_index, len(train_loader), batch_time=batch_time, data_time=data_time, loss=losses, top1=top1), file=F_txt)
162 |
163 |
164 |
165 | def validate(val_loader, model, criterion, epoch_index, best_prec1, F_txt):
166 | batch_time = AverageMeter()
167 | losses = AverageMeter()
168 | top1 = AverageMeter()
169 |
170 |
171 | # switch to evaluate mode
172 | model.eval()
173 | accuracies = []
174 |
175 |
176 | end = time.time()
177 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(val_loader):
178 |
179 | # Convert query and support images
180 | query_images = torch.cat(query_images, 0)
181 | input_var1 = query_images.cuda()
182 |
183 |
184 | input_var2 = []
185 | for i in range(len(support_images)):
186 | temp_support = support_images[i]
187 | temp_support = torch.cat(temp_support, 0)
188 | temp_support = temp_support.cuda()
189 | input_var2.append(temp_support)
190 |
191 |
192 | # Deal with the target
193 | target = torch.cat(query_targets, 0)
194 | target = target.cuda()
195 |
196 | # Calculate the output
197 | output = model(input_var1, input_var2)
198 | loss = criterion(output, target)
199 |
200 |
201 | # measure accuracy and record loss
202 | prec1, _ = accuracy(output, target, topk=(1, 3))
203 | losses.update(loss.item(), query_images.size(0))
204 | top1.update(prec1[0], query_images.size(0))
205 | accuracies.append(prec1)
206 |
207 |
208 | # measure elapsed time
209 | batch_time.update(time.time() - end)
210 | end = time.time()
211 |
212 |
213 | #============== print the intermediate results ==============#
214 | if episode_index % opt.print_freq == 0 and episode_index != 0:
215 |
216 | print('Test-({0}): [{1}/{2}]\t'
217 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
218 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
219 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
220 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1))
221 |
222 | print('Test-({0}): [{1}/{2}]\t'
223 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
224 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
225 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
226 | epoch_index, episode_index, len(val_loader), batch_time=batch_time, loss=losses, top1=top1), file=F_txt)
227 |
228 |
229 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1))
230 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1), file=F_txt)
231 |
232 | return top1.avg, accuracies
233 |
234 |
235 |
236 | def save_checkpoint(state, filename='checkpoint.pth.tar'):
237 | torch.save(state, filename)
238 |
239 |
240 | class AverageMeter(object):
241 | """Computes and stores the average and current value"""
242 | def __init__(self):
243 | self.reset()
244 |
245 | def reset(self):
246 | self.val = 0
247 | self.avg = 0
248 | self.sum = 0
249 | self.count = 0
250 |
251 | def update(self, val, n=1):
252 | self.val = val
253 | self.sum += val * n
254 | self.count += n
255 | self.avg = self.sum / self.count
256 |
257 |
258 | def accuracy(output, target, topk=(1,)):
259 | """Computes the precision@k for the specified values of k"""
260 | with torch.no_grad():
261 | maxk = max(topk)
262 | batch_size = target.size(0)
263 |
264 | _, pred = output.topk(maxk, 1, True, True)
265 | pred = pred.t()
266 | correct = pred.eq(target.view(1, -1).expand_as(pred))
267 |
268 | res = []
269 | for k in topk:
270 | correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
271 | res.append(correct_k.mul_(100.0 / batch_size))
272 | return res
273 |
274 |
275 |
276 | # ======================================== Settings of path ============================================
277 | # saving path
278 | opt.outf = opt.outf+'_'+opt.data_name+'_'+str(opt.basemodel)+'_'+str(opt.way_num)+'Way_'+str(opt.shot_num)+'Shot'+'_K'+str(opt.neighbor_k)
279 |
280 | if not os.path.exists(opt.outf):
281 | os.makedirs(opt.outf)
282 |
283 | if torch.cuda.is_available() and not opt.cuda:
284 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
285 |
286 | # save the opt and results to a txt file
287 | txt_save_path = os.path.join(opt.outf, 'opt_resutls.txt')
288 | F_txt = open(txt_save_path, 'a+')
289 | print(opt)
290 | print(opt, file=F_txt)
291 |
292 |
293 |
294 | # ========================================== Model Config ===============================================
295 | ngpu = int(opt.ngpu)
296 | global best_prec1, epoch_index
297 | best_prec1 = 0
298 | epoch_index = 0
299 |
300 | model = DN4Net.define_DN4Net(which_model=opt.basemodel, num_classes=opt.way_num, neighbor_k=opt.neighbor_k, norm='batch',
301 | init_type='normal', use_gpu=opt.cuda)
302 |
303 | # define loss function (criterion) and optimizer
304 | criterion = nn.CrossEntropyLoss().cuda()
305 | optimizer = optim.Adam(model.parameters(), lr=opt.lr, betas=(opt.beta1, 0.9))
306 |
307 |
308 | # optionally resume from a checkpoint
309 | if opt.resume:
310 | if os.path.isfile(opt.resume):
311 | print("=> loading checkpoint '{}'".format(opt.resume))
312 | checkpoint = torch.load(opt.resume)
313 | epoch_index = checkpoint['epoch_index']
314 | best_prec1 = checkpoint['best_prec1']
315 | model.load_state_dict(checkpoint['state_dict'])
316 | optimizer.load_state_dict(checkpoint['optimizer'])
317 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']))
318 | print("=> loaded checkpoint '{}' (epoch {})".format(opt.resume, checkpoint['epoch_index']), file=F_txt)
319 | else:
320 | print("=> no checkpoint found at '{}'".format(opt.resume))
321 | print("=> no checkpoint found at '{}'".format(opt.resume), file=F_txt)
322 |
323 | if opt.ngpu > 1:
324 | model = nn.DataParallel(model, range(opt.ngpu))
325 |
326 | # print the architecture of the network
327 | print(model)
328 | print(model, file=F_txt)
329 |
330 |
331 |
332 |
333 | # ======================================== Training phase ===============================================
334 | print('\n............Start training............\n')
335 | start_time = time.time()
336 |
337 |
338 | for epoch_item in range(opt.epochs):
339 | print('===================================== Epoch %d =====================================' %epoch_item)
340 | print('===================================== Epoch %d =====================================' %epoch_item, file=F_txt)
341 | adjust_learning_rate(optimizer, epoch_item)
342 |
343 |
344 | # ======================================= Folder of Datasets =======================================
345 | # image transform & normalization
346 | ImgTransform = transforms.Compose([
347 | transforms.Resize((opt.imageSize, opt.imageSize)),
348 | transforms.ToTensor(),
349 | transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
350 | ])
351 |
352 | trainset = Imagefolder_csv(
353 | data_dir=opt.dataset_dir, mode=opt.mode, image_size=opt.imageSize, transform=ImgTransform,
354 | episode_num=opt.episode_train_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
355 | )
356 | valset = Imagefolder_csv(
357 | data_dir=opt.dataset_dir, mode='val', image_size=opt.imageSize, transform=ImgTransform,
358 | episode_num=opt.episode_val_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
359 | )
360 | testset = Imagefolder_csv(
361 | data_dir=opt.dataset_dir, mode='test', image_size=opt.imageSize, transform=ImgTransform,
362 | episode_num=opt.episode_test_num, way_num=opt.way_num, shot_num=opt.shot_num, query_num=opt.query_num
363 | )
364 |
365 | print('Trainset: %d' %len(trainset))
366 | print('Valset: %d' %len(valset))
367 | print('Testset: %d' %len(testset))
368 | print('Trainset: %d' %len(trainset), file=F_txt)
369 | print('Valset: %d' %len(valset), file=F_txt)
370 | print('Testset: %d' %len(testset), file=F_txt)
371 |
372 |
373 |
374 | # ========================================== Load Datasets =========================================
375 | train_loader = torch.utils.data.DataLoader(
376 | trainset, batch_size=opt.episodeSize, shuffle=True,
377 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
378 | )
379 | val_loader = torch.utils.data.DataLoader(
380 | valset, batch_size=opt.testepisodeSize, shuffle=True,
381 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
382 | )
383 | test_loader = torch.utils.data.DataLoader(
384 | testset, batch_size=opt.testepisodeSize, shuffle=True,
385 | num_workers=int(opt.workers), drop_last=True, pin_memory=True
386 | )
387 |
388 |
389 | # ============================================ Training ===========================================
390 | # Fix the parameters of Batch Normalization after 10000 episodes (1 epoch)
391 | if epoch_item < 1:
392 | model.train()
393 | else:
394 | model.eval()
395 |
396 | # Train for 10000 episodes in each epoch
397 | train(train_loader, model, criterion, optimizer, epoch_item, F_txt)
398 |
399 |
400 | # =========================================== Evaluation ==========================================
401 | print('============ Validation on the val set ============')
402 | print('============ validation on the val set ============', file=F_txt)
403 | prec1, _ = validate(val_loader, model, criterion, epoch_item, best_prec1, F_txt)
404 |
405 |
406 | # record the best prec@1 and save checkpoint
407 | is_best = prec1 > best_prec1
408 | best_prec1 = max(prec1, best_prec1)
409 |
410 | # save the checkpoint
411 | if is_best:
412 | save_checkpoint(
413 | {
414 | 'epoch_index': epoch_item,
415 | 'arch': opt.basemodel,
416 | 'state_dict': model.state_dict(),
417 | 'best_prec1': best_prec1,
418 | 'optimizer' : optimizer.state_dict(),
419 | }, os.path.join(opt.outf, 'model_best.pth.tar'))
420 |
421 |
422 | if epoch_item % 10 == 0:
423 | filename = os.path.join(opt.outf, 'epoch_%d.pth.tar' %epoch_item)
424 | save_checkpoint(
425 | {
426 | 'epoch_index': epoch_item,
427 | 'arch': opt.basemodel,
428 | 'state_dict': model.state_dict(),
429 | 'best_prec1': best_prec1,
430 | 'optimizer' : optimizer.state_dict(),
431 | }, filename)
432 |
433 |
434 | # Testing Prase
435 | print('============ Testing on the test set ============')
436 | print('============ Testing on the test set ============', file=F_txt)
437 | prec1, _ = validate(test_loader, model, criterion, epoch_item, best_prec1, F_txt)
438 |
439 |
440 | F_txt.close()
441 | print('............Training is end............')
442 |
443 | # ============================================ Training End ==============================================================
444 |
--------------------------------------------------------------------------------
/DN4_2019_Version/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019, Wenbin Li
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 |
26 | --------------------------- LICENSE FOR CovaMNet --------------------------------
27 | BSD License
28 |
29 | For CovaMNet software
30 | Copyright (c) 2019, Wenbin Li
31 | All rights reserved.
32 |
33 | Redistribution and use in source and binary forms, with or without
34 | modification, are permitted provided that the following conditions are met:
35 |
36 | * Redistributions of source code must retain the above copyright notice, this
37 | list of conditions and the following disclaimer.
38 |
39 | * Redistributions in binary form must reproduce the above copyright notice,
40 | this list of conditions and the following disclaimer in the documentation
41 | and/or other materials provided with the distribution.
42 |
43 |
44 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/DN4_2019_Version/README.md:
--------------------------------------------------------------------------------
1 | # DN4 in PyTorch
2 |
3 | We provide a PyTorch implementation of DN4 for few-shot learning. If you use this code for your research, please cite:
4 |
5 | [Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning](http://cs.nju.edu.cn/rl/people/liwb/CVPR19.pdf).
6 | [Wenbin Li](https://cs.nju.edu.cn/liwenbin/), Lei Wang, Jinglin Xu, Jing Huo, Yang Gao and Jiebo Luo. In CVPR 2019.
7 |
8 |
9 |
10 | ## Prerequisites
11 | - Linux
12 | - Python 3
13 | - Pytorch 0.4 or 1.0
14 | - GPU + CUDA CuDNN
15 | - pillow, torchvision, scipy, numpy
16 |
17 | ## Getting Started
18 | ### Installation
19 |
20 | - Clone this repo:
21 | ```bash
22 | git clone https://github.com/WenbinLee/DN4.git
23 | cd DN4
24 | ```
25 |
26 | - Install [PyTorch](http://pytorch.org) 1.0 and other dependencies.
27 |
28 | ### Datasets
29 | - [miniImageNet](https://drive.google.com/file/d/1fUBrpv8iutYwdL4xE1rX_R9ef6tyncX9/view).
30 | - [StanfordDog](http://vision.stanford.edu/aditya86/ImageNetDogs/).
31 | - [StanfordCar](https://ai.stanford.edu/~jkrause/cars/car_dataset.html).
32 | - [CUB-200](http://www.vision.caltech.edu/visipedia/CUB-200.html).
33 | Thanks [Victor Garcia](https://github.com/vgsatorras/few-shot-gnn) for providing the miniImageNet dataset. In our paper, we just used the CUB-200 dataset. In fact, there is a newer revision of this dataset with more images, see [Caltech-UCSD Birds-200-2011](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html). Note, if you use these datasets, please cite the corresponding papers.
34 |
35 |
36 | ### miniImageNet Few-shot Classification
37 | - Train a 5-way 1-shot model based on Conv64F or ResNet256F:
38 | ```bash
39 | python DN4_Train_5way1shot.py --dataset_dir ./datasets/miniImageNet --data_name miniImageNet
40 | or
41 | python DN4_Train_5way1shot_Resnet.py --dataset_dir ./datasets/miniImageNet --data_name miniImageNet
42 | ```
43 | - Test the model (specify the dataset_dir, basemodel, and data_name first):
44 | ```bash
45 | python DN4_Test_5way1shot.py --resume ./results/DN4_miniImageNet_Conv64F_5Way_1Shot_K3/model_best.pth.tar --basemodel Conv64F
46 | or
47 | python DN4_Test_5way1shot.py --resume ./results/DN4_miniImageNet_ResNet256F_5Way_1Shot_K3/model_best.pth.tar --basemodel ResNet256F
48 | ```
49 |
50 | - The results on the miniImageNet dataset (If you set neighbor_k as 1, you may get better results in some cases):
51 |
52 |
53 |
54 | ### Fine-grained Few-shot Classification
55 | - Data prepocessing (e.g., StanfordDog)
56 | - Specify the path of the dataset and the saving path.
57 | - Run the preprocessing script.
58 | ```bash
59 | #!./dataset/StanfordDog_prepare_csv.py
60 | python ./dataset/StanfordDog_prepare_csv.py
61 | ```
62 | - Train a 5-way 1-shot model:
63 | ```bash
64 | python DN4_Train_5way1shot.py --dataset_dir ./datasets/StanfordDog --data_name StanfordDog
65 | ```
66 | - Test the model (specify the dataset_dir and data_name first):
67 | ```bash
68 | python DN4_Test_5way1shot.py --resume ./results/DN4_StanfordDog_Conv64F_5_Way_1_Shot/model_best.pth.tar --basemodel Conv64F
69 | ```
70 | - The results on the fine-grained datasets:
71 |
72 |
73 |
74 |
75 | ## Citation
76 | If you use this code for your research, please cite our paper.
77 | ```
78 | @inproceedings{li2019DN4,
79 | title={Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning},
80 | author={Li, Wenbin and Wang, Lei and Xu, Jinglin and Huo, Jing and Gao Yang and Luo, Jiebo},
81 | booktitle={CVPR},
82 | year={2019}
83 | }
84 | ```
85 |
--------------------------------------------------------------------------------
/DN4_2019_Version/dataset/CubBird_prepare_csv.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/CUB_birds' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/CUB_birds/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'images')
25 | train_class_num = 130
26 | val_class_num = 20
27 | test_class_num = 50
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(200)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/DN4_2019_Version/dataset/StanforCar_prepare_csv.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/Stanford_cars' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/Stanford_cars/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'images')
25 | train_class_num = 130
26 | val_class_num = 17
27 | test_class_num = 49
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(196)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/DN4_2019_Version/dataset/StanfordDog_prepare_csv.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/Stanford_dogs' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/Stanford_dogs/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'Images')
25 | train_class_num = 70
26 | val_class_num = 20
27 | test_class_num = 30
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(120)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/DN4_2019_Version/dataset/datasets_csv.py:
--------------------------------------------------------------------------------
1 | import os
2 | import os.path as path
3 | import json
4 | import torch
5 | import torch.utils.data as data
6 | import numpy as np
7 | import random
8 | from PIL import Image
9 | import pdb
10 | import csv
11 | import sys
12 | sys.dont_write_bytecode = True
13 |
14 |
15 |
16 | def pil_loader(path):
17 | # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)
18 | with open(path, 'rb') as f:
19 | with Image.open(f) as img:
20 | return img.convert('RGB')
21 |
22 |
23 | def accimage_loader(path):
24 | import accimage
25 | try:
26 | return accimage.Image(path)
27 | except IOError:
28 | # Potentially a decoding problem, fall back to PIL.Image
29 | return pil_loader(path)
30 |
31 |
32 | def gray_loader(path):
33 | with open(path, 'rb') as f:
34 | with Image.open(f) as img:
35 | return img.convert('P')
36 |
37 |
38 | def default_loader(path):
39 | from torchvision import get_image_backend
40 | if get_image_backend() == 'accimage':
41 | return accimage_loader(path)
42 | else:
43 | return pil_loader(path)
44 |
45 |
46 | def find_classes(dir):
47 | classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))]
48 | classes.sort()
49 | class_to_idx = {classes[i]: i for i in range(len(classes))}
50 |
51 | return classes, class_to_idx
52 |
53 |
54 | class Imagefolder_csv(object):
55 | """
56 | Imagefolder for miniImageNet--ravi, StanfordDog, StanfordCar and CubBird datasets.
57 | Images are stored in the folder of "images";
58 | Indexes are stored in the CSV files.
59 | """
60 |
61 | def __init__(self, data_dir="", mode="train", image_size=84, data_name="miniImageNet",
62 | transform=None, loader=default_loader, gray_loader=gray_loader,
63 | episode_num=1000, way_num=5, shot_num=5, query_num=5):
64 |
65 | super(Imagefolder_csv, self).__init__()
66 |
67 |
68 | # set the paths of the csv files
69 | train_csv = os.path.join(data_dir, 'train.csv')
70 | val_csv = os.path.join(data_dir, 'val.csv')
71 | test_csv = os.path.join(data_dir, 'test.csv')
72 |
73 |
74 | data_list = []
75 | e = 0
76 | if mode == "train":
77 |
78 | # store all the classes and images into a dict
79 | class_img_dict = {}
80 | with open(train_csv) as f_csv:
81 | f_train = csv.reader(f_csv, delimiter=',')
82 | for row in f_train:
83 | if f_train.line_num == 1:
84 | continue
85 | img_name, img_class = row
86 |
87 | if img_class in class_img_dict:
88 | class_img_dict[img_class].append(img_name)
89 | else:
90 | class_img_dict[img_class]=[]
91 | class_img_dict[img_class].append(img_name)
92 | f_csv.close()
93 | class_list = class_img_dict.keys()
94 |
95 |
96 | while e < episode_num:
97 |
98 | # construct each episode
99 | episode = []
100 | e += 1
101 | temp_list = random.sample(class_list, way_num)
102 | label_num = -1
103 |
104 | for item in temp_list:
105 | label_num += 1
106 | imgs_set = class_img_dict[item]
107 | support_imgs = random.sample(imgs_set, shot_num)
108 | query_imgs = [val for val in imgs_set if val not in support_imgs]
109 |
110 | if query_num < len(query_imgs):
111 | query_imgs = random.sample(query_imgs, query_num)
112 |
113 |
114 | # the dir of support set
115 | query_dir = [path.join(data_dir, 'images', i) for i in query_imgs]
116 | support_dir = [path.join(data_dir, 'images', i) for i in support_imgs]
117 |
118 |
119 | data_files = {
120 | "query_img": query_dir,
121 | "support_set": support_dir,
122 | "target": label_num
123 | }
124 | episode.append(data_files)
125 | data_list.append(episode)
126 |
127 |
128 | elif mode == "val":
129 |
130 | # store all the classes and images into a dict
131 | class_img_dict = {}
132 | with open(val_csv) as f_csv:
133 | f_val = csv.reader(f_csv, delimiter=',')
134 | for row in f_val:
135 | if f_val.line_num == 1:
136 | continue
137 | img_name, img_class = row
138 |
139 | if img_class in class_img_dict:
140 | class_img_dict[img_class].append(img_name)
141 | else:
142 | class_img_dict[img_class]=[]
143 | class_img_dict[img_class].append(img_name)
144 | f_csv.close()
145 | class_list = class_img_dict.keys()
146 |
147 |
148 |
149 | while e < episode_num: # setting the episode number to 600
150 |
151 | # construct each episode
152 | episode = []
153 | e += 1
154 | temp_list = random.sample(class_list, way_num)
155 | label_num = -1
156 |
157 | for item in temp_list:
158 | label_num += 1
159 | imgs_set = class_img_dict[item]
160 | support_imgs = random.sample(imgs_set, shot_num)
161 | query_imgs = [val for val in imgs_set if val not in support_imgs]
162 |
163 | if query_num Image-to-Class layer
138 | # Dataset: 3 x 84 x 84, for miniImageNet
139 | # Filters: 64->64->64->64
140 | # Mapping Sizes: 84->42->21->21->21
141 |
142 |
143 | class FourLayer_64F(nn.Module):
144 | def __init__(self, norm_layer=nn.BatchNorm2d, num_classes=5, neighbor_k=3):
145 | super(FourLayer_64F, self).__init__()
146 |
147 | if type(norm_layer) == functools.partial:
148 | use_bias = norm_layer.func == nn.InstanceNorm2d
149 | else:
150 | use_bias = norm_layer == nn.InstanceNorm2d
151 |
152 | self.features = nn.Sequential( # 3*84*84
153 | nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=use_bias),
154 | norm_layer(64),
155 | nn.LeakyReLU(0.2, True),
156 | nn.MaxPool2d(kernel_size=2, stride=2), # 64*42*42
157 |
158 | nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1, bias=use_bias),
159 | norm_layer(64),
160 | nn.LeakyReLU(0.2, True),
161 | nn.MaxPool2d(kernel_size=2, stride=2), # 64*21*21
162 |
163 | nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1, bias=use_bias),
164 | norm_layer(64),
165 | nn.LeakyReLU(0.2, True), # 64*21*21
166 |
167 | nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1, bias=use_bias),
168 | norm_layer(64),
169 | nn.LeakyReLU(0.2, True), # 64*21*21
170 | )
171 |
172 | self.imgtoclass = ImgtoClass_Metric(neighbor_k=neighbor_k) # 1*num_classes
173 |
174 |
175 |
176 | def forward(self, input1, input2):
177 |
178 | # extract features of input1--query image
179 | q = self.features(input1)
180 |
181 | # extract features of input2--support set
182 | S = []
183 | for i in range(len(input2)):
184 | support_set_sam = self.features(input2[i])
185 | B, C, h, w = support_set_sam.size()
186 | support_set_sam = support_set_sam.permute(1, 0, 2, 3)
187 | support_set_sam = support_set_sam.contiguous().view(C, -1)
188 | S.append(support_set_sam)
189 |
190 | x = self.imgtoclass(q, S) # get Batch*num_classes
191 |
192 | return x
193 |
194 |
195 |
196 | #========================== Define an image-to-class layer ==========================#
197 |
198 |
199 | class ImgtoClass_Metric(nn.Module):
200 | def __init__(self, neighbor_k=3):
201 | super(ImgtoClass_Metric, self).__init__()
202 | self.neighbor_k = neighbor_k
203 |
204 |
205 | # Calculate the k-Nearest Neighbor of each local descriptor
206 | def cal_cosinesimilarity(self, input1, input2):
207 | B, C, h, w = input1.size()
208 | Similarity_list = []
209 |
210 | for i in range(B):
211 | query_sam = input1[i]
212 | query_sam = query_sam.view(C, -1)
213 | query_sam = torch.transpose(query_sam, 0, 1)
214 | query_sam_norm = torch.norm(query_sam, 2, 1, True)
215 | query_sam = query_sam/query_sam_norm
216 |
217 | if torch.cuda.is_available():
218 | inner_sim = torch.zeros(1, len(input2)).cuda()
219 |
220 | for j in range(len(input2)):
221 | support_set_sam = input2[j]
222 | support_set_sam_norm = torch.norm(support_set_sam, 2, 0, True)
223 | support_set_sam = support_set_sam/support_set_sam_norm
224 |
225 | # cosine similarity between a query sample and a support category
226 | innerproduct_matrix = query_sam@support_set_sam
227 |
228 | # choose the top-k nearest neighbors
229 | topk_value, topk_index = torch.topk(innerproduct_matrix, self.neighbor_k, 1)
230 | inner_sim[0, j] = torch.sum(topk_value)
231 |
232 | Similarity_list.append(inner_sim)
233 |
234 | Similarity_list = torch.cat(Similarity_list, 0)
235 |
236 | return Similarity_list
237 |
238 |
239 | def forward(self, x1, x2):
240 |
241 | Similarity_list = self.cal_cosinesimilarity(x1, x2)
242 |
243 | return Similarity_list
244 |
245 |
246 |
247 |
248 | ##############################################################################
249 | # Classes: ResNetLike
250 | ##############################################################################
251 |
252 | # Model: ResNetLike
253 | # Refer to: https://github.com/gidariss/FewShotWithoutForgetting
254 | # Input: One query image and a support set
255 | # Base_model: 4 ResBlock layers --> Image-to-Class layer
256 | # Dataset: 3 x 84 x 84, for miniImageNet
257 | # Filters: 64->96->128->256
258 |
259 |
260 |
261 | class ResBlock(nn.Module):
262 | def __init__(self, nFin, nFout):
263 | super(ResBlock, self).__init__()
264 |
265 | self.conv_block = nn.Sequential()
266 | self.conv_block.add_module('BNorm1', nn.BatchNorm2d(nFin))
267 | self.conv_block.add_module('LRelu1', nn.LeakyReLU(0.2))
268 | self.conv_block.add_module('ConvL1', nn.Conv2d(nFin, nFout, kernel_size=3, padding=1, bias=False))
269 | self.conv_block.add_module('BNorm2', nn.BatchNorm2d(nFout))
270 | self.conv_block.add_module('LRelu2', nn.LeakyReLU(0.2))
271 | self.conv_block.add_module('ConvL2', nn.Conv2d(nFout, nFout, kernel_size=3, padding=1, bias=False))
272 | self.conv_block.add_module('BNorm3', nn.BatchNorm2d(nFout))
273 | self.conv_block.add_module('LRelu3', nn.LeakyReLU(0.2))
274 | self.conv_block.add_module('ConvL3', nn.Conv2d(nFout, nFout, kernel_size=3, padding=1, bias=False))
275 |
276 | self.skip_layer = nn.Conv2d(nFin, nFout, kernel_size=1, stride=1)
277 |
278 |
279 | def forward(self, x):
280 | return self.skip_layer(x) + self.conv_block(x)
281 |
282 |
283 |
284 | class ResNetLike(nn.Module):
285 | def __init__(self, opt, neighbor_k=3):
286 | super(ResNetLike, self).__init__()
287 |
288 | self.in_planes = opt['in_planes']
289 | self.out_planes = [64, 96, 128, 256]
290 | self.num_stages = 4
291 |
292 | if type(opt['norm_layer']) == functools.partial:
293 | use_bias = opt['norm_layer'].func == nn.InstanceNorm2d
294 | else:
295 | use_bias = opt['norm_layer'] == nn.InstanceNorm2d
296 |
297 |
298 | if type(self.out_planes) == int:
299 | self.out_planes = [self.out_planes for i in range(self.num_stages)]
300 |
301 | assert(type(self.out_planes)==list)
302 | assert(len(self.out_planes)==self.num_stages)
303 | num_planes = [self.out_planes[0],] + self.out_planes
304 | userelu = opt['userelu'] if ('userelu' in opt) else False
305 | dropout = opt['dropout'] if ('dropout' in opt) else 0
306 |
307 | self.feat_extractor = nn.Sequential()
308 | self.feat_extractor.add_module('ConvL0', nn.Conv2d(self.in_planes, num_planes[0], kernel_size=3, padding=1))
309 |
310 | for i in range(self.num_stages):
311 | self.feat_extractor.add_module('ResBlock'+str(i), ResBlock(num_planes[i], num_planes[i+1]))
312 | if i loaded checkpoint './results/DN4_new_miniImageNet_Conv64_5Way_1Shot_K3/model_best.pth.tar' (epoch 14)
3 | RelationNet_64(
4 | (features): Sequential(
5 | (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
6 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
7 | (2): LeakyReLU(negative_slope=0.2, inplace)
8 | (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
9 | (4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
10 | (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
11 | (6): LeakyReLU(negative_slope=0.2, inplace)
12 | (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
13 | (8): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (9): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (10): LeakyReLU(negative_slope=0.2, inplace)
16 | (11): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
17 | (12): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
18 | (13): LeakyReLU(negative_slope=0.2, inplace)
19 | )
20 | (indefense): CovaInDefense()
21 | )
22 | ===================================== Round 0 =====================================
23 | Testset: 600-------------0
24 | Test-(14): [100/600] Time 0.100 (0.268) Loss 1.179 (1.186) Prec@1 49.333 (52.528)
25 | Test-(14): [200/600] Time 0.224 (0.243) Loss 1.092 (1.199) Prec@1 50.667 (51.788)
26 | Test-(14): [300/600] Time 0.384 (0.232) Loss 1.505 (1.189) Prec@1 34.667 (52.385)
27 | Test-(14): [400/600] Time 0.382 (0.225) Loss 0.973 (1.192) Prec@1 54.667 (52.416)
28 | Test-(14): [500/600] Time 0.090 (0.223) Loss 1.079 (1.194) Prec@1 53.333 (52.357)
29 | * Prec@1 52.500 Best_prec1 50.575
30 | Test accuracy 52.500004 h 0.80446684
31 | ===================================== Round 1 =====================================
32 | Testset: 600-------------1
33 | Test-(14): [100/600] Time 0.290 (0.227) Loss 1.000 (1.210) Prec@1 60.000 (51.116)
34 | Test-(14): [200/600] Time 0.229 (0.200) Loss 1.053 (1.233) Prec@1 53.333 (50.600)
35 | Test-(14): [300/600] Time 0.110 (0.200) Loss 1.421 (1.231) Prec@1 44.000 (50.693)
36 | Test-(14): [400/600] Time 0.307 (0.199) Loss 1.354 (1.222) Prec@1 41.333 (51.009)
37 | Test-(14): [500/600] Time 0.114 (0.199) Loss 1.151 (1.219) Prec@1 52.000 (51.180)
38 | * Prec@1 51.731 Best_prec1 50.575
39 | Test accuracy 51.731113 h 0.8235916
40 | ===================================== Round 2 =====================================
41 | Testset: 600-------------2
42 | Test-(14): [100/600] Time 0.208 (0.229) Loss 1.802 (1.252) Prec@1 44.000 (49.914)
43 | Test-(14): [200/600] Time 0.140 (0.214) Loss 1.204 (1.230) Prec@1 60.000 (50.793)
44 | Test-(14): [300/600] Time 0.266 (0.208) Loss 1.311 (1.216) Prec@1 36.000 (51.380)
45 | Test-(14): [400/600] Time 0.172 (0.205) Loss 1.237 (1.228) Prec@1 46.667 (50.820)
46 | Test-(14): [500/600] Time 0.227 (0.203) Loss 1.130 (1.221) Prec@1 57.333 (51.026)
47 | * Prec@1 51.327 Best_prec1 50.575
48 | Test accuracy 51.32667 h 0.8058099
49 | ===================================== Round 3 =====================================
50 | Testset: 600-------------3
51 | Test-(14): [100/600] Time 0.360 (0.232) Loss 0.992 (1.202) Prec@1 54.667 (51.419)
52 | Test-(14): [200/600] Time 0.321 (0.216) Loss 1.203 (1.191) Prec@1 54.667 (52.219)
53 | Test-(14): [300/600] Time 0.096 (0.210) Loss 1.212 (1.199) Prec@1 49.333 (52.049)
54 | Test-(14): [400/600] Time 0.139 (0.201) Loss 0.988 (1.194) Prec@1 69.333 (52.226)
55 | Test-(14): [500/600] Time 0.107 (0.199) Loss 1.068 (1.202) Prec@1 61.333 (52.035)
56 | * Prec@1 52.222 Best_prec1 50.575
57 | Test accuracy 52.222225 h 0.8044752
58 | ===================================== Round 4 =====================================
59 | Testset: 600-------------4
60 | Test-(14): [100/600] Time 0.286 (0.225) Loss 1.180 (1.212) Prec@1 61.333 (52.409)
61 | Test-(14): [200/600] Time 0.141 (0.204) Loss 1.534 (1.221) Prec@1 48.000 (51.794)
62 | Test-(14): [300/600] Time 0.327 (0.205) Loss 1.679 (1.217) Prec@1 28.000 (51.743)
63 | Test-(14): [400/600] Time 0.246 (0.204) Loss 1.055 (1.214) Prec@1 56.000 (51.744)
64 | Test-(14): [500/600] Time 0.122 (0.205) Loss 0.873 (1.206) Prec@1 61.333 (51.976)
65 | * Prec@1 52.153 Best_prec1 50.575
66 | Test accuracy 52.153336 h 0.82311034
67 | Aver_accuracy: 51.986668 Aver_h 0.36276007
68 |
69 |
--------------------------------------------------------------------------------
/DN4_2019_Version/results/DN4_miniImageNet_Conv64F_5Way_1Shot_K3/model_best.pth.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/DN4_2019_Version/results/DN4_miniImageNet_Conv64F_5Way_1Shot_K3/model_best.pth.tar
--------------------------------------------------------------------------------
/DN4_2019_Version/results/DN4_miniImageNet_Conv64F_5Way_5Shot_K3/Test_resutls.txt:
--------------------------------------------------------------------------------
1 | Namespace(basemodel='Conv64', beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, cuda=True, data_name='miniImageNet', dataset_dir='/localdisk/wli70/FewShot/MultiTask_FewShot-V0/dataset/miniImageNet/miniImageNet--ravi', episodeSize=1, episode_test_num=600, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.005, mode='test', nc=3, neighbor_k=3, ngpu=1, outf='./results/DN4_new2_miniImageNet_Conv64_5Way_5Shot_K3', print_freq=100, query_num=10, resume='./results/DN4_new2_miniImageNet_Conv64_5Way_5Shot_K3/model_best.pth.tar', shot_num=5, testepisodeSize=1, way_num=5, workers=8)
2 | => loaded checkpoint './results/DN4_new2_miniImageNet_Conv64_5Way_5Shot_K3/model_best.pth.tar' (epoch 16)
3 | RelationNet_64(
4 | (features): Sequential(
5 | (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
6 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
7 | (2): LeakyReLU(negative_slope=0.2, inplace)
8 | (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
9 | (4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
10 | (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
11 | (6): LeakyReLU(negative_slope=0.2, inplace)
12 | (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
13 | (8): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (9): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (10): LeakyReLU(negative_slope=0.2, inplace)
16 | (11): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
17 | (12): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
18 | (13): LeakyReLU(negative_slope=0.2, inplace)
19 | )
20 | (indefense): CovaInDefense()
21 | )
22 | ===================================== Round 0 =====================================
23 | Testset: 600-------------0
24 | Test-(16): [100/600] Time 0.190 (0.217) Loss 0.320 (0.775) Prec@1 86.000 (71.149)
25 | Test-(16): [200/600] Time 0.258 (0.196) Loss 0.422 (0.741) Prec@1 88.000 (72.368)
26 | Test-(16): [300/600] Time 0.125 (0.189) Loss 0.500 (0.746) Prec@1 84.000 (72.033)
27 | Test-(16): [400/600] Time 0.147 (0.186) Loss 0.940 (0.758) Prec@1 66.000 (71.541)
28 | Test-(16): [500/600] Time 0.258 (0.184) Loss 1.100 (0.767) Prec@1 68.000 (71.082)
29 | * Prec@1 71.133 Best_prec1 69.308
30 | Test accuracy 71.13333 h 0.73003995
31 | ===================================== Round 1 =====================================
32 | Testset: 600-------------1
33 | Test-(16): [100/600] Time 0.283 (0.204) Loss 1.065 (0.774) Prec@1 64.000 (71.208)
34 | Test-(16): [200/600] Time 0.204 (0.185) Loss 0.573 (0.783) Prec@1 78.000 (71.114)
35 | Test-(16): [300/600] Time 0.180 (0.182) Loss 0.441 (0.771) Prec@1 80.000 (71.236)
36 | Test-(16): [400/600] Time 0.114 (0.181) Loss 0.828 (0.763) Prec@1 70.000 (71.646)
37 | Test-(16): [500/600] Time 0.213 (0.181) Loss 0.868 (0.768) Prec@1 70.000 (71.553)
38 | * Prec@1 71.337 Best_prec1 69.308
39 | Test accuracy 71.33667 h 0.67178565
40 | ===================================== Round 2 =====================================
41 | Testset: 600-------------2
42 | Test-(16): [100/600] Time 0.156 (0.194) Loss 1.051 (0.779) Prec@1 62.000 (70.931)
43 | Test-(16): [200/600] Time 0.165 (0.181) Loss 0.976 (0.789) Prec@1 62.000 (70.866)
44 | Test-(16): [300/600] Time 0.189 (0.179) Loss 0.915 (0.788) Prec@1 66.000 (70.651)
45 | Test-(16): [400/600] Time 0.263 (0.177) Loss 0.268 (0.790) Prec@1 90.000 (70.623)
46 | Test-(16): [500/600] Time 0.142 (0.177) Loss 0.483 (0.786) Prec@1 84.000 (70.683)
47 | * Prec@1 70.890 Best_prec1 69.308
48 | Test accuracy 70.89 h 0.69875926
49 | ===================================== Round 3 =====================================
50 | Testset: 600-------------3
51 | Test-(16): [100/600] Time 0.173 (0.205) Loss 0.882 (0.813) Prec@1 64.000 (69.030)
52 | Test-(16): [200/600] Time 0.105 (0.190) Loss 0.705 (0.787) Prec@1 66.000 (70.109)
53 | Test-(16): [300/600] Time 0.104 (0.185) Loss 0.839 (0.778) Prec@1 70.000 (70.771)
54 | Test-(16): [400/600] Time 0.141 (0.182) Loss 0.532 (0.788) Prec@1 80.000 (70.549)
55 | Test-(16): [500/600] Time 0.160 (0.181) Loss 1.124 (0.784) Prec@1 64.000 (70.762)
56 | * Prec@1 70.733 Best_prec1 69.308
57 | Test accuracy 70.73333 h 0.7160883
58 | ===================================== Round 4 =====================================
59 | Testset: 600-------------4
60 | Test-(16): [100/600] Time 0.212 (0.199) Loss 0.710 (0.803) Prec@1 76.000 (70.495)
61 | Test-(16): [200/600] Time 0.178 (0.185) Loss 0.384 (0.785) Prec@1 90.000 (71.214)
62 | Test-(16): [300/600] Time 0.189 (0.182) Loss 1.127 (0.780) Prec@1 56.000 (70.970)
63 | Test-(16): [400/600] Time 0.250 (0.181) Loss 0.466 (0.774) Prec@1 80.000 (71.082)
64 | Test-(16): [500/600] Time 0.111 (0.177) Loss 1.089 (0.781) Prec@1 62.000 (70.858)
65 | * Prec@1 71.013 Best_prec1 69.308
66 | Test accuracy 71.013336 h 0.71682656
67 | Aver_accuracy: 71.02133 Aver_h 0.31553766
68 |
69 |
--------------------------------------------------------------------------------
/DN4_2019_Version/results/DN4_miniImageNet_Conv64F_5Way_5Shot_K3/model_best.pth.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/DN4_2019_Version/results/DN4_miniImageNet_Conv64F_5Way_5Shot_K3/model_best.pth.tar
--------------------------------------------------------------------------------
/DN4_2019_Version/results/DN4_miniImageNet_ResNet256F_5Way_1Shot_K3/Test_resutls.txt:
--------------------------------------------------------------------------------
1 | Namespace(basemodel='ResNet256F', beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, cuda=True, data_name='miniImageNet', dataset_dir='/localdisk/wli70/FewShot/MultiTask_FewShot-V0/dataset/miniImageNet/miniImageNet--ravi', episodeSize=1, episode_test_num=600, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.005, mode='test', nc=3, neighbor_k=3, ngpu=1, outf='./results/DN4_new_miniImageNet_ResNet256F_5Way_1Shot_K3', print_freq=100, query_num=15, resume='./results/DN4_new_miniImageNet_ResNet256F_5Way_1Shot_K3/model_best.pth.tar', shot_num=1, testepisodeSize=1, way_num=5, workers=8)
2 | => loaded checkpoint './results/DN4_new_miniImageNet_ResNet256F_5Way_1Shot_K3/model_best.pth.tar' (epoch 21)
3 | ResNetLike(
4 | (feat_extractor): Sequential(
5 | (ConvL0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
6 | (ResBlock0): ResBlock(
7 | (conv_block): Sequential(
8 | (BNorm1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
9 | (LRelu1): LeakyReLU(negative_slope=0.2)
10 | (ConvL1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
11 | (BNorm2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
12 | (LRelu2): LeakyReLU(negative_slope=0.2)
13 | (ConvL2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (BNorm3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (LRelu3): LeakyReLU(negative_slope=0.2)
16 | (ConvL3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
17 | )
18 | (skip_layer): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1))
19 | )
20 | (MaxPool0): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
21 | (ResBlock1): ResBlock(
22 | (conv_block): Sequential(
23 | (BNorm1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
24 | (LRelu1): LeakyReLU(negative_slope=0.2)
25 | (ConvL1): Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
26 | (BNorm2): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
27 | (LRelu2): LeakyReLU(negative_slope=0.2)
28 | (ConvL2): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
29 | (BNorm3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
30 | (LRelu3): LeakyReLU(negative_slope=0.2)
31 | (ConvL3): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
32 | )
33 | (skip_layer): Conv2d(64, 96, kernel_size=(1, 1), stride=(1, 1))
34 | )
35 | (MaxPool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
36 | (ResBlock2): ResBlock(
37 | (conv_block): Sequential(
38 | (BNorm1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
39 | (LRelu1): LeakyReLU(negative_slope=0.2)
40 | (ConvL1): Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
41 | (BNorm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
42 | (LRelu2): LeakyReLU(negative_slope=0.2)
43 | (ConvL2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
44 | (BNorm3): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
45 | (LRelu3): LeakyReLU(negative_slope=0.2)
46 | (ConvL3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
47 | )
48 | (skip_layer): Conv2d(96, 128, kernel_size=(1, 1), stride=(1, 1))
49 | )
50 | (ResBlock3): ResBlock(
51 | (conv_block): Sequential(
52 | (BNorm1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
53 | (LRelu1): LeakyReLU(negative_slope=0.2)
54 | (ConvL1): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
55 | (BNorm2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
56 | (LRelu2): LeakyReLU(negative_slope=0.2)
57 | (ConvL2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
58 | (BNorm3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
59 | (LRelu3): LeakyReLU(negative_slope=0.2)
60 | (ConvL3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
61 | )
62 | (skip_layer): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1))
63 | )
64 | (ReluF1): LeakyReLU(negative_slope=0.2, inplace)
65 | )
66 | (indefense): CovaInDefense()
67 | )
68 | ===================================== Round 0 =====================================
69 | Testset: 600-------------0
70 | Test-(21): [100/600] Time 0.171 (0.270) Loss 1.190 (1.144) Prec@1 56.000 (55.406)
71 | Test-(21): [200/600] Time 0.194 (0.250) Loss 1.474 (1.186) Prec@1 52.000 (53.672)
72 | Test-(21): [300/600] Time 0.125 (0.240) Loss 0.996 (1.176) Prec@1 56.000 (54.277)
73 | Test-(21): [400/600] Time 0.304 (0.236) Loss 0.880 (1.173) Prec@1 57.333 (54.081)
74 | Test-(21): [500/600] Time 0.163 (0.234) Loss 1.191 (1.174) Prec@1 57.333 (54.172)
75 | * Prec@1 54.107 Best_prec1 55.108
76 | Test accuracy 54.106667 h 0.81440806
77 | ===================================== Round 1 =====================================
78 | Testset: 600-------------1
79 | Test-(21): [100/600] Time 0.180 (0.232) Loss 1.646 (1.174) Prec@1 33.333 (53.941)
80 | Test-(21): [200/600] Time 0.363 (0.229) Loss 1.564 (1.179) Prec@1 36.000 (53.844)
81 | Test-(21): [300/600] Time 0.116 (0.226) Loss 1.212 (1.196) Prec@1 46.667 (53.085)
82 | Test-(21): [400/600] Time 0.167 (0.222) Loss 1.674 (1.192) Prec@1 37.333 (53.303)
83 | Test-(21): [500/600] Time 0.237 (0.221) Loss 1.183 (1.189) Prec@1 42.667 (53.408)
84 | * Prec@1 53.709 Best_prec1 55.108
85 | Test accuracy 53.708885 h 0.8318296
86 | ===================================== Round 2 =====================================
87 | Testset: 600-------------2
88 | Test-(21): [100/600] Time 0.228 (0.242) Loss 1.240 (1.176) Prec@1 50.667 (53.611)
89 | Test-(21): [200/600] Time 0.241 (0.232) Loss 1.087 (1.148) Prec@1 58.667 (55.171)
90 | Test-(21): [300/600] Time 0.120 (0.230) Loss 1.588 (1.161) Prec@1 45.333 (54.808)
91 | Test-(21): [400/600] Time 0.264 (0.225) Loss 1.097 (1.160) Prec@1 48.000 (54.657)
92 | Test-(21): [500/600] Time 0.239 (0.223) Loss 1.099 (1.159) Prec@1 50.667 (54.752)
93 | * Prec@1 54.771 Best_prec1 55.108
94 | Test accuracy 54.771107 h 0.8287496
95 | ===================================== Round 3 =====================================
96 | Testset: 600-------------3
97 | Test-(21): [100/600] Time 0.150 (0.250) Loss 0.953 (1.153) Prec@1 57.333 (54.125)
98 | Test-(21): [200/600] Time 0.138 (0.236) Loss 0.955 (1.147) Prec@1 64.000 (54.740)
99 | Test-(21): [300/600] Time 0.209 (0.232) Loss 1.115 (1.152) Prec@1 44.000 (54.551)
100 | Test-(21): [400/600] Time 0.124 (0.230) Loss 1.205 (1.145) Prec@1 50.667 (54.856)
101 | Test-(21): [500/600] Time 0.155 (0.230) Loss 1.584 (1.142) Prec@1 41.333 (55.039)
102 | * Prec@1 54.938 Best_prec1 55.108
103 | Test accuracy 54.93778 h 0.8403389
104 | ===================================== Round 4 =====================================
105 | Testset: 600-------------4
106 | Test-(21): [100/600] Time 0.314 (0.240) Loss 1.260 (1.125) Prec@1 49.333 (55.459)
107 | Test-(21): [200/600] Time 0.129 (0.218) Loss 1.045 (1.139) Prec@1 65.333 (55.111)
108 | Test-(21): [300/600] Time 0.333 (0.218) Loss 0.834 (1.151) Prec@1 68.000 (54.653)
109 | Test-(21): [400/600] Time 0.161 (0.218) Loss 2.335 (1.153) Prec@1 34.667 (54.550)
110 | Test-(21): [500/600] Time 0.276 (0.219) Loss 1.044 (1.155) Prec@1 56.000 (54.456)
111 | * Prec@1 54.367 Best_prec1 55.108
112 | Test accuracy 54.36667 h 0.7963865
113 | Aver_accuracy: 54.378223 Aver_h 0.36733297
114 |
115 |
--------------------------------------------------------------------------------
/DN4_2019_Version/results/DN4_miniImageNet_ResNet256F_5Way_5Shot_K3/Test_resutls.txt:
--------------------------------------------------------------------------------
1 | Namespace(basemodel='ResNet256F', beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, cuda=True, data_name='miniImageNet', dataset_dir='/localdisk/wli70/FewShot/MultiTask_FewShot-V0/dataset/miniImageNet/miniImageNet--ravi', episodeSize=1, episode_test_num=600, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.005, mode='test', nc=3, neighbor_k=3, ngpu=1, outf='./results/DN4_new_miniImageNet_ResNet256F_5Way_5Shot_K3', print_freq=100, query_num=10, resume='./results/DN4_new_miniImageNet_ResNet256F_5Way_5Shot_K3/model_best.pth.tar', shot_num=5, testepisodeSize=1, way_num=5, workers=8)
2 | => loaded checkpoint './results/DN4_new_miniImageNet_ResNet256F_5Way_5Shot_K3/model_best.pth.tar' (epoch 25)
3 | ResNetLike(
4 | (feat_extractor): Sequential(
5 | (ConvL0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
6 | (ResBlock0): ResBlock(
7 | (conv_block): Sequential(
8 | (BNorm1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
9 | (LRelu1): LeakyReLU(negative_slope=0.2)
10 | (ConvL1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
11 | (BNorm2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
12 | (LRelu2): LeakyReLU(negative_slope=0.2)
13 | (ConvL2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (BNorm3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (LRelu3): LeakyReLU(negative_slope=0.2)
16 | (ConvL3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
17 | )
18 | (skip_layer): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1))
19 | )
20 | (MaxPool0): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
21 | (ResBlock1): ResBlock(
22 | (conv_block): Sequential(
23 | (BNorm1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
24 | (LRelu1): LeakyReLU(negative_slope=0.2)
25 | (ConvL1): Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
26 | (BNorm2): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
27 | (LRelu2): LeakyReLU(negative_slope=0.2)
28 | (ConvL2): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
29 | (BNorm3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
30 | (LRelu3): LeakyReLU(negative_slope=0.2)
31 | (ConvL3): Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
32 | )
33 | (skip_layer): Conv2d(64, 96, kernel_size=(1, 1), stride=(1, 1))
34 | )
35 | (MaxPool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
36 | (ResBlock2): ResBlock(
37 | (conv_block): Sequential(
38 | (BNorm1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
39 | (LRelu1): LeakyReLU(negative_slope=0.2)
40 | (ConvL1): Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
41 | (BNorm2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
42 | (LRelu2): LeakyReLU(negative_slope=0.2)
43 | (ConvL2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
44 | (BNorm3): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
45 | (LRelu3): LeakyReLU(negative_slope=0.2)
46 | (ConvL3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
47 | )
48 | (skip_layer): Conv2d(96, 128, kernel_size=(1, 1), stride=(1, 1))
49 | )
50 | (ResBlock3): ResBlock(
51 | (conv_block): Sequential(
52 | (BNorm1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
53 | (LRelu1): LeakyReLU(negative_slope=0.2)
54 | (ConvL1): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
55 | (BNorm2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
56 | (LRelu2): LeakyReLU(negative_slope=0.2)
57 | (ConvL2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
58 | (BNorm3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
59 | (LRelu3): LeakyReLU(negative_slope=0.2)
60 | (ConvL3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
61 | )
62 | (skip_layer): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1))
63 | )
64 | (ReluF1): LeakyReLU(negative_slope=0.2, inplace)
65 | )
66 | (indefense): CovaInDefense()
67 | )
68 | ===================================== Round 0 =====================================
69 | Testset: 600-------------0
70 | Test-(25): [100/600] Time 0.166 (0.208) Loss 1.320 (0.678) Prec@1 52.000 (74.733)
71 | Test-(25): [200/600] Time 0.154 (0.192) Loss 0.801 (0.697) Prec@1 70.000 (74.259)
72 | Test-(25): [300/600] Time 0.170 (0.196) Loss 0.993 (0.697) Prec@1 70.000 (74.186)
73 | Test-(25): [400/600] Time 0.184 (0.199) Loss 0.421 (0.696) Prec@1 76.000 (74.219)
74 | Test-(25): [500/600] Time 0.188 (0.199) Loss 0.769 (0.700) Prec@1 66.000 (74.048)
75 | * Prec@1 74.103 Best_prec1 75.458
76 | Test accuracy 74.10333 h 0.6610412
77 | ===================================== Round 1 =====================================
78 | Testset: 600-------------1
79 | Test-(25): [100/600] Time 0.158 (0.225) Loss 0.865 (0.668) Prec@1 64.000 (75.723)
80 | Test-(25): [200/600] Time 0.221 (0.212) Loss 0.561 (0.685) Prec@1 76.000 (75.025)
81 | Test-(25): [300/600] Time 0.219 (0.208) Loss 0.977 (0.690) Prec@1 72.000 (74.777)
82 | Test-(25): [400/600] Time 0.205 (0.207) Loss 0.944 (0.697) Prec@1 62.000 (74.529)
83 | Test-(25): [500/600] Time 0.272 (0.206) Loss 0.402 (0.694) Prec@1 88.000 (74.587)
84 | * Prec@1 74.530 Best_prec1 75.458
85 | Test accuracy 74.53 h 0.6211143
86 | ===================================== Round 2 =====================================
87 | Testset: 600-------------2
88 | Test-(25): [100/600] Time 0.165 (0.219) Loss 0.868 (0.677) Prec@1 72.000 (75.881)
89 | Test-(25): [200/600] Time 0.221 (0.210) Loss 0.434 (0.691) Prec@1 86.000 (75.164)
90 | Test-(25): [300/600] Time 0.220 (0.206) Loss 0.732 (0.701) Prec@1 66.000 (74.711)
91 | Test-(25): [400/600] Time 0.157 (0.205) Loss 1.067 (0.704) Prec@1 58.000 (74.584)
92 | Test-(25): [500/600] Time 0.188 (0.205) Loss 0.786 (0.708) Prec@1 72.000 (74.427)
93 | * Prec@1 74.530 Best_prec1 75.458
94 | Test accuracy 74.53 h 0.6545631
95 | ===================================== Round 3 =====================================
96 | Testset: 600-------------3
97 | Test-(25): [100/600] Time 0.301 (0.225) Loss 0.619 (0.679) Prec@1 78.000 (75.624)
98 | Test-(25): [200/600] Time 0.190 (0.212) Loss 0.605 (0.694) Prec@1 78.000 (74.607)
99 | Test-(25): [300/600] Time 0.155 (0.208) Loss 0.571 (0.689) Prec@1 76.000 (74.950)
100 | Test-(25): [400/600] Time 0.169 (0.209) Loss 0.406 (0.687) Prec@1 86.000 (74.918)
101 | Test-(25): [500/600] Time 0.198 (0.208) Loss 0.608 (0.683) Prec@1 74.000 (75.038)
102 | * Prec@1 74.950 Best_prec1 75.458
103 | Test accuracy 74.95 h 0.6368377
104 | ===================================== Round 4 =====================================
105 | Testset: 600-------------4
106 | Test-(25): [100/600] Time 0.188 (0.231) Loss 0.818 (0.728) Prec@1 74.000 (74.218)
107 | Test-(25): [200/600] Time 0.279 (0.220) Loss 0.806 (0.718) Prec@1 66.000 (73.930)
108 | Test-(25): [300/600] Time 0.304 (0.217) Loss 0.874 (0.726) Prec@1 64.000 (73.821)
109 | Test-(25): [400/600] Time 0.158 (0.213) Loss 0.961 (0.716) Prec@1 64.000 (74.195)
110 | Test-(25): [500/600] Time 0.160 (0.211) Loss 0.266 (0.713) Prec@1 88.000 (74.184)
111 | * Prec@1 74.103 Best_prec1 75.458
112 | Test accuracy 74.10333 h 0.7051564
113 | Aver_accuracy: 74.44334 Aver_h 0.2930813
114 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019, Wenbin Li
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 |
26 | --------------------------- LICENSE FOR DN4 --------------------------------
27 | BSD License
28 |
29 | For DN4 software
30 | Copyright (c) 2019, Wenbin Li
31 | All rights reserved.
32 |
33 | Redistribution and use in source and binary forms, with or without
34 | modification, are permitted provided that the following conditions are met:
35 |
36 | * Redistributions of source code must retain the above copyright notice, this
37 | list of conditions and the following disclaimer.
38 |
39 | * Redistributions in binary form must reproduce the above copyright notice,
40 | this list of conditions and the following disclaimer in the documentation
41 | and/or other materials provided with the distribution.
42 |
43 |
44 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DN4 in PyTorch (2023 Version)
2 |
3 | We provide a PyTorch implementation of DN4 for few-shot learning.
4 | If you use this code, please cite:
5 |
6 | [Revisiting Local Descriptor based Image-to-Class Measure for Few-shot Learning](http://cs.nju.edu.cn/rl/people/liwb/CVPR19.pdf).
7 | [Wenbin Li](https://cs.nju.edu.cn/liwenbin/), Lei Wang, Jinglin Xu, Jing Huo, Yang Gao and Jiebo Luo. In CVPR 2019.
8 |
9 |
10 |
11 | ## Prerequisites
12 | - Linux
13 | - Python 3.8
14 | - Pytorch 1.7.0
15 | - GPU + CUDA CuDNN
16 | - pillow, torchvision, scipy, numpy
17 |
18 | ## Getting Started
19 | ### Installation
20 |
21 | - Clone this repo:
22 | ```bash
23 | git clone https://github.com/WenbinLee/DN4.git
24 | cd DN4
25 | ```
26 |
27 | - Install [PyTorch](http://pytorch.org) 1.7.0 and other dependencies.
28 |
29 | ### Datasets
30 | [Caltech-UCSD Birds-200-2011](https://data.caltech.edu/records/20098), [Standford Cars](https://ai.stanford.edu/~jkrause/cars/car_dataset.html), [Standford Dogs](http://vision.stanford.edu/aditya86/ImageNetDogs/main.html), [*mini*ImageNet](https://arxiv.org/abs/1606.04080v2) and [*tiered*ImageNet](https://arxiv.org/abs/1803.00676) are available at [Google Drive](https://drive.google.com/drive/u/1/folders/1SEoARH5rADckI-_gZSQRkLclrunL-yb0) and [百度网盘(提取码:yr1w)](https://pan.baidu.com/s/1M3jFo2OI5GTOpytxgtO1qA).
31 |
32 |
33 | ### miniImageNet Few-shot Classification
34 | - Train a 5-way 1-shot model based on Conv64:
35 | ```bash
36 | python Train_DN4.py --dataset_dir ./path/to/miniImageNet --data_name miniImageNet --encoder_model Conv64F_Local --way_num 5 --shot_num 1
37 | ```
38 | - Train a 5-way 1-shot model based on ResNet12:
39 | ```bash
40 | python Train_DN4.py --dataset_dir ./path/to/miniImageNet --data_name miniImageNet --encoder_model ResNet12 --way_num 5 --shot_num 1
41 | ```
42 | - Test the model (specify the dataset_dir, encoder_model, and data_name first):
43 | ```bash
44 | python Test_DN4.py --resume ./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/ --encoder_model Conv64F_Local
45 | ```
46 |
47 |
48 | ## Latest results on miniImageNet (2023)
49 | (Compared to the originally reported results in the paper. * denotes that ResNet256F is used.)
50 |
51 |
52 | Method |
53 | Backbone |
54 | 5-way 1-shot |
55 | 5-way 5-shot |
56 |
57 |
58 | 2019 Version |
59 | 2023 Version |
60 | 2019 Version |
61 | 2023 Version |
62 |
63 |
64 |
65 | DN4 |
66 | Conv64F_Local |
67 | 51.24 |
68 | 51.97 |
69 | 71.02 |
70 | 73.19 |
71 |
72 |
73 | ResNet12 |
74 | 54.37* |
75 | 61.23 |
76 | 74.44* |
77 | 75.66 |
78 |
79 |
80 |
81 |
82 |
83 | - The results on the miniImageNet dataset reported in the orinigal paper:
84 |
85 |
86 |
87 |
88 | ## Citation
89 | If you use this code for your research, please cite our paper.
90 | ```
91 | @inproceedings{DN4_CVPR_2019,
92 | author = {Wenbin Li and
93 | Lei Wang and
94 | Jinglin Xu and
95 | Jing Huo and
96 | Yang Gao and
97 | Jiebo Luo},
98 | title = {Revisiting Local Descriptor Based Image-To-Class Measure for Few-Shot Learning},
99 | booktitle = {{IEEE} Conference on Computer Vision and Pattern Recognition (CVPR)},
100 | pages = {7260--7268},
101 | year = {2019}
102 | }
103 | ```
104 |
--------------------------------------------------------------------------------
/Test_DN4.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | Author: Wenbin Li (liwenbin@nju.edu.cn)
6 | Date: June 18, 2023
7 | Version: V5
8 |
9 | Citation:
10 | @inproceedings{DN4_CVPR_2019,
11 | author = {Wenbin Li and
12 | Lei Wang and
13 | Jinglin Xu and
14 | Jing Huo and
15 | Yang Gao and
16 | Jiebo Luo},
17 | title = {Revisiting Local Descriptor Based Image-To-Class Measure for Few-Shot Learning},
18 | booktitle = {{IEEE} Conference on Computer Vision and Pattern Recognition (CVPR)},
19 | pages = {7260--7268},
20 | year = {2019}
21 | }
22 | """
23 |
24 | from __future__ import print_function
25 | import argparse
26 | import os
27 | import random
28 | import shutil
29 | import numpy as np
30 | import torch
31 | import torch.nn as nn
32 | import torch.nn.parallel
33 | import torch.backends.cudnn as cudnn
34 | import torch.optim as optim
35 | import torch.utils.data
36 | import torchvision.datasets as dset
37 | import torchvision.transforms as transforms
38 | import torchvision.utils as vutils
39 | from torch.autograd import grad
40 | import time
41 | from torch import autograd
42 | from PIL import ImageFile
43 | import pdb
44 | import copy
45 | import sys
46 | sys.dont_write_bytecode = True
47 |
48 |
49 | # ============================ Data & Networks =====================================
50 | import dataset.general_dataloader as FewShotDataloader
51 | import models.network as FewShotNet
52 | import utils
53 | # ==================================================================================
54 |
55 |
56 | ImageFile.LOAD_TRUNCATED_IMAGES = True
57 | os.environ['CUDA_DEVICE_ORDER']='PCI_BUS_ID'
58 | os.environ['CUDA_VISIBLE_DEVICES']='6'
59 |
60 |
61 | model_trained = './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/'
62 |
63 |
64 | parser = argparse.ArgumentParser()
65 | parser.add_argument('--dataset_dir', default='/data1/Liwenbin/Datasets/miniImageNet--ravi', help='/miniImageNet--ravi')
66 | parser.add_argument('--data_name', default='miniImageNet', help='miniImageNet|StanfordDog|StanfordCar|CubBird_2011')
67 | parser.add_argument('--mode', default='test', help='train|val|test')
68 | parser.add_argument('--outf', default='./results/')
69 | parser.add_argument('--resume', default=model_trained, type=str, help='path to the lastest checkpoint (default: none)')
70 | parser.add_argument('--encoder_model', default='Conv64F_Local', help='Conv64F|Conv64F_Local')
71 | parser.add_argument('--classifier_model', default='DN4', help='ProtoNet|DN4')
72 | parser.add_argument('--workers', type=int, default=4)
73 | parser.add_argument('--imageSize', type=int, default=84)
74 | parser.add_argument('--train_aug', action='store_true', default=True, help='Perform data augmentation or not during training')
75 | parser.add_argument('--test_aug', action='store_true', default=False, help='Perform data augmentation or not during test')
76 | # Few-shot parameters #
77 | parser.add_argument('--episodeSize', type=int, default=1, help='the mini-batch size of training')
78 | parser.add_argument('--testepisodeSize', type=int, default=1, help='one episode is taken as a mini-batch')
79 | parser.add_argument('--epochs', type=int, default=30, help='the total number of training epoch')
80 | parser.add_argument('--start_epoch', default=0, type=int, help='manual epoch number (useful on restarts)')
81 | parser.add_argument('--episode_train_num', type=int, default=10000, help='the total number of training episodes')
82 | parser.add_argument('--episode_val_num', type=int, default=1000, help='the total number of evaluation episodes')
83 | parser.add_argument('--episode_test_num', type=int, default=1000, help='the total number of testing episodes')
84 | parser.add_argument('--way_num', type=int, default=5, help='the number of way/class')
85 | parser.add_argument('--shot_num', type=int, default=1, help='the number of shot')
86 | parser.add_argument('--query_num', type=int, default=15, help='the number of queries')
87 | parser.add_argument('--aug_shot_num', type=int, default=20, help='the number of augmented support images of each class during test')
88 | parser.add_argument('--neighbor_k', type=int, default=3, help='the number of k-nearest neighbors')
89 | # Other parameters #
90 | parser.add_argument('--lr', type=float, default=0.05, help='initial learning rate')
91 | parser.add_argument('--cosine', type=bool, default=True, help='using cosine annealing')
92 | parser.add_argument('--lr_decay_epochs', type=list, default=[60,80], help='where to decay lr, can be a list')
93 | parser.add_argument('--lr_decay_rate', type=float, default=0.1, help='decay rate for learning rate')
94 | parser.add_argument('--weight_decay', type=float, default=5e-4, help='weight decay')
95 | parser.add_argument('--momentum', type=float, default=0.9, help='momentum')
96 | parser.add_argument('--adam', action='store_true', default=False, help='use adam optimizer')
97 | parser.add_argument('--beta1', type=float, default=0.5, help='beta1 for adam. default=0.5')
98 | parser.add_argument('--cuda', action='store_true', default=True, help='enables cuda')
99 | parser.add_argument('--ngpu', type=int, default=1, help='the number of gpus')
100 | parser.add_argument('--nc', type=int, default=3, help='input image channels')
101 | parser.add_argument('--clamp_lower', type=float, default=-0.01)
102 | parser.add_argument('--clamp_upper', type=float, default=0.01)
103 | parser.add_argument('--print_freq', '-p', default=100, type=int, help='print frequency (default: 100)')
104 | opt = parser.parse_args()
105 | opt.cuda = True
106 | cudnn.benchmark = True
107 |
108 |
109 |
110 | # ======================================= Define Test Function =============================================
111 | def test(test_loader, model, criterion, epoch_index, best_prec1, F_txt):
112 | batch_time = utils.AverageMeter()
113 | losses = utils.AverageMeter()
114 | top1 = utils.AverageMeter()
115 |
116 |
117 | # switch to evaluate mode
118 | model.eval()
119 | accuracies = []
120 |
121 | end = time.time()
122 | for episode_index, (query_images, query_targets, support_images, support_targets) in enumerate(test_loader):
123 |
124 |
125 | # Convert query and support images
126 | input_var1 = torch.cat(query_images, 0).cuda()
127 | input_var2 = torch.cat(support_images, 0).squeeze(0).cuda()
128 | input_var2 = input_var2.contiguous().view(-1, input_var2.size(2), input_var2.size(3), input_var2.size(4))
129 |
130 |
131 | # Deal with the targets
132 | target = torch.cat(query_targets, 0).cuda()
133 |
134 |
135 | # Calculate the output
136 | output = model(input_var1, input_var2)
137 | loss = criterion(output, target)
138 |
139 |
140 | # Measure accuracy and record loss
141 | prec1, _ = utils.accuracy(output, target, topk=(1,3))
142 | losses.update(loss.item(), target.size(0))
143 | top1.update(prec1[0], target.size(0))
144 | accuracies.append(prec1)
145 |
146 |
147 | # measure elapsed time
148 | batch_time.update(time.time() - end)
149 | end = time.time()
150 |
151 |
152 | #============== print the intermediate results ==============#
153 | if episode_index % opt.print_freq == 0 and episode_index != 0:
154 |
155 | print('Test-({0}): [{1}/{2}]\t'
156 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
157 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
158 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
159 | epoch_index, episode_index, len(test_loader), batch_time=batch_time, loss=losses, top1=top1))
160 |
161 | print('Test-({0}): [{1}/{2}]\t'
162 | 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
163 | 'Loss {loss.val:.3f} ({loss.avg:.3f})\t'
164 | 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})'.format(
165 | epoch_index, episode_index, len(test_loader), batch_time=batch_time, loss=losses, top1=top1), file=F_txt)
166 |
167 |
168 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1))
169 | print(' * Prec@1 {top1.avg:.3f} Best_prec1 {best_prec1:.3f}'.format(top1=top1, best_prec1=best_prec1), file=F_txt)
170 |
171 | return top1.avg, losses.avg, accuracies
172 |
173 |
174 |
175 | if __name__=='__main__':
176 |
177 | model = FewShotNet.define_model(encoder_model=opt.encoder_model, classifier_model=opt.classifier_model, norm='batch',
178 | way_num=opt.way_num, shot_num=opt.shot_num, init_type='normal', use_gpu=opt.cuda)
179 |
180 | # define loss function (criterion) and optimizer
181 | criterion = nn.CrossEntropyLoss().cuda()
182 |
183 | # ============================================ Test phase ============================================
184 | # Set the save path
185 | opt.outf, F_txt_test = utils.set_save_test_path2(opt)
186 | print('========================================== Start Test ==========================================\n')
187 | print('========================================== Start Test ==========================================\n', file=F_txt_test)
188 |
189 | # Load the trained best model
190 | best_model_path = os.path.join(opt.resume, 'model_best.pth.tar')
191 | checkpoint = utils.get_resume_file(best_model_path, F_txt_test)
192 | epoch_index = checkpoint['epoch_index']
193 | best_prec1 = checkpoint['best_prec1']
194 | model.load_state_dict(checkpoint['model'])
195 |
196 |
197 | # print the parameters and architecture of the model
198 | print(opt)
199 | print(opt, file=F_txt_test)
200 |
201 |
202 | # Repeat five times
203 | repeat_num = 5
204 | total_accuracy = 0.0
205 | total_h = np.zeros(repeat_num)
206 | for r in range(repeat_num):
207 |
208 | print('==================== The %d-th round ====================' %r)
209 | print('==================== The %d-th round ====================' %r, file=F_txt_test)
210 |
211 | # ======================================= Loaders of Datasets =======================================
212 | _, _, test_loader = FewShotDataloader.get_Fewshot_dataloader(opt, ['train', 'val', 'test'])
213 |
214 |
215 | # evaluate on validation/test set
216 | with torch.no_grad():
217 | prec1, test_loss, accuracies = test(test_loader, model, criterion, epoch_index, best_prec1, F_txt_test)
218 | test_accuracy, h = utils.mean_confidence_interval(accuracies)
219 | total_accuracy += test_accuracy
220 | total_h[r] = h
221 |
222 | print('Test accuracy: %f h: %f \n' %(test_accuracy, h))
223 | print('Test accuracy: %f h: %f \n' %(test_accuracy, h), file=F_txt_test)
224 | print('Mean_accuracy: %f h: %f' %(total_accuracy/repeat_num, total_h.mean()))
225 | print('Mean_accuracy: %f h: %f' %(total_accuracy/repeat_num, total_h.mean()), file=F_txt_test)
226 | print('===================================== Test is END =====================================\n')
227 | print('===================================== Test is END =====================================\n', file=F_txt_test)
228 | F_txt_test.close()
--------------------------------------------------------------------------------
/dataset/Prepare_csv_CubBird.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/CUB_birds' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/CUB_birds/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'images')
25 | train_class_num = 130
26 | val_class_num = 20
27 | test_class_num = 50
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(200)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/dataset/Prepare_csv_StanfordCar.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/Stanford_cars' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/Stanford_cars/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'images')
25 | train_class_num = 130
26 | val_class_num = 17
27 | test_class_num = 49
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(196)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/dataset/Prepare_csv_StanfordDog.py:
--------------------------------------------------------------------------------
1 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 | ## Created by: Wenbin Li
3 | ## Date: Dec. 16 2018
4 | ##
5 | ## Divide data into train/val/test in a csv version
6 | ## Output: train.csv, val.csv, test.csv
7 | ##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | import os
10 | import csv
11 | import numpy as np
12 | import random
13 | from PIL import Image
14 | import pdb
15 |
16 |
17 | data_dir = '/FewShot/Datasets/Stanford_dogs' # the path of the download dataset
18 | save_dir = '/FewShot/Datasets/Stanford_dogs/For_FewShot' # the saving path of the divided dataset
19 |
20 |
21 | if not os.path.exists(os.path.join(save_dir, 'images')):
22 | os.makedirs(os.path.join(save_dir, 'images'))
23 |
24 | images_dir = os.path.join(data_dir, 'Images')
25 | train_class_num = 70
26 | val_class_num = 20
27 | test_class_num = 30
28 |
29 |
30 |
31 | # get all the dog classes
32 | classes_list = [class_name for class_name in os.listdir(images_dir) if os.path.isdir(os.path.join(images_dir, class_name))]
33 |
34 |
35 | # divide the train/val/test set
36 | random.seed(120)
37 | train_list = random.sample(classes_list, train_class_num)
38 | remain_list = [rem for rem in classes_list if rem not in train_list]
39 | val_list = random.sample(remain_list, val_class_num)
40 | test_list = [rem for rem in remain_list if rem not in val_list]
41 |
42 |
43 | # save data into csv file----- Train
44 | train_data = []
45 | for class_name in train_list:
46 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
47 | train_data.extend(images)
48 | print('Train----%s' %class_name)
49 |
50 | # read images and store these images
51 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
52 | for index, img_path in enumerate(img_paths):
53 | img = Image.open(img_path)
54 | img = img.convert('RGB')
55 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
56 |
57 |
58 | with open(os.path.join(save_dir, 'train.csv'), 'w') as csvfile:
59 | writer = csv.writer(csvfile)
60 |
61 | writer.writerow(['filename', 'label'])
62 | writer.writerows(train_data)
63 |
64 |
65 |
66 |
67 | # save data into csv file----- Val
68 | val_data = []
69 | for class_name in val_list:
70 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
71 | val_data.extend(images)
72 | print('Val----%s' %class_name)
73 |
74 | # read images and store these images
75 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
76 | for index, img_path in enumerate(img_paths):
77 | img = Image.open(img_path)
78 | img = img.convert('RGB')
79 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
80 |
81 | with open(os.path.join(save_dir, 'val.csv'), 'w') as csvfile:
82 | writer = csv.writer(csvfile)
83 |
84 | writer.writerow(['filename', 'label'])
85 | writer.writerows(val_data)
86 |
87 |
88 |
89 |
90 | # save data into csv file----- Test
91 | test_data = []
92 | for class_name in test_list:
93 | images = [[i, class_name] for i in os.listdir(os.path.join(images_dir, class_name))]
94 | test_data.extend(images)
95 | print('Test----%s' %class_name)
96 |
97 | # read images and store these images
98 | img_paths = [os.path.join(images_dir, class_name, i) for i in os.listdir(os.path.join(images_dir, class_name))]
99 | for index, img_path in enumerate(img_paths):
100 | img = Image.open(img_path)
101 | img = img.convert('RGB')
102 | img.save(os.path.join(save_dir, 'images', images[index][0]), quality=100)
103 |
104 |
105 | with open(os.path.join(save_dir, 'test.csv'), 'w') as csvfile:
106 | writer = csv.writer(csvfile)
107 |
108 | writer.writerow(['filename', 'label'])
109 | writer.writerows(test_data)
110 |
--------------------------------------------------------------------------------
/models/classifier.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | from torch.nn import init
4 | import numpy as np
5 | import torch.nn.functional as F
6 | import utils
7 | import pdb
8 | from abc import abstractmethod
9 | from torch.nn.utils.weight_norm import WeightNorm
10 |
11 |
12 |
13 | # =========================== Few-shot learning method: ProtoNet =========================== #
14 | class Prototype_Metric(nn.Module):
15 | '''
16 | The classifier module of ProtoNet by using the mean prototype and Euclidean distance,
17 | which is also Non-parametric.
18 | "Prototypical networks for few-shot learning. NeurIPS 2017."
19 | '''
20 | def __init__(self, way_num=5, shot_num=5, neighbor_k=3):
21 | super(Prototype_Metric, self).__init__()
22 | self.way_num = way_num
23 | self.avgpool = nn.AdaptiveAvgPool2d(1)
24 |
25 |
26 | # Calculate the Euclidean distance between the query and the mean prototype of the support class.
27 | def cal_EuclideanDis(self, input1, input2):
28 | '''
29 | input1 (query images): 75 * 64 * 5 * 5
30 | input2 (support set): 25 * 64 * 5 * 5
31 | '''
32 |
33 | # input1---query images
34 | # query = input1.view(input1.size(0), -1) # 75 * 1600 (Conv64F)
35 | query = self.avgpool(input1).squeeze(3).squeeze(2) # 75 * 64
36 | query = query.unsqueeze(1) # 75 * 1 * 1600 (Conv64F)
37 |
38 |
39 | # input2--support set
40 | input2 = self.avgpool(input2).squeeze(3).squeeze(2) # 25 * 64
41 | # input2 = input2.view(input2.size(0), -1) # 25 * 1600
42 | support_set = input2.contiguous().view(self.way_num, -1, input2.size(1)) # 5 * 5 * 1600
43 | support_set = torch.mean(support_set, 1) # 5 * 1600
44 |
45 |
46 | # Euclidean distances between a query set and a support set
47 | proto_dis = -torch.pow(query-support_set, 2).sum(2) # 75 * 5
48 |
49 |
50 | return proto_dis
51 |
52 |
53 | def forward(self, x1, x2):
54 |
55 | proto_dis = self.cal_EuclideanDis(x1, x2)
56 |
57 | return proto_dis
58 |
59 |
60 |
61 | # =========================== Few-shot learning method: DN4 =========================== #
62 | class ImgtoClass_Metric(nn.Module):
63 | '''
64 | Image-to-class classifier module for DN4, which is a Non-parametric classifier.
65 | "Revisiting local descriptor based image-to-class measure for few-shot learning. CVPR 2019."
66 | '''
67 | def __init__(self, way_num=5, shot_num=5, neighbor_k=3):
68 | super(ImgtoClass_Metric, self).__init__()
69 | self.neighbor_k = neighbor_k
70 | self.shot_num = shot_num
71 |
72 |
73 | # Calculate the Image-to-class similarity between the query and support class via k-NN.
74 | def cal_cosinesimilarity(self, input1, input2):
75 | '''
76 | input1 (query images): 75 * 64 * 21 * 21
77 | input2 (support set): 25 * 64 * 21 * 21
78 | '''
79 |
80 | # input1---query images
81 | input1 = input1.contiguous().view(input1.size(0), input1.size(1), -1) # 75 * 64 * 441 (Conv64F_Local)
82 | input1 = input1.permute(0, 2, 1) # 75 * 441 * 64 (Conv64F_Local)
83 |
84 |
85 | # input2--support set
86 | input2 = input2.contiguous().view(input2.size(0), input2.size(1), -1) # 25 * 64 * 441
87 | input2 = input2.permute(0, 2, 1) # 25 * 441 * 64
88 |
89 |
90 | # L2 Normalization
91 | input1_norm = torch.norm(input1, 2, 2, True) # 75 * 441 * 1
92 | query = input1/input1_norm # 75 * 441 * 64
93 | query = query.unsqueeze(1) # 75 * 1 * 441 *64
94 |
95 |
96 | input2_norm = torch.norm(input2, 2, 2, True) # 25 * 441 * 1
97 | support_set = input2/input2_norm # 25 * 441 * 64
98 | support_set = support_set.contiguous().view(-1,
99 | self.shot_num*support_set.size(1), support_set.size(2)) # 5 * 2205 * 64
100 | support_set = support_set.permute(0, 2, 1) # 5 * 64 * 2205
101 |
102 |
103 | # cosine similarity between a query set and a support set
104 | innerproduct_matrix = torch.matmul(query, support_set) # 75 * 5 * 441 * 2205
105 |
106 |
107 | # choose the top-k nearest neighbors
108 | topk_value, topk_index = torch.topk(innerproduct_matrix, self.neighbor_k, 3) # 75 * 5 * 441 * 3
109 | img2class_sim = torch.sum(torch.sum(topk_value, 3), 2) # 75 * 5
110 |
111 |
112 | return img2class_sim
113 |
114 |
115 | def forward(self, x1, x2):
116 |
117 | img2class_sim = self.cal_cosinesimilarity(x1, x2)
118 |
119 | return img2class_sim
120 |
--------------------------------------------------------------------------------
/models/network.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | from torch.nn import init
4 | import numpy as np
5 | import functools
6 | import random
7 | import pdb
8 | import copy
9 | import sys
10 | sys.dont_write_bytecode = True
11 |
12 |
13 |
14 | # ============================ Backbone & Classifier ===============================
15 | import models.backbone as backbone
16 | import models.classifier as classifier
17 | from sklearn import metrics
18 | from sklearn.linear_model import LogisticRegression
19 | # ==================================================================================
20 | '''
21 | All models consist of two parts: backbone module and classifier module.
22 | '''
23 |
24 |
25 | ###############################################################################
26 | # Functions
27 | ###############################################################################
28 |
29 | encoder_dict = dict(
30 | Conv64F = backbone.Conv64F,
31 | Conv64F_Local = backbone.Conv64F_Local,
32 | ResNet10 = backbone.ResNet10,
33 | ResNet12 = backbone.ResNet12,
34 | SeResNet12 = backbone.SeResNet12,
35 | ResNet18 = backbone.ResNet18,
36 | ResNet34 = backbone.ResNet34,
37 | ResNet50 = backbone.ResNet50,
38 | ResNet101 = backbone.ResNet101)
39 |
40 |
41 | classifier_dict = dict(
42 | ProtoNet = classifier.Prototype_Metric,
43 | DN4 = classifier.ImgtoClass_Metric)
44 |
45 |
46 |
47 | def weights_init_normal(m):
48 | classname = m.__class__.__name__
49 | # pdb.set_trace()
50 | # print(classname)
51 | if classname.find('Conv') != -1:
52 | init.normal_(m.weight.data, 0.0, 0.02)
53 | elif classname.find('Linear') != -1:
54 | init.normal_(m.weight.data, 0.0, 0.02)
55 | elif classname.find('BatchNorm2d') != -1:
56 | init.normal_(m.weight.data, 1.0, 0.02)
57 | init.constant_(m.bias.data, 0.0)
58 |
59 |
60 | def weights_init_xavier(m):
61 | classname = m.__class__.__name__
62 | # print(classname)
63 | if classname.find('Conv') != -1:
64 | init.xavier_normal_(m.weight.data, gain=0.02)
65 | elif classname.find('Linear') != -1:
66 | init.xavier_normal_(m.weight.data, gain=0.02)
67 | elif classname.find('BatchNorm2d') != -1:
68 | init.normal_(m.weight.data, 1.0, 0.02)
69 | init.constant_(m.bias.data, 0.0)
70 |
71 |
72 | def weights_init_kaiming(m):
73 | classname = m.__class__.__name__
74 | # print(classname)
75 | if classname.find('Conv') != -1:
76 | init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
77 | elif classname.find('Linear') != -1:
78 | init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
79 | elif classname.find('BatchNorm2d') != -1:
80 | init.normal_(m.weight.data, 1.0, 0.02)
81 | init.constant_(m.bias.data, 0.0)
82 |
83 |
84 | def weights_init_orthogonal(m):
85 | classname = m.__class__.__name__
86 | print(classname)
87 | if classname.find('Conv') != -1:
88 | init.orthogonal_(m.weight.data, gain=1)
89 | elif classname.find('Linear') != -1:
90 | init.orthogonal_(m.weight.data, gain=1)
91 | elif classname.find('BatchNorm2d') != -1:
92 | init.normal_(m.weight.data, 1.0, 0.02)
93 | init.constant_(m.bias.data, 0.0)
94 |
95 |
96 | def init_weights(net, init_type='normal'):
97 | print('initialization method [%s]' % init_type)
98 | if init_type == 'normal':
99 | net.apply(weights_init_normal)
100 | elif init_type == 'xavier':
101 | net.apply(weights_init_xavier)
102 | elif init_type == 'kaiming':
103 | net.apply(weights_init_kaiming)
104 | elif init_type == 'orthogonal':
105 | net.apply(weights_init_orthogonal)
106 | else:
107 | raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
108 |
109 |
110 | def get_norm_layer(norm_type='instance'):
111 | if norm_type == 'batch':
112 | norm_layer = functools.partial(nn.BatchNorm2d, affine=True)
113 | elif norm_type == 'instance':
114 | norm_layer = functools.partial(nn.InstanceNorm2d, affine=False)
115 | elif norm_type == 'none':
116 | norm_layer = None
117 | else:
118 | raise NotImplementedError('normalization layer [%s] is not found' % norm_type)
119 | return norm_layer
120 |
121 |
122 | def print_network(net):
123 | num_params = 0
124 | for param in net.parameters():
125 | num_params += param.numel()
126 |
127 | print('Total number of parameters: %d' % num_params)
128 |
129 |
130 |
131 | def define_model(pretrained=False, model_root=None, encoder_model='Conv64F', classifier_model='DN4', norm='batch', init_type='normal', use_gpu=True, **kwargs):
132 | model = None
133 | norm_layer = get_norm_layer(norm_type=norm)
134 |
135 | if use_gpu:
136 | assert(torch.cuda.is_available())
137 |
138 | if classifier_model in ['ProtoNet', 'DN4']:
139 | model = Fewshot_model(encoder_model=encoder_model, classifier_model=classifier_model, **kwargs)
140 |
141 | else:
142 | raise NotImplementedError('Model name [%s] is not recognized' % classifier_model)
143 |
144 | # init_weights(model, init_type=init_type)
145 | print_network(model)
146 |
147 | if use_gpu:
148 | model.cuda()
149 |
150 | if pretrained:
151 | model.load_state_dict(model_root)
152 |
153 | return model
154 |
155 |
156 |
157 |
158 | class Fewshot_model(nn.Module):
159 | '''
160 | Define a few-shot learning model, which consists of an embedding module and a classifier moduel.
161 | '''
162 | def __init__(self, encoder_model='Conv64F', classifier_model='DN4', class_num=64, way_num=5, shot_num=5, query_num=10, neighbor_k=3):
163 | super(Fewshot_model, self).__init__()
164 | self.encoder_model = encoder_model
165 | self.classifier_model = classifier_model
166 | self.way_num = way_num
167 | self.shot_num = shot_num
168 | self.query_num = query_num
169 | self.neighbor_k = neighbor_k
170 | self.loss_type = 'softmax'
171 |
172 | if encoder_model == 'Conv64F':
173 | self.feature_dim = 64
174 | elif encoder_model == 'Conv64F_Local':
175 | self.feature_dim = 64
176 | elif encoder_model in ['ResNet10', 'ResNet18', 'ResNet34']:
177 | self.feature_dim = 512
178 | elif encoder_model in ['ResNet12', 'SeResNet12']:
179 | self.feature_dim = 640
180 | elif encoder_model in ['ResNet50', 'ResNet101']:
181 | self.feature_dim = 2048
182 |
183 | encoder_module = encoder_dict[self.encoder_model]
184 | classifier_module = classifier_dict[self.classifier_model]
185 |
186 | self.features = encoder_module()
187 | self.classifier = classifier_module(way_num=self.way_num, shot_num=self.shot_num, neighbor_k=self.neighbor_k)
188 |
189 |
190 | for m in self.modules():
191 | if isinstance(m, nn.Conv1d):
192 | init.normal_(m.weight.data, 0.0, 0.02)
193 | elif isinstance(m, nn.Linear):
194 | init.normal_(m.weight.data, 0.0, 0.02)
195 | elif isinstance(m, nn.BatchNorm2d):
196 | init.normal_(m.weight.data, 1.0, 0.02)
197 | init.constant_(m.bias.data, 0.0)
198 |
199 |
200 | def forward(self, input1, input2, is_feature=False):
201 |
202 | # pdb.set_trace()
203 | x1 = self.features(input1) # query: 75 * 64 * 21 * 21
204 | x2 = self.features(input2) # support set: 25 * 64 * 21 * 21
205 |
206 | out = self.classifier(x1, x2)
207 |
208 | if is_feature:
209 | return x1, x2, out
210 | else:
211 | return out
212 |
213 |
214 | class Model_with_reused_Encoder(nn.Module):
215 | '''
216 | Construct a new few-shot model by reusing a pre-trained embedding module.
217 | '''
218 | def __init__(self, pre_trained_model, new_classifier='DN4', way_num=5, shot_num=5, neighbor_k=3):
219 | super(Model_with_reused_Encoder, self).__init__()
220 | self.way_num = way_num
221 | self.shot_num = shot_num
222 | self.neighbor_k = neighbor_k
223 | self.model = pre_trained_model
224 |
225 | # Only use the features module
226 | self.features = nn.Sequential(
227 | *list(self.model.features.children())
228 | )
229 |
230 | classifier_module = classifier_dict[new_classifier]
231 | self.classifier = classifier_module(way_num=self.way_num, shot_num=self.shot_num, neighbor_k=self.neighbor_k)
232 |
233 |
234 | def forward(self, input1, input2):
235 |
236 | # pdb.set_trace()
237 | x1 = self.features(input1)
238 | x2 = self.features(input2)
239 | out = self.classifier(x1, x2)
240 |
241 | return out
242 |
243 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/Loss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/Loss.png
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/Test_results.txt:
--------------------------------------------------------------------------------
1 | ========================================== Start Test ==========================================
2 |
3 | => loading checkpoint './results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar'
4 | => loaded checkpoint './results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar' (epoch 28)
5 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, current_epoch=29, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='ResNet12', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.01, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='train', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot', print_freq=100, query_num=15, resume='', shot_num=1, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
6 | Fewshot_model(
7 | (features): ResNet_84(
8 | (layer1): Sequential(
9 | (0): BasicBlock(
10 | (conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
11 | (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
12 | (relu): LeakyReLU(negative_slope=0.1)
13 | (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (conv3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
16 | (bn3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
17 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
18 | (downsample): Sequential(
19 | (0): Conv2d(3, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
20 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
21 | )
22 | (DropBlock): DropBlock()
23 | )
24 | )
25 | (layer2): Sequential(
26 | (0): BasicBlock(
27 | (conv1): Conv2d(64, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
28 | (bn1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
29 | (relu): LeakyReLU(negative_slope=0.1)
30 | (conv2): Conv2d(160, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
31 | (bn2): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
32 | (conv3): Conv2d(160, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
33 | (bn3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
34 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
35 | (downsample): Sequential(
36 | (0): Conv2d(64, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
37 | (1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
38 | )
39 | (DropBlock): DropBlock()
40 | )
41 | )
42 | (layer3): Sequential(
43 | (0): BasicBlock(
44 | (conv1): Conv2d(160, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
45 | (bn1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
46 | (relu): LeakyReLU(negative_slope=0.1)
47 | (conv2): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
48 | (bn2): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
49 | (conv3): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
50 | (bn3): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
51 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
52 | (downsample): Sequential(
53 | (0): Conv2d(160, 320, kernel_size=(1, 1), stride=(1, 1), bias=False)
54 | (1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
55 | )
56 | (DropBlock): DropBlock()
57 | )
58 | )
59 | (layer4): Sequential(
60 | (0): BasicBlock(
61 | (conv1): Conv2d(320, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
62 | (bn1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
63 | (relu): LeakyReLU(negative_slope=0.1)
64 | (conv2): Conv2d(640, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
65 | (bn2): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
66 | (conv3): Conv2d(640, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
67 | (bn3): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
68 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
69 | (downsample): Sequential(
70 | (0): Conv2d(320, 640, kernel_size=(1, 1), stride=(1, 1), bias=False)
71 | (1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
72 | )
73 | (DropBlock): DropBlock()
74 | )
75 | )
76 | )
77 | (classifier): ImgtoClass_Metric()
78 | )
79 | ==================== The 0-th round ====================
80 | Val-(28): [100/1000] Time 0.05 (0.10) Loss 1.22 (1.05) Prec@1 54.67 (61.43)
81 | Val-(28): [200/1000] Time 0.05 (0.09) Loss 0.88 (1.07) Prec@1 66.67 (60.48)
82 | Val-(28): [300/1000] Time 0.13 (0.09) Loss 1.69 (1.06) Prec@1 46.67 (60.99)
83 | Val-(28): [400/1000] Time 0.05 (0.09) Loss 1.24 (1.07) Prec@1 65.33 (61.02)
84 | Val-(28): [500/1000] Time 0.05 (0.09) Loss 0.84 (1.07) Prec@1 68.00 (60.71)
85 | Val-(28): [600/1000] Time 0.36 (0.09) Loss 0.91 (1.07) Prec@1 66.67 (60.80)
86 | Val-(28): [700/1000] Time 0.05 (0.09) Loss 0.93 (1.06) Prec@1 62.67 (60.78)
87 | Val-(28): [800/1000] Time 0.05 (0.09) Loss 0.94 (1.07) Prec@1 64.00 (60.58)
88 | Val-(28): [900/1000] Time 0.32 (0.09) Loss 0.76 (1.06) Prec@1 70.67 (60.74)
89 | * Prec@1 60.87 Best_prec1 65.43
90 | Test accuracy: 60.868000 h: 0.637646
91 |
92 | ==================== The 1-th round ====================
93 | Val-(28): [100/1000] Time 0.21 (0.10) Loss 0.76 (1.04) Prec@1 70.67 (61.50)
94 | Val-(28): [200/1000] Time 0.05 (0.10) Loss 1.00 (1.02) Prec@1 60.00 (61.67)
95 | Val-(28): [300/1000] Time 0.05 (0.09) Loss 0.99 (1.03) Prec@1 69.33 (61.46)
96 | Val-(28): [400/1000] Time 0.10 (0.09) Loss 1.13 (1.03) Prec@1 54.67 (61.54)
97 | Val-(28): [500/1000] Time 0.18 (0.09) Loss 1.08 (1.03) Prec@1 60.00 (61.27)
98 | Val-(28): [600/1000] Time 0.05 (0.09) Loss 1.33 (1.04) Prec@1 48.00 (61.21)
99 | Val-(28): [700/1000] Time 0.05 (0.09) Loss 0.81 (1.04) Prec@1 66.67 (61.05)
100 | Val-(28): [800/1000] Time 0.05 (0.09) Loss 0.81 (1.04) Prec@1 68.00 (61.04)
101 | Val-(28): [900/1000] Time 0.05 (0.09) Loss 1.61 (1.04) Prec@1 40.00 (61.05)
102 | * Prec@1 61.27 Best_prec1 65.43
103 | Test accuracy: 61.273331 h: 0.623978
104 |
105 | ==================== The 2-th round ====================
106 | Val-(28): [100/1000] Time 0.05 (0.10) Loss 1.26 (1.07) Prec@1 60.00 (60.48)
107 | Val-(28): [200/1000] Time 0.05 (0.10) Loss 0.73 (1.05) Prec@1 70.67 (61.12)
108 | Val-(28): [300/1000] Time 0.05 (0.09) Loss 1.11 (1.04) Prec@1 56.00 (61.37)
109 | Val-(28): [400/1000] Time 0.05 (0.09) Loss 1.07 (1.04) Prec@1 64.00 (61.43)
110 | Val-(28): [500/1000] Time 0.05 (0.09) Loss 0.80 (1.04) Prec@1 62.67 (61.51)
111 | Val-(28): [600/1000] Time 0.05 (0.09) Loss 1.22 (1.04) Prec@1 58.67 (61.49)
112 | Val-(28): [700/1000] Time 0.05 (0.09) Loss 0.96 (1.04) Prec@1 66.67 (61.38)
113 | Val-(28): [800/1000] Time 0.05 (0.09) Loss 0.76 (1.04) Prec@1 70.67 (61.50)
114 | Val-(28): [900/1000] Time 0.05 (0.09) Loss 1.78 (1.04) Prec@1 40.00 (61.45)
115 | * Prec@1 61.63 Best_prec1 65.43
116 | Test accuracy: 61.627998 h: 0.610496
117 |
118 | ==================== The 3-th round ====================
119 | Val-(28): [100/1000] Time 0.08 (0.09) Loss 1.08 (1.06) Prec@1 50.67 (60.48)
120 | Val-(28): [200/1000] Time 0.19 (0.09) Loss 0.98 (1.05) Prec@1 64.00 (61.27)
121 | Val-(28): [300/1000] Time 0.05 (0.09) Loss 1.23 (1.04) Prec@1 64.00 (61.29)
122 | Val-(28): [400/1000] Time 0.05 (0.09) Loss 0.85 (1.04) Prec@1 72.00 (61.25)
123 | Val-(28): [500/1000] Time 0.05 (0.09) Loss 1.09 (1.05) Prec@1 53.33 (61.10)
124 | Val-(28): [600/1000] Time 0.05 (0.09) Loss 1.08 (1.05) Prec@1 68.00 (61.05)
125 | Val-(28): [700/1000] Time 0.05 (0.09) Loss 1.34 (1.05) Prec@1 49.33 (61.04)
126 | Val-(28): [800/1000] Time 0.13 (0.09) Loss 1.39 (1.05) Prec@1 42.67 (61.26)
127 | Val-(28): [900/1000] Time 0.05 (0.09) Loss 1.28 (1.05) Prec@1 50.67 (61.21)
128 | * Prec@1 61.30 Best_prec1 65.43
129 | Test accuracy: 61.296005 h: 0.624320
130 |
131 | ==================== The 4-th round ====================
132 | Val-(28): [100/1000] Time 0.06 (0.10) Loss 0.50 (1.04) Prec@1 77.33 (61.06)
133 | Val-(28): [200/1000] Time 0.08 (0.09) Loss 1.02 (1.02) Prec@1 60.00 (61.52)
134 | Val-(28): [300/1000] Time 0.05 (0.09) Loss 1.72 (1.05) Prec@1 44.00 (60.99)
135 | Val-(28): [400/1000] Time 0.05 (0.09) Loss 0.86 (1.05) Prec@1 68.00 (60.94)
136 | Val-(28): [500/1000] Time 0.05 (0.09) Loss 0.62 (1.05) Prec@1 78.67 (60.92)
137 | Val-(28): [600/1000] Time 0.05 (0.09) Loss 0.95 (1.05) Prec@1 65.33 (60.82)
138 | Val-(28): [700/1000] Time 0.15 (0.09) Loss 0.89 (1.04) Prec@1 58.67 (61.02)
139 | Val-(28): [800/1000] Time 0.05 (0.09) Loss 0.51 (1.05) Prec@1 80.00 (60.88)
140 | Val-(28): [900/1000] Time 0.05 (0.09) Loss 1.04 (1.05) Prec@1 61.33 (61.10)
141 | * Prec@1 61.09 Best_prec1 65.43
142 | Test accuracy: 61.090668 h: 0.634639
143 |
144 | Mean_accuracy: 61.231200 h: 0.626216
145 | ===================================== Test is END =====================================
146 |
147 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/test_loss.txt:
--------------------------------------------------------------------------------
1 | 1.253673746883869233e+00
2 | 1.175363154888153128e+00
3 | 1.126533054888248397e+00
4 | 1.116016005635261488e+00
5 | 1.086189859867096041e+00
6 | 1.077181908696889900e+00
7 | 1.091881560593843448e+00
8 | 1.071739518642425448e+00
9 | 1.066117631584405867e+00
10 | 1.045860359370708537e+00
11 | 1.052673544406890871e+00
12 | 1.021202118217945154e+00
13 | 1.059072216629981966e+00
14 | 1.075823018640279738e+00
15 | 1.018044667035341355e+00
16 | 1.032609475791454345e+00
17 | 1.032400890231132573e+00
18 | 1.050499824374914182e+00
19 | 1.015169827967882243e+00
20 | 1.077288622945547170e+00
21 | 1.008571608692407695e+00
22 | 1.012665395826101378e+00
23 | 1.059207549989223507e+00
24 | 1.020502974927425477e+00
25 | 1.031800021022558189e+00
26 | 1.021756289094686521e+00
27 | 1.040406664311885887e+00
28 | 1.048552886307239529e+00
29 | 1.050527185380458750e+00
30 | 1.044508923292160052e+00
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/train_loss.txt:
--------------------------------------------------------------------------------
1 | 1.395911455857753669e+00
2 | 1.235713104736805068e+00
3 | 1.144744067624211326e+00
4 | 1.076060488390922609e+00
5 | 1.011772379270196032e+00
6 | 9.715176198184489742e-01
7 | 9.266147161453962555e-01
8 | 8.854524700559676109e-01
9 | 8.517675985291600638e-01
10 | 8.144459471218288282e-01
11 | 7.861138152942060975e-01
12 | 7.514922330245376036e-01
13 | 7.213985654670744818e-01
14 | 6.938584349561482956e-01
15 | 6.661867645502090873e-01
16 | 6.298230365678667564e-01
17 | 6.092061093773692981e-01
18 | 5.818210175462067424e-01
19 | 5.511680436317808462e-01
20 | 5.301910962749272205e-01
21 | 5.055666309557854676e-01
22 | 4.742365922626107788e-01
23 | 4.432025669872760587e-01
24 | 4.220217605788260662e-01
25 | 4.013453226396814233e-01
26 | 3.774004172056913409e-01
27 | 3.547824192937463761e-01
28 | 3.351189949912484756e-01
29 | 3.251082921743392862e-01
30 | 3.225487162891309545e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_1Shot/val_loss.txt:
--------------------------------------------------------------------------------
1 | 1.302756758093833955e+00
2 | 1.206469823241233863e+00
3 | 1.167996160447597465e+00
4 | 1.110277335435152057e+00
5 | 1.078763202548026934e+00
6 | 1.060682893872261001e+00
7 | 1.056014724582433617e+00
8 | 1.025647476971149441e+00
9 | 1.028116998285055095e+00
10 | 1.029297127872705442e+00
11 | 1.063265623092651380e+00
12 | 1.031772689104080154e+00
13 | 1.007225043669343068e+00
14 | 1.014933643430471433e+00
15 | 1.000232069969177351e+00
16 | 1.010613498389720810e+00
17 | 9.800566422045230430e-01
18 | 1.021281833261251437e+00
19 | 9.849715006053447741e-01
20 | 9.727315579056740047e-01
21 | 9.694692134708166043e-01
22 | 9.776101870536804128e-01
23 | 9.603498172610998029e-01
24 | 9.599604772925376395e-01
25 | 9.734738064706325300e-01
26 | 9.642601183503866080e-01
27 | 9.656532637029886512e-01
28 | 9.440980364978313055e-01
29 | 9.491272331327199607e-01
30 | 9.420109668523073410e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/Loss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/Loss.png
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/Test_results.txt:
--------------------------------------------------------------------------------
1 | ========================================== Start Test ==========================================
2 |
3 | => loading checkpoint './results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar'
4 | => loaded checkpoint './results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar' (epoch 28)
5 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, current_epoch=29, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='ResNet12', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.01, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='train', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot', print_freq=100, query_num=15, resume='', shot_num=5, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
6 | Fewshot_model(
7 | (features): ResNet_84(
8 | (layer1): Sequential(
9 | (0): BasicBlock(
10 | (conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
11 | (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
12 | (relu): LeakyReLU(negative_slope=0.1)
13 | (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
14 | (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (conv3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
16 | (bn3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
17 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
18 | (downsample): Sequential(
19 | (0): Conv2d(3, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
20 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
21 | )
22 | (DropBlock): DropBlock()
23 | )
24 | )
25 | (layer2): Sequential(
26 | (0): BasicBlock(
27 | (conv1): Conv2d(64, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
28 | (bn1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
29 | (relu): LeakyReLU(negative_slope=0.1)
30 | (conv2): Conv2d(160, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
31 | (bn2): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
32 | (conv3): Conv2d(160, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
33 | (bn3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
34 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
35 | (downsample): Sequential(
36 | (0): Conv2d(64, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
37 | (1): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
38 | )
39 | (DropBlock): DropBlock()
40 | )
41 | )
42 | (layer3): Sequential(
43 | (0): BasicBlock(
44 | (conv1): Conv2d(160, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
45 | (bn1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
46 | (relu): LeakyReLU(negative_slope=0.1)
47 | (conv2): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
48 | (bn2): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
49 | (conv3): Conv2d(320, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
50 | (bn3): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
51 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
52 | (downsample): Sequential(
53 | (0): Conv2d(160, 320, kernel_size=(1, 1), stride=(1, 1), bias=False)
54 | (1): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
55 | )
56 | (DropBlock): DropBlock()
57 | )
58 | )
59 | (layer4): Sequential(
60 | (0): BasicBlock(
61 | (conv1): Conv2d(320, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
62 | (bn1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
63 | (relu): LeakyReLU(negative_slope=0.1)
64 | (conv2): Conv2d(640, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
65 | (bn2): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
66 | (conv3): Conv2d(640, 640, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
67 | (bn3): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
68 | (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
69 | (downsample): Sequential(
70 | (0): Conv2d(320, 640, kernel_size=(1, 1), stride=(1, 1), bias=False)
71 | (1): BatchNorm2d(640, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
72 | )
73 | (DropBlock): DropBlock()
74 | )
75 | )
76 | )
77 | (classifier): ImgtoClass_Metric()
78 | )
79 | ==================== The 0-th round ====================
80 | Val-(28): [100/1000] Time 0.06 (0.13) Loss 0.71 (0.65) Prec@1 62.67 (74.59)
81 | Val-(28): [200/1000] Time 0.06 (0.12) Loss 0.42 (0.66) Prec@1 85.33 (74.28)
82 | Val-(28): [300/1000] Time 0.06 (0.12) Loss 0.81 (0.64) Prec@1 70.67 (74.85)
83 | Val-(28): [400/1000] Time 0.24 (0.11) Loss 0.53 (0.65) Prec@1 80.00 (74.90)
84 | Val-(28): [500/1000] Time 0.29 (0.11) Loss 0.94 (0.65) Prec@1 66.67 (74.95)
85 | Val-(28): [600/1000] Time 0.06 (0.11) Loss 0.68 (0.64) Prec@1 68.00 (75.30)
86 | Val-(28): [700/1000] Time 0.06 (0.11) Loss 0.70 (0.65) Prec@1 74.67 (75.08)
87 | Val-(28): [800/1000] Time 0.06 (0.11) Loss 0.42 (0.65) Prec@1 86.67 (75.14)
88 | Val-(28): [900/1000] Time 0.06 (0.11) Loss 0.69 (0.64) Prec@1 66.67 (75.23)
89 | * Prec@1 75.18 Best_prec1 79.01
90 | Test accuracy: 75.177338 h: 0.484989
91 |
92 | ==================== The 1-th round ====================
93 | Val-(28): [100/1000] Time 0.23 (0.12) Loss 0.46 (0.63) Prec@1 81.33 (75.18)
94 | Val-(28): [200/1000] Time 0.06 (0.11) Loss 1.15 (0.63) Prec@1 57.33 (75.66)
95 | Val-(28): [300/1000] Time 0.23 (0.11) Loss 0.65 (0.63) Prec@1 74.67 (75.69)
96 | Val-(28): [400/1000] Time 0.24 (0.11) Loss 0.56 (0.63) Prec@1 76.00 (75.73)
97 | Val-(28): [500/1000] Time 0.06 (0.11) Loss 0.48 (0.63) Prec@1 84.00 (75.73)
98 | Val-(28): [600/1000] Time 0.10 (0.11) Loss 0.98 (0.63) Prec@1 57.33 (75.85)
99 | Val-(28): [700/1000] Time 0.06 (0.11) Loss 0.53 (0.63) Prec@1 80.00 (75.68)
100 | Val-(28): [800/1000] Time 0.08 (0.11) Loss 0.58 (0.63) Prec@1 73.33 (75.81)
101 | Val-(28): [900/1000] Time 0.28 (0.11) Loss 0.40 (0.63) Prec@1 86.67 (75.94)
102 | * Prec@1 75.93 Best_prec1 79.01
103 | Test accuracy: 75.931999 h: 0.497722
104 |
105 | ==================== The 2-th round ====================
106 | Val-(28): [100/1000] Time 0.06 (0.12) Loss 0.78 (0.63) Prec@1 64.00 (75.63)
107 | Val-(28): [200/1000] Time 0.06 (0.11) Loss 1.04 (0.62) Prec@1 58.67 (76.11)
108 | Val-(28): [300/1000] Time 0.06 (0.11) Loss 0.42 (0.62) Prec@1 84.00 (76.10)
109 | Val-(28): [400/1000] Time 0.06 (0.11) Loss 0.43 (0.62) Prec@1 89.33 (76.03)
110 | Val-(28): [500/1000] Time 0.06 (0.11) Loss 0.70 (0.63) Prec@1 76.00 (75.74)
111 | Val-(28): [600/1000] Time 0.06 (0.11) Loss 0.46 (0.63) Prec@1 80.00 (75.63)
112 | Val-(28): [700/1000] Time 0.06 (0.11) Loss 0.68 (0.63) Prec@1 73.33 (75.49)
113 | Val-(28): [800/1000] Time 0.06 (0.11) Loss 0.63 (0.63) Prec@1 80.00 (75.52)
114 | Val-(28): [900/1000] Time 0.06 (0.11) Loss 0.35 (0.63) Prec@1 89.33 (75.61)
115 | * Prec@1 75.61 Best_prec1 79.01
116 | Test accuracy: 75.614670 h: 0.494373
117 |
118 | ==================== The 3-th round ====================
119 | Val-(28): [100/1000] Time 0.20 (0.12) Loss 0.81 (0.61) Prec@1 70.67 (77.37)
120 | Val-(28): [200/1000] Time 0.06 (0.12) Loss 0.55 (0.61) Prec@1 80.00 (77.21)
121 | Val-(28): [300/1000] Time 0.06 (0.11) Loss 0.51 (0.62) Prec@1 89.33 (76.69)
122 | Val-(28): [400/1000] Time 0.06 (0.11) Loss 0.82 (0.63) Prec@1 64.00 (76.38)
123 | Val-(28): [500/1000] Time 0.06 (0.11) Loss 0.83 (0.63) Prec@1 70.67 (76.36)
124 | Val-(28): [600/1000] Time 0.11 (0.11) Loss 0.60 (0.62) Prec@1 76.00 (76.27)
125 | Val-(28): [700/1000] Time 0.06 (0.11) Loss 0.41 (0.63) Prec@1 85.33 (76.00)
126 | Val-(28): [800/1000] Time 0.06 (0.11) Loss 0.89 (0.63) Prec@1 68.00 (76.05)
127 | Val-(28): [900/1000] Time 0.06 (0.11) Loss 0.50 (0.63) Prec@1 81.33 (75.89)
128 | * Prec@1 75.86 Best_prec1 79.01
129 | Test accuracy: 75.863998 h: 0.491147
130 |
131 | ==================== The 4-th round ====================
132 | Val-(28): [100/1000] Time 0.21 (0.12) Loss 0.82 (0.63) Prec@1 62.67 (76.01)
133 | Val-(28): [200/1000] Time 0.06 (0.12) Loss 0.90 (0.65) Prec@1 69.33 (75.33)
134 | Val-(28): [300/1000] Time 0.06 (0.12) Loss 0.56 (0.64) Prec@1 80.00 (75.90)
135 | Val-(28): [400/1000] Time 0.06 (0.12) Loss 1.05 (0.63) Prec@1 69.33 (75.95)
136 | Val-(28): [500/1000] Time 0.06 (0.11) Loss 1.07 (0.63) Prec@1 60.00 (75.80)
137 | Val-(28): [600/1000] Time 0.06 (0.11) Loss 0.69 (0.63) Prec@1 80.00 (75.94)
138 | Val-(28): [700/1000] Time 0.06 (0.11) Loss 0.75 (0.63) Prec@1 65.33 (75.91)
139 | Val-(28): [800/1000] Time 0.06 (0.11) Loss 0.34 (0.63) Prec@1 85.33 (75.93)
140 | Val-(28): [900/1000] Time 0.24 (0.11) Loss 0.72 (0.63) Prec@1 73.33 (75.79)
141 | * Prec@1 75.73 Best_prec1 79.01
142 | Test accuracy: 75.732002 h: 0.479748
143 |
144 | Mean_accuracy: 75.664001 h: 0.489596
145 | ===================================== Test is END =====================================
146 |
147 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/test_loss.txt:
--------------------------------------------------------------------------------
1 | 8.425347571074962572e-01
2 | 7.676017894446849343e-01
3 | 7.155224827527999487e-01
4 | 6.975680709481238972e-01
5 | 6.747762677669525422e-01
6 | 6.798861018270254686e-01
7 | 6.394134938269853130e-01
8 | 6.571893894076347165e-01
9 | 6.605198022127151125e-01
10 | 6.350636517703532880e-01
11 | 6.165688731074333573e-01
12 | 6.264167745858431058e-01
13 | 6.172348148077726471e-01
14 | 6.424799344837665016e-01
15 | 6.057428984493017365e-01
16 | 6.356335954070091443e-01
17 | 6.404178363978862976e-01
18 | 6.325181835740805170e-01
19 | 6.327834124863147558e-01
20 | 6.353237496763467496e-01
21 | 6.283777105212211556e-01
22 | 6.428970314860343871e-01
23 | 6.132191962748766434e-01
24 | 6.240370995253324837e-01
25 | 6.418749737814068990e-01
26 | 6.256901976466179294e-01
27 | 6.413167422860860389e-01
28 | 6.382769202739000391e-01
29 | 6.326134659498929835e-01
30 | 6.346755950599909379e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/train_loss.txt:
--------------------------------------------------------------------------------
1 | 1.069172682148218145e+00
2 | 8.350652296170592015e-01
3 | 7.287498992070555737e-01
4 | 6.581147375971079239e-01
5 | 6.009942553445696278e-01
6 | 5.563013286013156478e-01
7 | 5.161444501563906551e-01
8 | 4.785886963196098742e-01
9 | 4.452948411948978724e-01
10 | 4.179902077697217333e-01
11 | 3.942830233976244991e-01
12 | 3.718382237531244749e-01
13 | 3.492388568334281462e-01
14 | 3.236543662257492793e-01
15 | 3.041007597845047927e-01
16 | 2.851266865017824115e-01
17 | 2.625101308761164653e-01
18 | 2.476264038450084748e-01
19 | 2.288478393948636946e-01
20 | 2.139564101365394877e-01
21 | 1.958350068296305924e-01
22 | 1.807401515219360655e-01
23 | 1.679967967917211369e-01
24 | 1.548463949769502412e-01
25 | 1.432186931292293575e-01
26 | 1.333264289785409396e-01
27 | 1.259894539327127971e-01
28 | 1.197119251540861989e-01
29 | 1.167707228128449098e-01
30 | 1.138622411621035974e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.01_DN4_ResNet12_Epoch_30_miniImageNet_84_84_5Way_5Shot/val_loss.txt:
--------------------------------------------------------------------------------
1 | 8.759202211499214075e-01
2 | 8.044318869411944961e-01
3 | 7.252530652880668782e-01
4 | 6.950626986473799063e-01
5 | 6.620363071709871594e-01
6 | 6.551726454049349169e-01
7 | 6.436411685943603800e-01
8 | 6.343203865736722902e-01
9 | 5.940749592334032547e-01
10 | 6.189273901581764381e-01
11 | 6.109338519275188117e-01
12 | 5.949030190035701215e-01
13 | 5.794951391220092285e-01
14 | 5.854391817450523838e-01
15 | 6.124846868738531569e-01
16 | 6.087907980903982663e-01
17 | 5.970074675455689928e-01
18 | 5.879807460978627720e-01
19 | 5.804871315881610094e-01
20 | 5.789883091896772527e-01
21 | 5.938965923488139786e-01
22 | 5.820528274029492799e-01
23 | 5.751057557091117101e-01
24 | 5.993690277859569093e-01
25 | 5.804712954238057110e-01
26 | 5.830413467884063561e-01
27 | 5.741889033764601136e-01
28 | 5.786011957153678331e-01
29 | 5.678801862224936992e-01
30 | 5.741089160293341154e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/Loss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/Loss.png
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/Test_results.txt:
--------------------------------------------------------------------------------
1 | ========================================== Start Test ==========================================
2 |
3 | => loading checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar'
4 | => loaded checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar' (epoch 29)
5 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, current_epoch=29, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='Conv64F_Local', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.05, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='train', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot', print_freq=100, query_num=15, resume='', shot_num=1, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
6 | Fewshot_model(
7 | (features): Conv64F_Local(
8 | (features): Sequential(
9 | (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
10 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
11 | (2): LeakyReLU(negative_slope=0.2, inplace=True)
12 | (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
13 | (4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
14 | (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (6): LeakyReLU(negative_slope=0.2, inplace=True)
16 | (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
17 | (8): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
18 | (9): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
19 | (10): LeakyReLU(negative_slope=0.2, inplace=True)
20 | (11): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
21 | (12): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
22 | (13): LeakyReLU(negative_slope=0.2, inplace=True)
23 | )
24 | )
25 | (classifier): ImgtoClass_Metric()
26 | )
27 | ==================== The 0-th round ====================
28 | Val-(29): [100/1000] Time 0.02 (0.12) Loss 1.34 (1.11) Prec@1 45.33 (53.72)
29 | Val-(29): [200/1000] Time 0.03 (0.11) Loss 1.09 (1.14) Prec@1 62.67 (52.50)
30 | Val-(29): [300/1000] Time 0.03 (0.10) Loss 1.06 (1.16) Prec@1 57.33 (51.86)
31 | Val-(29): [400/1000] Time 0.22 (0.10) Loss 0.89 (1.16) Prec@1 68.00 (52.31)
32 | Val-(29): [500/1000] Time 0.08 (0.10) Loss 1.12 (1.16) Prec@1 60.00 (52.18)
33 | Val-(29): [600/1000] Time 0.06 (0.10) Loss 0.99 (1.16) Prec@1 62.67 (52.54)
34 | Val-(29): [700/1000] Time 0.02 (0.10) Loss 1.19 (1.16) Prec@1 44.00 (52.43)
35 | Val-(29): [800/1000] Time 0.02 (0.10) Loss 0.87 (1.16) Prec@1 62.67 (52.36)
36 | Val-(29): [900/1000] Time 0.25 (0.10) Loss 1.05 (1.16) Prec@1 48.00 (52.41)
37 | * Prec@1 52.21 Best_prec1 50.33
38 | Test accuracy: 52.206673 h: 0.621866
39 |
40 | ==================== The 1-th round ====================
41 | Val-(29): [100/1000] Time 0.02 (0.11) Loss 1.42 (1.18) Prec@1 33.33 (53.02)
42 | Val-(29): [200/1000] Time 0.02 (0.10) Loss 0.88 (1.18) Prec@1 69.33 (52.31)
43 | Val-(29): [300/1000] Time 0.21 (0.10) Loss 1.19 (1.18) Prec@1 52.00 (52.14)
44 | Val-(29): [400/1000] Time 0.02 (0.10) Loss 1.18 (1.18) Prec@1 53.33 (51.84)
45 | Val-(29): [500/1000] Time 0.06 (0.10) Loss 1.22 (1.19) Prec@1 46.67 (51.67)
46 | Val-(29): [600/1000] Time 0.02 (0.10) Loss 1.09 (1.18) Prec@1 54.67 (51.82)
47 | Val-(29): [700/1000] Time 0.10 (0.10) Loss 1.42 (1.18) Prec@1 36.00 (51.87)
48 | Val-(29): [800/1000] Time 0.02 (0.10) Loss 1.31 (1.18) Prec@1 42.67 (51.94)
49 | Val-(29): [900/1000] Time 0.03 (0.10) Loss 1.14 (1.18) Prec@1 45.33 (51.97)
50 | * Prec@1 51.90 Best_prec1 50.33
51 | Test accuracy: 51.901333 h: 0.633740
52 |
53 | ==================== The 2-th round ====================
54 | Val-(29): [100/1000] Time 0.22 (0.10) Loss 1.01 (1.15) Prec@1 56.00 (53.64)
55 | Val-(29): [200/1000] Time 0.02 (0.09) Loss 1.20 (1.18) Prec@1 45.33 (52.54)
56 | Val-(29): [300/1000] Time 0.02 (0.09) Loss 1.10 (1.18) Prec@1 56.00 (52.10)
57 | Val-(29): [400/1000] Time 0.02 (0.09) Loss 1.07 (1.18) Prec@1 60.00 (52.48)
58 | Val-(29): [500/1000] Time 0.02 (0.09) Loss 1.10 (1.18) Prec@1 54.67 (52.43)
59 | Val-(29): [600/1000] Time 0.02 (0.09) Loss 1.19 (1.18) Prec@1 54.67 (52.40)
60 | Val-(29): [700/1000] Time 0.02 (0.09) Loss 1.17 (1.17) Prec@1 53.33 (52.58)
61 | Val-(29): [800/1000] Time 0.20 (0.09) Loss 1.29 (1.18) Prec@1 49.33 (52.26)
62 | Val-(29): [900/1000] Time 0.25 (0.09) Loss 1.57 (1.18) Prec@1 37.33 (52.12)
63 | * Prec@1 52.08 Best_prec1 50.33
64 | Test accuracy: 52.081333 h: 0.622958
65 |
66 | ==================== The 3-th round ====================
67 | Val-(29): [100/1000] Time 0.05 (0.10) Loss 1.72 (1.15) Prec@1 37.33 (53.80)
68 | Val-(29): [200/1000] Time 0.02 (0.10) Loss 0.76 (1.16) Prec@1 77.33 (53.14)
69 | Val-(29): [300/1000] Time 0.02 (0.09) Loss 1.19 (1.16) Prec@1 54.67 (52.66)
70 | Val-(29): [400/1000] Time 0.29 (0.09) Loss 1.05 (1.16) Prec@1 57.33 (52.61)
71 | Val-(29): [500/1000] Time 0.11 (0.09) Loss 0.90 (1.17) Prec@1 69.33 (52.30)
72 | Val-(29): [600/1000] Time 0.19 (0.09) Loss 1.14 (1.17) Prec@1 48.00 (52.35)
73 | Val-(29): [700/1000] Time 0.02 (0.09) Loss 1.12 (1.17) Prec@1 58.67 (52.33)
74 | Val-(29): [800/1000] Time 0.03 (0.09) Loss 1.12 (1.17) Prec@1 42.67 (52.32)
75 | Val-(29): [900/1000] Time 0.02 (0.09) Loss 1.06 (1.17) Prec@1 57.33 (52.21)
76 | * Prec@1 52.09 Best_prec1 50.33
77 | Test accuracy: 52.091999 h: 0.621697
78 |
79 | ==================== The 4-th round ====================
80 | Val-(29): [100/1000] Time 0.02 (0.10) Loss 1.44 (1.21) Prec@1 34.67 (50.19)
81 | Val-(29): [200/1000] Time 0.02 (0.10) Loss 1.64 (1.20) Prec@1 36.00 (50.75)
82 | Val-(29): [300/1000] Time 0.21 (0.10) Loss 1.57 (1.18) Prec@1 22.67 (51.54)
83 | Val-(29): [400/1000] Time 0.14 (0.09) Loss 0.85 (1.18) Prec@1 76.00 (51.87)
84 | Val-(29): [500/1000] Time 0.36 (0.09) Loss 1.24 (1.17) Prec@1 53.33 (51.85)
85 | Val-(29): [600/1000] Time 0.02 (0.09) Loss 0.82 (1.18) Prec@1 72.00 (51.76)
86 | Val-(29): [700/1000] Time 0.02 (0.09) Loss 0.83 (1.18) Prec@1 68.00 (51.68)
87 | Val-(29): [800/1000] Time 0.30 (0.09) Loss 1.60 (1.19) Prec@1 26.67 (51.64)
88 | Val-(29): [900/1000] Time 0.18 (0.09) Loss 1.27 (1.18) Prec@1 40.00 (51.66)
89 | * Prec@1 51.61 Best_prec1 50.33
90 | Test accuracy: 51.610668 h: 0.607089
91 |
92 | Mean_accuracy: 51.978401 h: 0.621470
93 | ===================================== Test is END =====================================
94 |
95 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/Test_results_New.txt:
--------------------------------------------------------------------------------
1 | ========================================== Start Test ==========================================
2 |
3 | => loading checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar'
4 | => loaded checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar' (epoch 29)
5 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='Conv64F_Local', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.05, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='test', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/', print_freq=100, query_num=15, resume='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/', shot_num=1, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
6 | ==================== The 0-th round ====================
7 | ========================================== Start Test ==========================================
8 |
9 | => loading checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar'
10 | => loaded checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar' (epoch 29)
11 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='Conv64F_Local', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.05, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='test', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/', print_freq=100, query_num=15, resume='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/', shot_num=1, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
12 | ==================== The 0-th round ====================
13 | Test-(29): [100/1000] Time 0.244 (0.097) Loss 1.098 (1.179) Prec@1 60.000 (51.644)
14 | Test-(29): [200/1000] Time 0.024 (0.092) Loss 1.127 (1.175) Prec@1 53.333 (52.060)
15 | Test-(29): [300/1000] Time 0.024 (0.092) Loss 1.503 (1.178) Prec@1 34.667 (52.089)
16 | Test-(29): [400/1000] Time 0.026 (0.091) Loss 0.846 (1.180) Prec@1 72.000 (51.930)
17 | Test-(29): [500/1000] Time 0.026 (0.090) Loss 1.146 (1.182) Prec@1 52.000 (52.106)
18 | Test-(29): [600/1000] Time 0.292 (0.089) Loss 1.327 (1.183) Prec@1 42.667 (51.958)
19 | Test-(29): [700/1000] Time 0.023 (0.089) Loss 1.357 (1.185) Prec@1 48.000 (51.897)
20 | Test-(29): [800/1000] Time 0.023 (0.088) Loss 0.942 (1.185) Prec@1 58.667 (51.895)
21 | Test-(29): [900/1000] Time 0.027 (0.088) Loss 0.965 (1.183) Prec@1 62.667 (51.917)
22 | * Prec@1 51.981 Best_prec1 50.331
23 | Test accuracy: 51.981335 h: 0.623445
24 |
25 | ==================== The 1-th round ====================
26 | Test-(29): [100/1000] Time 0.337 (0.091) Loss 1.486 (1.190) Prec@1 33.333 (50.746)
27 | Test-(29): [200/1000] Time 0.140 (0.089) Loss 1.199 (1.175) Prec@1 46.667 (51.708)
28 | Test-(29): [300/1000] Time 0.024 (0.087) Loss 1.035 (1.187) Prec@1 56.000 (51.384)
29 | Test-(29): [400/1000] Time 0.024 (0.089) Loss 1.222 (1.175) Prec@1 46.667 (51.920)
30 | Test-(29): [500/1000] Time 0.054 (0.088) Loss 1.057 (1.175) Prec@1 53.333 (51.880)
31 | Test-(29): [600/1000] Time 0.024 (0.088) Loss 1.111 (1.175) Prec@1 54.667 (51.783)
32 | Test-(29): [700/1000] Time 0.024 (0.089) Loss 1.389 (1.175) Prec@1 33.333 (51.804)
33 | Test-(29): [800/1000] Time 0.028 (0.090) Loss 1.017 (1.172) Prec@1 62.667 (51.983)
34 | Test-(29): [900/1000] Time 0.024 (0.090) Loss 1.332 (1.175) Prec@1 42.667 (51.809)
35 | * Prec@1 51.777 Best_prec1 50.331
36 | Test accuracy: 51.777332 h: 0.618619
37 |
38 | ==================== The 2-th round ====================
39 | Test-(29): [100/1000] Time 0.026 (0.095) Loss 1.546 (1.148) Prec@1 33.333 (53.861)
40 | Test-(29): [200/1000] Time 0.024 (0.091) Loss 0.740 (1.162) Prec@1 74.667 (52.909)
41 | Test-(29): [300/1000] Time 0.227 (0.090) Loss 1.211 (1.171) Prec@1 53.333 (52.558)
42 | Test-(29): [400/1000] Time 0.088 (0.090) Loss 1.384 (1.173) Prec@1 36.000 (52.156)
43 | Test-(29): [500/1000] Time 0.030 (0.089) Loss 0.973 (1.175) Prec@1 57.333 (51.933)
44 | Test-(29): [600/1000] Time 0.024 (0.089) Loss 1.199 (1.171) Prec@1 46.667 (52.204)
45 | Test-(29): [700/1000] Time 0.169 (0.088) Loss 1.340 (1.174) Prec@1 38.667 (52.065)
46 | Test-(29): [800/1000] Time 0.065 (0.088) Loss 1.505 (1.175) Prec@1 37.333 (51.955)
47 | Test-(29): [900/1000] Time 0.024 (0.088) Loss 1.106 (1.176) Prec@1 61.333 (51.907)
48 | * Prec@1 51.929 Best_prec1 50.331
49 | Test accuracy: 51.929337 h: 0.627479
50 |
51 | ==================== The 3-th round ====================
52 | Test-(29): [100/1000] Time 0.024 (0.096) Loss 1.036 (1.210) Prec@1 57.333 (50.389)
53 | Test-(29): [200/1000] Time 0.024 (0.095) Loss 1.280 (1.203) Prec@1 46.667 (50.348)
54 | Test-(29): [300/1000] Time 0.024 (0.093) Loss 1.511 (1.188) Prec@1 38.667 (51.375)
55 | Test-(29): [400/1000] Time 0.024 (0.091) Loss 0.993 (1.195) Prec@1 62.667 (50.983)
56 | Test-(29): [500/1000] Time 0.024 (0.090) Loss 1.449 (1.196) Prec@1 33.333 (50.986)
57 | Test-(29): [600/1000] Time 0.025 (0.090) Loss 1.508 (1.193) Prec@1 46.667 (51.115)
58 | Test-(29): [700/1000] Time 0.024 (0.090) Loss 1.150 (1.190) Prec@1 57.333 (51.249)
59 | Test-(29): [800/1000] Time 0.024 (0.090) Loss 1.544 (1.190) Prec@1 40.000 (51.244)
60 | Test-(29): [900/1000] Time 0.023 (0.090) Loss 1.315 (1.186) Prec@1 49.333 (51.399)
61 | * Prec@1 51.361 Best_prec1 50.331
62 | Test accuracy: 51.361336 h: 0.646845
63 |
64 | ==================== The 4-th round ====================
65 | Test-(29): [100/1000] Time 0.358 (0.100) Loss 1.408 (1.200) Prec@1 46.667 (51.366)
66 | Test-(29): [200/1000] Time 0.241 (0.096) Loss 1.475 (1.200) Prec@1 37.333 (51.104)
67 | Test-(29): [300/1000] Time 0.024 (0.095) Loss 0.959 (1.199) Prec@1 62.667 (51.101)
68 | Test-(29): [400/1000] Time 0.036 (0.093) Loss 0.947 (1.195) Prec@1 60.000 (51.096)
69 | Test-(29): [500/1000] Time 0.149 (0.093) Loss 1.124 (1.186) Prec@1 61.333 (51.494)
70 | Test-(29): [600/1000] Time 0.289 (0.092) Loss 0.671 (1.183) Prec@1 73.333 (51.527)
71 | Test-(29): [700/1000] Time 0.023 (0.091) Loss 1.445 (1.182) Prec@1 38.667 (51.576)
72 | Test-(29): [800/1000] Time 0.216 (0.092) Loss 1.014 (1.184) Prec@1 56.000 (51.531)
73 | Test-(29): [900/1000] Time 0.156 (0.092) Loss 1.263 (1.184) Prec@1 52.000 (51.596)
74 | * Prec@1 51.655 Best_prec1 50.331
75 | Test accuracy: 51.654667 h: 0.620802
76 |
77 | Mean_accuracy: 51.740801 h: 0.627438
78 | ===================================== Test is END =====================================
79 |
80 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/model_best.pth.tar
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/test_loss.txt:
--------------------------------------------------------------------------------
1 | 1.588965280413627612e+00
2 | 1.580805958509445164e+00
3 | 1.553094785094261132e+00
4 | 1.513077440857887312e+00
5 | 1.484222897410392816e+00
6 | 1.442642955780029324e+00
7 | 1.422873528480529837e+00
8 | 1.422249255418777558e+00
9 | 1.337551431953907022e+00
10 | 1.319544102966785371e+00
11 | 1.330531956791877857e+00
12 | 1.313925987958908026e+00
13 | 1.324365826487541309e+00
14 | 1.304923660099506444e+00
15 | 1.288792364060878715e+00
16 | 1.278352851450443195e+00
17 | 1.310629327356815255e+00
18 | 1.292831373512744797e+00
19 | 1.260266643941402531e+00
20 | 1.291257175683975245e+00
21 | 1.252241140484809945e+00
22 | 1.232725776433944764e+00
23 | 1.259019998848438293e+00
24 | 1.212792974293231962e+00
25 | 1.217878570377826764e+00
26 | 1.233708600878715478e+00
27 | 1.197975303232669875e+00
28 | 1.217177280008792772e+00
29 | 1.183406202018260966e+00
30 | 1.175420023381710033e+00
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/train_loss.txt:
--------------------------------------------------------------------------------
1 | 1.761601435124874104e+00
2 | 1.562190455317497229e+00
3 | 1.549602791261672996e+00
4 | 1.530674070775508877e+00
5 | 1.498226171290874431e+00
6 | 1.475548240065574612e+00
7 | 1.454539830613136298e+00
8 | 1.432932049363851545e+00
9 | 1.418241293960809779e+00
10 | 1.400847774267196755e+00
11 | 1.390578488349914599e+00
12 | 1.379888338118791635e+00
13 | 1.367536048835515938e+00
14 | 1.360217748552560835e+00
15 | 1.349348247718811011e+00
16 | 1.337980837726592931e+00
17 | 1.329394348561763861e+00
18 | 1.316805605852603867e+00
19 | 1.302767693603038790e+00
20 | 1.295108445727825242e+00
21 | 1.279733602273464221e+00
22 | 1.273384560090303319e+00
23 | 1.256879824048280803e+00
24 | 1.242287492871284593e+00
25 | 1.230280000776052374e+00
26 | 1.218111183929443397e+00
27 | 1.200011553645133899e+00
28 | 1.192383873623609647e+00
29 | 1.175867653366923227e+00
30 | 1.168693618550896707e+00
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_1Shot/val_loss.txt:
--------------------------------------------------------------------------------
1 | 1.575199795722961316e+00
2 | 1.569603443980216895e+00
3 | 1.561417399406433093e+00
4 | 1.534682530045509363e+00
5 | 1.505603410720825153e+00
6 | 1.491549753427505509e+00
7 | 1.456938738226890573e+00
8 | 1.433602441072463929e+00
9 | 1.405755109906196676e+00
10 | 1.375410828590392986e+00
11 | 1.398355887174606238e+00
12 | 1.378046454668045095e+00
13 | 1.365522751629352660e+00
14 | 1.353747321248054414e+00
15 | 1.372285865902900692e+00
16 | 1.337879590153694176e+00
17 | 1.341320399284362752e+00
18 | 1.344282808244228411e+00
19 | 1.327187149405479438e+00
20 | 1.343007812678813861e+00
21 | 1.320870438754558673e+00
22 | 1.330829265534877681e+00
23 | 1.306217297494411511e+00
24 | 1.282890752315521299e+00
25 | 1.274596982717514093e+00
26 | 1.257495359361171738e+00
27 | 1.256209821581840469e+00
28 | 1.244305944681167508e+00
29 | 1.224589444100856683e+00
30 | 1.212966168940067258e+00
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/Loss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/Loss.png
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/Test_results.txt:
--------------------------------------------------------------------------------
1 | ========================================== Start Test ==========================================
2 |
3 | => loading checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar'
4 | => loaded checkpoint './results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar' (epoch 29)
5 | Namespace(adam=False, aug_shot_num=20, beta1=0.5, clamp_lower=-0.01, clamp_upper=0.01, classifier_model='DN4', cosine=True, cuda=True, current_epoch=29, data_name='miniImageNet', dataset_dir='/data1/Liwenbin/Datasets/miniImageNet--ravi', encoder_model='Conv64F_Local', episodeSize=1, episode_test_num=1000, episode_train_num=10000, episode_val_num=1000, epochs=30, imageSize=84, lr=0.05, lr_decay_epochs=[60, 80], lr_decay_rate=0.1, mode='train', momentum=0.9, nc=3, neighbor_k=3, ngpu=1, outf='./results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot', print_freq=100, query_num=15, resume='', shot_num=5, start_epoch=0, test_aug=False, testepisodeSize=1, train_aug=True, way_num=5, weight_decay=0.0005, workers=4)
6 | Fewshot_model(
7 | (features): Conv64F_Local(
8 | (features): Sequential(
9 | (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
10 | (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
11 | (2): LeakyReLU(negative_slope=0.2, inplace=True)
12 | (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
13 | (4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
14 | (5): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
15 | (6): LeakyReLU(negative_slope=0.2, inplace=True)
16 | (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
17 | (8): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
18 | (9): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
19 | (10): LeakyReLU(negative_slope=0.2, inplace=True)
20 | (11): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
21 | (12): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
22 | (13): LeakyReLU(negative_slope=0.2, inplace=True)
23 | )
24 | )
25 | (classifier): ImgtoClass_Metric()
26 | )
27 | ==================== The 0-th round ====================
28 | Val-(29): [100/1000] Time 0.07 (0.16) Loss 0.32 (0.74) Prec@1 88.00 (72.30)
29 | Val-(29): [200/1000] Time 0.26 (0.16) Loss 0.51 (0.71) Prec@1 82.67 (73.39)
30 | Val-(29): [300/1000] Time 0.07 (0.15) Loss 0.50 (0.70) Prec@1 82.67 (73.47)
31 | Val-(29): [400/1000] Time 0.06 (0.14) Loss 0.41 (0.70) Prec@1 78.67 (73.39)
32 | Val-(29): [500/1000] Time 0.06 (0.13) Loss 0.76 (0.70) Prec@1 73.33 (73.26)
33 | Val-(29): [600/1000] Time 0.06 (0.13) Loss 0.60 (0.70) Prec@1 81.33 (73.26)
34 | Val-(29): [700/1000] Time 0.06 (0.13) Loss 0.42 (0.71) Prec@1 88.00 (73.12)
35 | Val-(29): [800/1000] Time 0.21 (0.12) Loss 0.60 (0.71) Prec@1 77.33 (73.05)
36 | Val-(29): [900/1000] Time 0.20 (0.12) Loss 0.48 (0.71) Prec@1 80.00 (73.06)
37 | * Prec@1 73.09 Best_prec1 71.56
38 | Test accuracy: 73.085335 h: 0.482404
39 |
40 | ==================== The 1-th round ====================
41 | Val-(29): [100/1000] Time 0.41 (0.12) Loss 1.07 (0.71) Prec@1 60.00 (73.44)
42 | Val-(29): [200/1000] Time 0.19 (0.11) Loss 0.95 (0.72) Prec@1 72.00 (72.96)
43 | Val-(29): [300/1000] Time 0.07 (0.11) Loss 0.81 (0.71) Prec@1 69.33 (73.29)
44 | Val-(29): [400/1000] Time 0.06 (0.11) Loss 0.90 (0.71) Prec@1 64.00 (73.24)
45 | Val-(29): [500/1000] Time 0.06 (0.11) Loss 0.63 (0.71) Prec@1 77.33 (73.21)
46 | Val-(29): [600/1000] Time 0.06 (0.11) Loss 0.74 (0.71) Prec@1 68.00 (73.17)
47 | Val-(29): [700/1000] Time 0.06 (0.11) Loss 0.87 (0.71) Prec@1 62.67 (73.11)
48 | Val-(29): [800/1000] Time 0.07 (0.11) Loss 0.47 (0.70) Prec@1 80.00 (73.24)
49 | Val-(29): [900/1000] Time 0.07 (0.11) Loss 0.65 (0.71) Prec@1 81.33 (73.19)
50 | * Prec@1 73.31 Best_prec1 71.56
51 | Test accuracy: 73.306664 h: 0.481580
52 |
53 | ==================== The 2-th round ====================
54 | Val-(29): [100/1000] Time 0.07 (0.12) Loss 0.75 (0.71) Prec@1 76.00 (72.54)
55 | Val-(29): [200/1000] Time 0.07 (0.12) Loss 1.17 (0.70) Prec@1 53.33 (72.80)
56 | Val-(29): [300/1000] Time 0.20 (0.11) Loss 0.56 (0.70) Prec@1 81.33 (73.16)
57 | Val-(29): [400/1000] Time 0.06 (0.11) Loss 0.96 (0.70) Prec@1 52.00 (73.07)
58 | Val-(29): [500/1000] Time 0.06 (0.11) Loss 0.58 (0.70) Prec@1 76.00 (73.13)
59 | Val-(29): [600/1000] Time 0.07 (0.11) Loss 0.39 (0.70) Prec@1 85.33 (73.05)
60 | Val-(29): [700/1000] Time 0.06 (0.11) Loss 0.64 (0.70) Prec@1 74.67 (73.24)
61 | Val-(29): [800/1000] Time 0.07 (0.11) Loss 0.88 (0.70) Prec@1 62.67 (73.23)
62 | Val-(29): [900/1000] Time 0.06 (0.11) Loss 0.64 (0.70) Prec@1 76.00 (73.17)
63 | * Prec@1 72.99 Best_prec1 71.56
64 | Test accuracy: 72.990669 h: 0.497712
65 |
66 | ==================== The 3-th round ====================
67 | Val-(29): [100/1000] Time 0.06 (0.16) Loss 0.90 (0.69) Prec@1 61.33 (73.58)
68 | Val-(29): [200/1000] Time 0.24 (0.16) Loss 0.58 (0.69) Prec@1 77.33 (74.02)
69 | Val-(29): [300/1000] Time 0.06 (0.16) Loss 0.57 (0.69) Prec@1 80.00 (73.67)
70 | Val-(29): [400/1000] Time 0.07 (0.15) Loss 0.72 (0.70) Prec@1 72.00 (73.12)
71 | Val-(29): [500/1000] Time 0.07 (0.14) Loss 0.40 (0.70) Prec@1 82.67 (73.27)
72 | Val-(29): [600/1000] Time 0.23 (0.14) Loss 0.68 (0.70) Prec@1 78.67 (73.28)
73 | Val-(29): [700/1000] Time 0.15 (0.15) Loss 1.27 (0.70) Prec@1 52.00 (73.45)
74 | Val-(29): [800/1000] Time 0.22 (0.14) Loss 0.60 (0.70) Prec@1 77.33 (73.51)
75 | Val-(29): [900/1000] Time 0.22 (0.14) Loss 0.69 (0.70) Prec@1 76.00 (73.45)
76 | * Prec@1 73.48 Best_prec1 71.56
77 | Test accuracy: 73.482674 h: 0.479026
78 |
79 | ==================== The 4-th round ====================
80 | Val-(29): [100/1000] Time 0.06 (0.12) Loss 0.96 (0.70) Prec@1 65.33 (72.95)
81 | Val-(29): [200/1000] Time 0.07 (0.11) Loss 0.51 (0.70) Prec@1 85.33 (73.09)
82 | Val-(29): [300/1000] Time 0.07 (0.11) Loss 0.83 (0.70) Prec@1 64.00 (73.29)
83 | Val-(29): [400/1000] Time 0.19 (0.11) Loss 0.68 (0.70) Prec@1 73.33 (73.18)
84 | Val-(29): [500/1000] Time 0.06 (0.11) Loss 0.52 (0.71) Prec@1 82.67 (73.05)
85 | Val-(29): [600/1000] Time 0.17 (0.11) Loss 0.78 (0.70) Prec@1 73.33 (73.16)
86 | Val-(29): [700/1000] Time 0.25 (0.11) Loss 0.58 (0.70) Prec@1 76.00 (73.31)
87 | Val-(29): [800/1000] Time 0.08 (0.11) Loss 0.55 (0.70) Prec@1 81.33 (73.22)
88 | Val-(29): [900/1000] Time 0.10 (0.11) Loss 0.46 (0.71) Prec@1 81.33 (73.13)
89 | * Prec@1 73.13 Best_prec1 71.56
90 | Test accuracy: 73.125336 h: 0.501544
91 |
92 | Mean_accuracy: 73.198135 h: 0.488453
93 | ===================================== Test is END =====================================
94 |
95 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WenbinLee/DN4/440857b23a5bc9798004f81f732c5cc9272a99b8/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/model_best.pth.tar
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/test_loss.txt:
--------------------------------------------------------------------------------
1 | 1.345906615495681802e+00
2 | 1.103285467445850321e+00
3 | 1.060474659025669064e+00
4 | 9.981950015425682388e-01
5 | 9.811021184921264737e-01
6 | 9.786735889315605341e-01
7 | 9.327543408870696551e-01
8 | 8.975806340277194817e-01
9 | 8.827502713799476597e-01
10 | 9.025217817425728040e-01
11 | 8.698854534029960561e-01
12 | 8.654945094585418941e-01
13 | 8.590273474156856492e-01
14 | 8.348823354840279043e-01
15 | 8.583094394803046923e-01
16 | 8.240921595692634050e-01
17 | 8.346195108592510126e-01
18 | 8.080945486724376847e-01
19 | 8.381706591546534968e-01
20 | 8.250573616027832013e-01
21 | 7.829902250170707179e-01
22 | 7.623370675742626723e-01
23 | 7.903140447139740399e-01
24 | 7.611604312360287228e-01
25 | 7.565869103670119777e-01
26 | 7.281737144589424116e-01
27 | 7.320693117082118784e-01
28 | 7.268759717345237847e-01
29 | 7.113414543271064927e-01
30 | 7.156810471117496242e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/train_loss.txt:
--------------------------------------------------------------------------------
1 | 1.496538908123969946e+00
2 | 1.257998045879602511e+00
3 | 1.146439006930589644e+00
4 | 1.095848687407374289e+00
5 | 1.059380434823036232e+00
6 | 1.029195302659273059e+00
7 | 1.004549385365843817e+00
8 | 9.767368407040833977e-01
9 | 9.582664603412150983e-01
10 | 9.425074189394712088e-01
11 | 9.286693536251783287e-01
12 | 9.149164662480354648e-01
13 | 9.021934506341815485e-01
14 | 8.881664996087551556e-01
15 | 8.808592478379607682e-01
16 | 8.674960011214017941e-01
17 | 8.568784933090209943e-01
18 | 8.401622610181570527e-01
19 | 8.321849884554743948e-01
20 | 8.175077314525842631e-01
21 | 8.011071323052049165e-01
22 | 7.911748012885451153e-01
23 | 7.759259826585650499e-01
24 | 7.611166337728499931e-01
25 | 7.434809941619634488e-01
26 | 7.278668548434972241e-01
27 | 7.116137386247515240e-01
28 | 6.960380281150341242e-01
29 | 6.869022204510867313e-01
30 | 6.795899570740759899e-01
31 |
--------------------------------------------------------------------------------
/results/SGD_Cosine_Lr0.05_DN4_Conv64F_Local_Epoch_30_miniImageNet_84_84_5Way_5Shot/val_loss.txt:
--------------------------------------------------------------------------------
1 | 1.386973905324935918e+00
2 | 1.162551319837570096e+00
3 | 1.106109781026840100e+00
4 | 1.060794358670711590e+00
5 | 1.056823077559471136e+00
6 | 1.032484755963086975e+00
7 | 9.956440748572349397e-01
8 | 9.643782387077808327e-01
9 | 9.402065452635288700e-01
10 | 9.695851418972015745e-01
11 | 9.229096755981445188e-01
12 | 9.295306026339530403e-01
13 | 9.344420723021030772e-01
14 | 8.799210217893123076e-01
15 | 9.087069990336894554e-01
16 | 8.725697695910931140e-01
17 | 8.700383878946303939e-01
18 | 8.599405329823494037e-01
19 | 8.809840641617775470e-01
20 | 8.594751699566841596e-01
21 | 8.228730600774287751e-01
22 | 8.301036271154880186e-01
23 | 8.254547930657863963e-01
24 | 8.042804000973701184e-01
25 | 8.040184194743633661e-01
26 | 7.724396421313285410e-01
27 | 7.655473987609148212e-01
28 | 7.647515845596790651e-01
29 | 7.482675210982561165e-01
30 | 7.426448170393705750e-01
31 |
--------------------------------------------------------------------------------
/results/test:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import os
3 | import pdb
4 | import scipy as sp
5 | import scipy.stats
6 | import numpy as np
7 | import matplotlib
8 | import matplotlib.pyplot as plt
9 |
10 |
11 |
12 | def adjust_learning_rate(opt, optimizer, epoch, F_txt):
13 | """Sets the learning rate to the initial LR decayed by 2 every 10 epoches"""
14 | if opt.classifier_model == 'Baseline':
15 | lr = opt.lr * (0.5 ** (epoch // 30))
16 | else:
17 | lr = opt.lr * (0.1 ** (epoch // 10))
18 | print('Learning rate: %f' %lr)
19 | print('Learning rate: %f' %lr, file=F_txt)
20 | for param_group in optimizer.param_groups:
21 | param_group['lr'] = lr
22 |
23 |
24 | def adjust_learning_rate2(opt, optimizer, epoch, F_txt):
25 | """Sets the learning rate to the initial LR decayed by decay rate every steep step"""
26 | steps = np.sum(epoch > np.asarray(opt.lr_decay_epochs))
27 | if steps > 0:
28 | new_lr = opt.lr * (opt.lr_decay_rate ** steps)
29 | print('Learning rate: %f' %new_lr)
30 | print('Learning rate: %f' %new_lr, file=F_txt)
31 | for param_group in optimizer.param_groups:
32 | param_group['lr'] = new_lr
33 |
34 |
35 | def count_parameters(model):
36 | """Count the total number of parameters in one model"""
37 | return sum(p.numel() for p in model.parameters() if p.requires_grad)
38 |
39 |
40 | def save_checkpoint(state, filename='checkpoint.pth.tar'):
41 | torch.save(state, filename)
42 |
43 |
44 | class AverageMeter(object):
45 | """Computes and stores the average and current value"""
46 | def __init__(self):
47 | self.reset()
48 |
49 | def reset(self):
50 | self.val = 0
51 | self.avg = 0
52 | self.sum = 0
53 | self.count = 0
54 |
55 | def update(self, val, n=1):
56 | self.val = val
57 | self.sum += val * n
58 | self.count += n
59 | self.avg = self.sum / self.count
60 |
61 |
62 | def accuracy(output, target, topk=(1,)):
63 | """Computes the precision@k for the specified values of k"""
64 | with torch.no_grad():
65 | maxk = max(topk)
66 | batch_size = target.size(0)
67 |
68 | _, pred = output.topk(maxk, 1, True, True)
69 | pred = pred.t()
70 | correct = pred.eq(target.view(1, -1).expand_as(pred))
71 |
72 | res = []
73 | for k in topk:
74 | correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)
75 | res.append(correct_k.mul_(100.0 / batch_size))
76 | return res
77 |
78 |
79 | def mean_confidence_interval(data, confidence=0.95):
80 | a = [1.0*np.array(data[i].cpu()) for i in range(len(data))]
81 | n = len(a)
82 | m, se = np.mean(a), scipy.stats.sem(a)
83 | h = se * sp.stats.t._ppf((1+confidence)/2., n-1)
84 | return m,h
85 |
86 |
87 |
88 | def set_save_path(opt):
89 | '''
90 | Settings of the save path
91 | '''
92 | opt.outf = opt.outf + opt.classifier_model + '_' + opt.encoder_model + '_' + 'Epoch_' + str(opt.epochs) + '_' +\
93 | opt.data_name + '_' + str(opt.imageSize) + '_' + str(opt.imageSize) + '_' + str(opt.way_num)+'Way_'+str(opt.shot_num)+'Shot'
94 |
95 | if not os.path.exists(opt.outf):
96 | os.makedirs(opt.outf)
97 |
98 | if torch.cuda.is_available() and not opt.cuda:
99 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
100 |
101 | # save the opt and results to txt file
102 | txt_save_path = os.path.join(opt.outf, 'opt_results.txt')
103 | F_txt = open(txt_save_path, 'a+')
104 |
105 | return opt.outf, F_txt
106 |
107 |
108 |
109 |
110 | def set_save_test_path(opt, finetune=False):
111 | '''
112 | Settings of the save path
113 | '''
114 |
115 | if not os.path.exists(opt.outf):
116 | os.makedirs(opt.outf)
117 |
118 | if torch.cuda.is_available() and not opt.cuda:
119 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
120 |
121 | # save the opt and results to txt file
122 | if finetune:
123 | txt_save_path = os.path.join(opt.outf, 'Test_Finetune_results.txt')
124 | else:
125 | txt_save_path = os.path.join(opt.outf, 'Test_results.txt')
126 | F_txt_test = open(txt_save_path, 'a+')
127 |
128 | return F_txt_test
129 |
130 |
131 |
132 | def set_save_test_path2(opt, finetune=False):
133 | '''
134 | Settings of the save path
135 | '''
136 |
137 | if not str(opt.resume).endswith('/'):
138 | opt.outf = opt.resume + '/'
139 | else:
140 | opt.outf = opt.resume
141 |
142 | if not os.path.exists(opt.outf):
143 | os.makedirs(opt.outf)
144 |
145 | if torch.cuda.is_available() and not opt.cuda:
146 | print("WARNING: You have a CUDA device, so you should probably run with --cuda")
147 |
148 | # save the opt and results to txt file
149 | if finetune:
150 | txt_save_path = os.path.join(opt.outf, 'Test_Finetune_results_New.txt')
151 | else:
152 | txt_save_path = os.path.join(opt.outf, 'Test_results_New.txt')
153 | F_txt_test = open(txt_save_path, 'a+')
154 |
155 | return opt.outf, F_txt_test
156 |
157 |
158 |
159 | def get_resume_file(checkpoint_dir, F_txt):
160 |
161 | if os.path.isfile(checkpoint_dir):
162 | print("=> loading checkpoint '{}'".format(checkpoint_dir))
163 | print("=> loading checkpoint '{}'".format(checkpoint_dir), file=F_txt)
164 | checkpoint = torch.load(checkpoint_dir)
165 | print("=> loaded checkpoint '{}' (epoch {})".format(checkpoint_dir, checkpoint['epoch_index']))
166 | print("=> loaded checkpoint '{}' (epoch {})".format(checkpoint_dir, checkpoint['epoch_index']), file=F_txt)
167 |
168 | return checkpoint
169 | else:
170 | print("=> no checkpoint found at '{}'".format(checkpoint_dir))
171 | print("=> no checkpoint found at '{}'".format(checkpoint_dir), file=F_txt)
172 |
173 | return None
174 |
175 |
176 | def plot_loss_curve(opt, train_loss, val_loss, test_loss=None):
177 |
178 | if test_loss:
179 | train_loss = np.array(train_loss)
180 | val_loss = np.array(val_loss)
181 | test_loss = np.array(test_loss)
182 |
183 |
184 | # Save lossed to txt
185 | np.savetxt(os.path.join(opt.outf, 'train_loss.txt'), train_loss)
186 | np.savetxt(os.path.join(opt.outf, 'val_loss.txt'), val_loss)
187 | np.savetxt(os.path.join(opt.outf, 'test_loss.txt'), test_loss)
188 |
189 | # Plot the loss curves
190 | fig, ax = plt.subplots()
191 | ax.plot(range(0, opt.epochs), train_loss, label='Train loss')
192 | ax.plot(range(0, opt.epochs), val_loss, label='Val loss')
193 | ax.plot(range(0, opt.epochs), test_loss, label='Test loss')
194 | legend = ax.legend(loc='upper right', fontsize='medium')
195 | plt.savefig(os.path.join(opt.outf, 'Loss.png'), bbox_inches='tight')
196 | # plt.show()
197 | else:
198 | train_loss = np.array(train_loss)
199 | val_loss = np.array(val_loss)
200 |
201 |
202 | # Save lossed to txt
203 | np.savetxt(os.path.join(opt.outf, 'train_loss.txt'), train_loss)
204 | np.savetxt(os.path.join(opt.outf, 'val_loss.txt'), val_loss)
205 |
206 |
207 | # Plot the loss curves
208 | fig, ax = plt.subplots()
209 | ax.plot(range(0, opt.epochs), train_loss, label='Train loss')
210 | ax.plot(range(0, opt.epochs), val_loss, label='Val loss')
211 | legend = ax.legend(loc='upper right', fontsize='medium')
212 | plt.savefig(os.path.join(opt.outf, 'Loss.png'), bbox_inches='tight')
213 | # plt.show()
214 |
215 |
216 |
217 |
218 |
219 |
220 |
--------------------------------------------------------------------------------