Yikai-Wang/ICI-FSL

miniimagenet experiment

rp775 opened this issue · 1 comments

rp775 commented

Hi Yikai-Wang:
Thanks for paper and code. it looks interesting . I am trying to understand ICI implementation.
I tried to run the code with miniimagenet pre trained model and it is working.

python main.py -g 0 --dataset miniimagenet --mode test --unlabel 5 --num-batches 16 --num_shots 1 --num_test_ways 2 --resume ckpt/res12_mini.pth.tar

But having few question. could you please clarify them when you get a chance.?

Question 1:
But i couldn't understand why you are create target and generating test/train/unlabeled set from this line 1. based on my understanding from paper that we need to read test data from dataloader[from test csv file] and use it here right?

Line 1:
targets = torch.arange(args.num_test_ways).repeat(args.num_shots+15+args.unlabel).long()[indicator[:args.num_test_ways*(args.num_shots+15+args.unlabel)] != 0]


indicator VALUE
tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
targets VALUE
tensor([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1])
Here we generated target value- what was the reason? any inside on this

Line 2:
data = data[indicator != 0].to(args.device)
train_inputs = data[:k]
train_targets = targets[:k].cpu().numpy()
test_inputs = data[k:k+15args.num_test_ways]
test_targets = targets[k:k+15
args.num_test_ways].cpu().numpy()

Question 2:
test.csv file has both data and label [same as val and train]. why we need to pass label for test data.

Question 3:
Does this ICI approach only works for classification task. can we use this approach for segmentation task. whats your though on this?

Q1:
The reason is that our episode is constructed with samples from all classes one by one. As in your experiments, we have 2 classes, each of which contains 1 labeled data, 5 unlabeled data, 15 test data (the number is fixed by code). Hence we have 2*(1+5+15)=52 samples in total. Then our dataloader will first sample 1 data from the first class, and then 1 data from the second class, and again and again until all the data are sampled. Hence we simply generate the target following the sample strategy.
See the following codes for more details.

ICI-FSL/datasets.py

Lines 64 to 99 in f2537b7

class CategoriesSampler():
def __init__(self, label, n_batch, n_cls, n_per):
self.n_batch = n_batch #num_batches
self.n_cls = n_cls # test_ways
self.n_per = np.sum(n_per) # num_per_class
self.number_distract = n_per[-1]
label = np.array(label)
self.m_ind = []
for i in range(max(label) + 1):
ind = np.argwhere(label == i).reshape(-1)
ind = torch.from_numpy(ind)
self.m_ind.append(ind)
def __len__(self):
return self.n_batch
def __iter__(self):
for i_batch in range(self.n_batch):
batch = []
indicator_batch = []
classes = torch.randperm(len(self.m_ind))
trad_classes = classes[:self.n_cls]
for c in trad_classes:
l = self.m_ind[c]
pos = torch.randperm(len(l))[:self.n_per]
cls_batch = l[pos]
cls_indicator = np.zeros(self.n_per)
cls_indicator[:cls_batch.shape[0]] = 1
if cls_batch.shape[0] != self.n_per:
cls_batch = torch.cat([cls_batch, -1*torch.ones([self.n_per-cls_batch.shape[0]]).long()], 0)
batch.append(cls_batch)
indicator_batch.append(cls_indicator)
batch = torch.stack(batch).t().reshape(-1)
yield batch

Q2:
Passing labels for test data is for computing the accuracy.
Q3:
We haven't tried this. Maybe a point you need to consider is that the time complexity of ICI grows fast as the number of samples increases, which makes it not very scalable to problems with big data.