def __init__(self, model_func, entropy, train_param, test_param): super(Baseline, self).__init__() if train_param['shake']: self.feature = model_func(shake_config=train_param['shake_config']) else: self.feature = model_func() self.num_classes = train_param['num_classes'] self.train_num_way = train_param['num_way'] self.train_num_shot = train_param['num_shot'] self.train_num_query = train_param['num_query'] self.test_num_way = test_param['num_way'] self.test_num_shot = test_param['num_shot'] self.test_num_query = test_param['num_query'] self.episodic = train_param['episodic'] self.train_loss_type = train_param['loss_type'] self.train_temperature = train_param['temperature'] self.train_margin = train_param['margin'] self.train_lr = train_param['lr'] self.shake = train_param['shake'] self.shake_config = train_param['shake_config'] self.test_loss_type = test_param['loss_type'] self.test_temperature = test_param['temperature'] self.test_margin = test_param['margin'] self.test_lr = test_param['lr'] self.final_feat_dim = self.feature.final_feat_dim self.entropy = entropy if self.train_loss_type == 'softmax': self.train_classifier = nn.Linear(self.final_feat_dim, self.num_classes) self.train_classifier.bias.data.fill_(0) self.train_classifier.apply(init_weights) elif self.train_loss_type == 'dist': # Baseline ++ self.train_classifier = backbone.distLinear(self.final_feat_dim, self.num_classes, self.train_temperature, None) elif self.train_loss_type == 'lsoftmax': self.train_classifier = LSoftmaxLinear(self.final_feat_dim, self.num_classes, self.train_margin) self.train_classifier.reset_parameters() elif self.train_loss_type == 'ldist': self.train_classifier = backbone.distLinear(self.final_feat_dim, self.num_classes, self.train_temperature, self.train_margin) elif self.train_loss_type == 'msoftmax': self.train_classifier = MetrixSoftmax(self.final_feat_dim, self.num_classes, self.train_temperature) if self.episodic and self.entropy: self.entropy_layer = nn.Linear(self.final_feat_dim, self.num_classes) self.entropy_layer.apply(init_weights) self.train_loss_softmax = nn.CrossEntropyLoss()
def set_forward_adaptation(self, x, is_feature=False): # just for finetuning # almost the same with MetaTemplate, except linear_clf & loss_function part # exactly the same with BaselineFinetune, except the assertion. # freeze feature network # reset to trainable for par in self.feature.parameters(): par.requires_grad = False z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) linear_clf = linear_clf.cuda() set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) # BUGFIX: BaselineFinetune has no attribute 'loss_fn' loss_function = self.loss_fn batch_size = 4 support_size = self.n_way * self.n_support # an epoch is just go through support set once n_epoch = 20 #100 for epoch in range(n_epoch): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) loss.backward() set_optimizer.step() scores = linear_clf(z_query) # reset to trainable for par in self.feature.parameters(): par.requires_grad = True return scores
def __init__(self, model_func, num_class, n_way, n_support, loss_type='softmax', change_way=True): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == 'softmax': self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': #Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss() self.DBval = False #only set True for CUB dataset, see issue #31 # self.DBval = True; #only set True for CUB dataset, see issue #31 # only for validation fine-tuning self.n_way = n_way self.n_support = n_support self.n_query = -1 #(change depends on input) self.feat_dim = self.feature.final_feat_dim self.change_way = change_way #some methods allow different_way classification during training and test
def log_p_y(self, xs, xq, no_grad=False, mask=None): del no_grad del mask self.check_feat_dim(xs) self.encoder.eval() way, shot, c, h, w = xs.shape n_query = xq.shape[1] if xq.shape[0] == 1: n_query = n_query // way assert way == self.n_way and shot == self.n_support with torch.no_grad(): z_support = self.encoder(xs.view(-1, c, h, w)) z_query = self.encoder(xq.view(-1, c, h, w)) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) linear_clf = linear_clf.cuda() set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) loss_function = nn.CrossEntropyLoss() loss_function = loss_function.cuda() batch_size = 4 support_size = self.n_way * self.n_support for epoch in range(100): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id].detach() y_batch = y_support[selected_id] scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) loss.backward() set_optimizer.step() scores = linear_clf(z_query) # Ret vals ret_dict = {} ret_dict['logits'] = scores.view(way, n_query, -1) ret_dict['log_p_y'] = F.log_softmax(scores, -1).view(way, n_query, -1) n_class = way target_inds = torch.arange(0, n_class).view(n_class, 1, 1).expand( n_class, n_query, 1).long().to(scores.device) ret_dict['target_inds'] = target_inds return ret_dict
def __init__(self, model_func, num_class, loss_type): super(BaselineTrain, self).__init__() self.feature = model_func() self.classifier = backbone.distLinear(self.feature.final_feat_dim[0], num_class) self.loss_type = loss_type self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss()
def set_forward_adaptation(self, x, is_feature=True): assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = y_support.to(self.device) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way, self.init_ortho) linear_clf = linear_clf.to(self.device) set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, self.wd) loss_function = nn.CrossEntropyLoss() loss_function = loss_function.to(self.device) batch_size = 4 support_size = self.n_way * self.n_support for epoch in range(100): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) if self.ortho: if self.loss_type == 'dist': #Baseline ++ oloss = l2_reg_ortho(linear_clf.L.weight, self.device) else: oloss = l2_reg_ortho(linear_clf.weight, self.device) else: oloss = 0.0 loss = loss + 1e-4 * oloss loss.backward() set_optimizer.step() scores = linear_clf(z_query) return scores
def set_forward_adaptation(self, x, is_feature=True): assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.loss_type == 'softmax': linear_clf = nn.Sequential( torch.nn.Linear(self.feat_dim, self.feat_dim), torch.nn.ReLU(), torch.nn.Linear(self.feat_dim, self.n_way)) #linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) linear_clf = linear_clf.cuda() #set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr = 0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01) loss_function = nn.CrossEntropyLoss() loss_function = loss_function.cuda() loss_function_ = snn_loss(1.0, True, cuda=True, optimized=False) #loss_function_ = loss_function_.cuda() batch_size = 25 epochs = 100 support_size = self.n_way * self.n_support for epoch in range(epochs): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] scores = linear_clf(z_batch) embeds = linear_clf[-2](z_batch) # loss = loss_function(scores,y_batch) print(loss_function_(embeds, y_batch)) print(loss_function(scores, y_batch)) loss = loss_function( scores, y_batch) - 10.0 * loss_function_(embeds, y_batch) print("Tot loss", loss) loss.backward() set_optimizer.step() scores = linear_clf(z_query) return scores
def __init__(self, model_func, num_class, dataset, loss_type='softmax'): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == 'softmax': if dataset == 'CIFARFS': self.classifier = nn.Linear(256, num_class) else: self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': #Baseline ++ if dataset == 'CIFARFS': self.classifier = backbone.distLinear(256, num_class) else: self.classifier = backbone.distLinear( self.feature.final_feat_dim, num_class) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss() self.DBval = False
def __init__(self, model_func, num_class, loss_type = 'softmax'): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == 'softmax': self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': #Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss() self.DBval = False; #only set True for CUB dataset, see issue #31
def __init__(self, model_func, num_class, loss_type="softmax"): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == "softmax": self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == "dist": # Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss()
def set_forward_adaptation(self, x, is_feature=True): # almost the same with MetaTemplate, except linear_clf & loss_function part assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.finetune_dropout_p is not None: dropout = nn.Dropout(p=self.finetune_dropout_p) #.cuda()? if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) linear_clf = linear_clf.cuda() set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) # BUGFIX: BaselineFinetune has no attribute 'loss_fn' loss_function = self.loss_fn batch_size = 4 support_size = self.n_way * self.n_support for epoch in range(100): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] if self.finetune_dropout_p is not None: z_batch = dropout(z_batch) scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) loss.backward() set_optimizer.step() scores = linear_clf(z_query) return scores
def set_forward_adaptation(self, x, is_feature=True): """ z_support : (Ns*C): (25*640) z_query : (Nq*C): (2975*640) """ assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) # TODO: for moco elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) ### for moco # linear_clf = backbone.distLinear(128, self.n_way) linear_clf = linear_clf.cuda() set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) loss_function = nn.CrossEntropyLoss() loss_function = loss_function.cuda() batch_size = 4 support_size = self.n_way * self.n_support scores_eval = [] for epoch in range(301): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) loss.backward() set_optimizer.step() if epoch % 100 == 0 and epoch != 0: scores_eval.append(linear_clf(z_query)) return scores_eval
def __init__(self, depth=28, widen_factor=10, num_classes=200, loss_type='dist', per_img_std=False, stride=1, dropRate=0.5): flatten = True super(WideResNet, self).__init__() nChannels = [ 16, 16 * widen_factor, 32 * widen_factor, 64 * widen_factor ] assert ((depth - 4) % 6 == 0) n = (depth - 4) / 6 block = BasicBlock # 1st conv before any network block self.conv1 = nn.Conv2d(3, nChannels[0], kernel_size=3, stride=1, padding=1, bias=False) # 1st block self.block1 = NetworkBlock(n, nChannels[0], nChannels[1], block, stride, dropRate) # 2nd block self.block2 = NetworkBlock(n, nChannels[1], nChannels[2], block, 2, dropRate) # 3rd block self.block3 = NetworkBlock(n, nChannels[2], nChannels[3], block, 2, dropRate) # global average pooling and linear self.bn1 = nn.BatchNorm2d(nChannels[3]) self.relu = nn.ReLU(inplace=True) self.nChannels = nChannels[3] if loss_type == 'softmax': self.linear = nn.Linear(nChannels[3], int(num_classes)) self.linear.bias.data.fill_(0) else: self.linear = backbone.distLinear(nChannels[3], int(num_classes)) self.num_classes = num_classes if flatten: self.final_feat_dim = 640 for m in self.modules(): if isinstance(m, nn.Conv2d): n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels m.weight.data.normal_(0, math.sqrt(2. / n)) elif isinstance(m, nn.BatchNorm2d): m.weight.data.fill_(1) m.bias.data.zero_()
def __init__(self, model_func, num_class, num_shot, train_temperature, test_temperature, loss_type, margin): super(Baseline, self).__init__() self.feature = model_func() self.num_class = num_class self.num_shot = num_shot self.train_temperature = train_temperature self.test_temperature = test_temperature self.loss_type = loss_type self.margin = margin self.final_feature_dim = self.feature.final_feat_dim if loss_type == 'softmax': self.classifier = nn.Linear(self.final_feat_dim, self.num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': # Baseline ++ self.classifier = backbone.distLinear(self.final_feat_dim, self.num_class, self.temperature) elif loss_type == 'lsoftmax': self.classifier = LSoftmaxLinear(self.final_feat_dim, self.num_class, self.margin) self.classifier.reset_parameters() elif loss_type == 'ldist': self.classifier = backbone.distLinear(self.final_feat_dim, self.num_class, self.temperature, self.margin) self.loss_softmax = nn.CrossEntropyLoss().cuda()
def __init__(self, model_func, num_class, loss_type = 'softmax', init_orthogonal = False, ortho_reg = None, device = None): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == 'softmax': self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': #Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class, init_orthogonal) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss() self.ortho = ortho_reg self.device = device
def set_forward_adaptation(self, x, is_feature=True): assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(to_cuda(y_support)) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) elif self.loss_type == 'dist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way) linear_clf = to_cuda(linear_clf) set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) loss_function = nn.CrossEntropyLoss() loss_function = to_cuda(loss_function) batch_size = 4 support_size = self.n_way * self.n_support for epoch in range(100): rand_id = np.random.permutation(support_size) for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = to_cuda( torch.from_numpy(rand_id[i:min(i + batch_size, support_size)])) z_batch = z_support[selected_id] y_batch = y_support[selected_id] scores = linear_clf(z_batch) loss = loss_function(scores, y_batch) loss.backward() set_optimizer.step() scores = linear_clf(z_query) return scores
def __init__(self, model_func, num_class, loss_type='softmax'): super(BaselineTrain, self).__init__() self.feature = model_func() if loss_type == 'softmax': self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) self.loss_fn = nn.CrossEntropyLoss() elif loss_type == 'dist': #Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class) self.loss_fn = nn.CrossEntropyLoss() elif loss_type == 'bce': linear = nn.Linear(self.feature.final_feat_dim, 312) linear.bias.data.fill_(0) self.classifier = nn.Sequential(linear, nn.Sigmoid()) self.loss_fn = nn.BCELoss() self.loss_type = loss_type self.num_class = num_class
def __init__(self, model_func, num_class, loss_type='softmax', jigsaw=False, lbda=0.0, rotation=False, ortho_loss=False, ortho_factor=1, tracking=True, pretrain=False): super(BaselineTrain, self).__init__() self.jigsaw = jigsaw self.lbda = lbda self.rotation = rotation self.tracking = tracking print('tracking in baseline train:', tracking) self.pretrain = pretrain print("USE pre-trained model:", pretrain) self.ortho_loss = ortho_loss self.ortho_factor = ortho_factor self.loss_factor = ortho_factor if isinstance(model_func, str): if model_func == 'resnet18': self.feature = ResidualNet('ImageNet', 18, 1000, None, tracking=self.tracking) self.feature.final_feat_dim = 512 elif model_func == 'resnet18_pytorch': self.feature = resnet18(pretrained=self.pretrain, tracking=self.tracking) self.feature.final_feat_dim = 512 elif model_func == 'resnet50_pytorch': self.feature = resnet50(pretrained=self.pretrain, tracking=self.tracking) self.feature.final_feat_dim = 2048 else: self.feature = model_func() if loss_type == 'softmax': self.classifier = nn.Linear(self.feature.final_feat_dim, num_class) self.classifier.bias.data.fill_(0) elif loss_type == 'dist': #Baseline ++ self.classifier = backbone.distLinear(self.feature.final_feat_dim, num_class) self.loss_type = loss_type #'softmax' #'dist' self.num_class = num_class self.loss_fn = nn.CrossEntropyLoss() self.global_count = 0 if self.jigsaw: self.fc6 = nn.Sequential() self.fc6.add_module('fc6_s1', nn.Linear(512, 512)) #for resnet self.fc6.add_module('relu6_s1', nn.ReLU(inplace=True)) self.fc6.add_module('drop6_s1', nn.Dropout(p=0.5)) self.fc7 = nn.Sequential() self.fc7.add_module('fc7', nn.Linear(9 * 512, 4096)) #for resnet self.fc7.add_module('relu7', nn.ReLU(inplace=True)) self.fc7.add_module('drop7', nn.Dropout(p=0.5)) self.classifier_jigsaw = nn.Sequential() self.classifier_jigsaw.add_module('fc8', nn.Linear(4096, 35)) if self.rotation: self.fc6 = nn.Sequential() self.fc6.add_module('fc6_s1', nn.Linear(512, 512)) #for resnet self.fc6.add_module('relu6_s1', nn.ReLU(inplace=True)) self.fc6.add_module('drop6_s1', nn.Dropout(p=0.5)) self.fc7 = nn.Sequential() self.fc7.add_module('fc7', nn.Linear(512, 128)) #for resnet self.fc7.add_module('relu7', nn.ReLU(inplace=True)) self.fc7.add_module('drop7', nn.Dropout(p=0.5)) self.classifier_rotation = nn.Sequential() self.classifier_rotation.add_module('fc8', nn.Linear(128, 4))
def test_loop(self, cl_data_file): if self.test_loss_type == 'softmax': classifier = nn.Linear(self.final_feat_dim, self.test_num_way) classifier.bias.data.fill_(0) elif self.test_loss_type == 'dist': # Baseline ++ classifier = backbone.distLinear(self.final_feat_dim, self.train_num_way, self.test_temperature, None) elif self.test_loss_type == 'lsoftmax': classifier = LSoftmaxLinear(self.final_feat_dim, self.test_num_way, self.test_margin) classifier.reset_parameters() elif self.test_loss_type == 'ldist': classifier = backbone.distLinear(self.final_feat_dim, self.test_num_way, self.test_temperature, self.test_margin) classifier = classifier.cuda() test_loss_softmax = nn.CrossEntropyLoss().cuda() class_list = cl_data_file.keys() select_class = random.sample(class_list, self.test_num_way) z_all = [] for cl in select_class: img_feat = cl_data_file[cl] perm_ids = np.random.permutation(len(img_feat)).tolist() z_all.append([np.squeeze(img_feat[perm_ids[i]]) for i in range(self.test_num_shot + self.test_num_query)]) # stack each batch z_all = torch.from_numpy(np.array(z_all)) z_all = Variable(z_all.cuda()) z_support, z_query = self.parse_feature(z_all, True) z_support = z_support.contiguous().view(self.test_num_way * self.test_num_shot, -1) z_query = z_query.contiguous().view(self.test_num_way * self.test_num_query, -1) y_support = torch.from_numpy(np.repeat(range(self.test_num_way), self.test_num_shot)) y_support = Variable(y_support.cuda()) optimizer = torch.optim.SGD(classifier.parameters(), lr=self.test_lr, momentum=0.9, dampening=0.9, weight_decay=0.001) batch_size = 4 support_size = self.test_num_way * self.test_num_shot for episode in range(100): rand_id = np.random.permutation(support_size) classifier.train() for i in range(0, support_size, batch_size): optimizer.zero_grad() selected_id = torch.from_numpy(rand_id[i: min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] if self.test_loss_type == 'softmax': scores = classifier(z_batch) else: scores = classifier(z_batch, y_batch) loss = test_loss_softmax(scores, y_batch) loss.backward() optimizer.step() classifier.eval() scores = classifier(z_query, None) pred = scores.data.cpu().numpy().argmax(axis=1) y = np.repeat(range(self.test_num_way), self.test_num_query) acc = np.mean(pred == y) * 100 return acc
def set_forward_adaptation(self, iter, x, writer, is_feature=True): assert is_feature == True, 'Baseline only support testing with feature' z_support, z_query = self.parse_feature(x, is_feature) z_support = z_support.contiguous().view(self.n_way * self.n_support, -1) z_query = z_query.contiguous().view(self.n_way * self.n_query, -1) y_support = torch.from_numpy( np.repeat(range(self.n_way), self.n_support)) y_support = Variable(y_support.cuda()) if self.loss_type == 'softmax': linear_clf = nn.Linear(self.feat_dim, self.n_way) linear_clf.bias.data.fill_(0) elif self.loss_type == 'dist': # Baseline ++ linear_clf = backbone.distLinear(self.feat_dim, self.n_way, self.temperature) elif self.loss_type == 'lsoftmax': linear_clf = LSoftmaxLinear(self.feat_dim, self.n_way, self.margin) linear_clf.reset_parameters() elif self.loss_type == 'ldist': linear_clf = backbone.distLinear(self.feat_dim, self.n_way, self.temperature, self.margin, True) linear_clf = linear_clf.cuda() set_optimizer = torch.optim.SGD(linear_clf.parameters(), lr=0.01, momentum=0.9, dampening=0.9, weight_decay=0.001) loss_function = nn.CrossEntropyLoss() loss_function = loss_function.cuda() if self.centered: loss_center = CenterLoss(num_classes=self.n_way, feat_dim=self.feature.final_feat_dim) loss_center = loss_center.cuda() batch_size = 4 support_size = self.n_way * self.n_support for epoch in range(100): rand_id = np.random.permutation(support_size) linear_clf.train() for i in range(0, support_size, batch_size): set_optimizer.zero_grad() selected_id = torch.from_numpy( rand_id[i:min(i + batch_size, support_size)]).cuda() z_batch = z_support[selected_id] y_batch = y_support[selected_id] if self.loss_type[0] == 'l': scores = linear_clf(z_batch, y_batch) else: scores = linear_clf(z_batch) if self.centered: loss = loss_function( scores, y_batch) + self.alpha * loss_center(z_batch, y_batch) else: loss = loss_function(scores, y_batch) writer.add_scalar('loss/test_loss', loss.item(), ((iter * 100 + epoch) * support_size + i) // batch_size) loss.backward() if self.centered: for param in loss_center.parameters(): param.grad.data *= (1. / self.alpha) set_optimizer.step() linear_clf.eval() scores = linear_clf(z_query, None) pred = scores.data.cpu().numpy().argmax(axis=1) y = np.repeat(range(self.n_way), self.n_query) acc = np.mean(pred == y) * 100 writer.add_scalar('acc/test_acc', acc.item(), iter) return scores