From fa66901861f0a58e6fd19905a2c8aefb7cb09981 Mon Sep 17 00:00:00 2001 From: Han-Jia Date: Thu, 26 Mar 2020 14:46:30 +0800 Subject: [PATCH] update FEAT --- README.md | 130 +++++++--- download_weight.sh | 7 +- eval_feat.py | 74 ------ eval_feat_star.py | 73 ------ eval_matchnet.py | 82 ------ eval_protonet.py | 73 ------ feat/dataloader/cub.py | 60 ----- feat/dataloader/mini_imagenet.py | 67 ----- feat/dataloader/mini_imagenet_pre.py | 90 ------- feat/dataloader/samplers.py | 32 --- feat/dataloader/tiered_imagenet.py | 72 ----- feat/models/feat.py | 124 --------- feat/models/matchnet.py | 93 ------- feat/models/protonet.py | 22 -- feat/utils.py | 79 ------ imgs/architecture.png | Bin 179072 -> 228942 bytes {feat => model}/__init__.py | 0 model/data_parallel.py | 90 +++++++ model/dataloader/cub.py | 123 +++++++++ model/dataloader/mini_imagenet.py | 122 +++++++++ model/dataloader/samplers.py | 92 +++++++ model/dataloader/tiered_imagenet.py | 120 +++++++++ model/logger.py | 44 ++++ model/models/__init__.py | 1 + model/models/base.py | 58 +++++ model/models/bilstm.py | 122 +++++++++ {feat => model}/models/classifier.py | 25 +- model/models/deepset.py | 118 +++++++++ model/models/feat.py | 148 +++++++++++ .../feat_star.py => model/models/featstar.py | 98 ++++--- model/models/graphnet.py | 176 +++++++++++++ model/models/matchnet.py | 54 ++++ model/models/protonet.py | 47 ++++ {feat => model}/networks/WRN28.py | 160 ++++++------ {feat => model}/networks/convnet.py | 0 model/networks/dropblock.py | 61 +++++ model/networks/res12.py | 125 +++++++++ .../resnet.py => model/networks/res18.py | 115 +++++--- {feat/models => model/trainer}/__init__.py | 0 model/trainer/base.py | 97 +++++++ model/trainer/fsl_trainer.py | 208 +++++++++++++++ model/trainer/helpers.py | 159 ++++++++++++ model/utils.py | 184 +++++++++++++ pretrain.py | 128 +++++---- train_feat.py | 227 ---------------- train_feat_star.py | 237 ----------------- train_fsl.py | 25 ++ train_matchnet.py | 245 ------------------ train_protonet.py | 222 ---------------- 49 files changed, 2588 insertions(+), 2121 deletions(-) delete mode 100644 eval_feat.py delete mode 100644 eval_feat_star.py delete mode 100644 eval_matchnet.py delete mode 100644 eval_protonet.py delete mode 100644 feat/dataloader/cub.py delete mode 100644 feat/dataloader/mini_imagenet.py delete mode 100644 feat/dataloader/mini_imagenet_pre.py delete mode 100644 feat/dataloader/samplers.py delete mode 100644 feat/dataloader/tiered_imagenet.py delete mode 100644 feat/models/feat.py delete mode 100644 feat/models/matchnet.py delete mode 100644 feat/models/protonet.py delete mode 100644 feat/utils.py rename {feat => model}/__init__.py (100%) create mode 100644 model/data_parallel.py create mode 100644 model/dataloader/cub.py create mode 100644 model/dataloader/mini_imagenet.py create mode 100644 model/dataloader/samplers.py create mode 100644 model/dataloader/tiered_imagenet.py create mode 100644 model/logger.py create mode 100644 model/models/__init__.py create mode 100644 model/models/base.py create mode 100644 model/models/bilstm.py rename {feat => model}/models/classifier.py (53%) create mode 100644 model/models/deepset.py create mode 100644 model/models/feat.py rename feat/models/feat_star.py => model/models/featstar.py (54%) create mode 100644 model/models/graphnet.py create mode 100644 model/models/matchnet.py create mode 100644 model/models/protonet.py rename {feat => model}/networks/WRN28.py (96%) rename {feat => model}/networks/convnet.py (100%) create mode 100644 model/networks/dropblock.py create mode 100644 model/networks/res12.py rename feat/networks/resnet.py => model/networks/res18.py (51%) rename {feat/models => model/trainer}/__init__.py (100%) create mode 100644 model/trainer/base.py create mode 100644 model/trainer/fsl_trainer.py create mode 100644 model/trainer/helpers.py create mode 100644 model/utils.py delete mode 100644 train_feat.py delete mode 100644 train_feat_star.py create mode 100644 train_fsl.py delete mode 100644 train_matchnet.py delete mode 100644 train_protonet.py diff --git a/README.md b/README.md index ff12e3b..fead138 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ The code repository for "[Few-Shot Learning via Embedding Adaptation with Set-to ## Few-Shot Embedding Adaptation with Transformer -Few-shot learning methods address this challenge by learning an instance embedding function from seen classes, and apply the function to instances from unseen classes with limited labels. This style of transfer learning is task-agnostic: the embedding function is not learned optimally discriminative with respect to the unseen classes, where discerning among them is the target task. In this work, we propose a novel approach to adapt the embedding model to the target classification task, yielding embeddings that are task-specific and are discriminative. To this end, we employ a type of self-attention mechanism called Transformer to transform the embeddings from task-agnostic to task-specific by focusing on relating instances from the test instances to the training instances in both seen and unseen classes. +Learning with limited data is a key challenge for visual recognition. Many few-shot learning methods address this challenge by learning an instance embedding function from seen classes and apply the function to instances from unseen classes with limited labels. This style of transfer learning is task-agnostic: the embedding function is not learned optimally discriminative with respect to the unseen classes, where discerning among them leads to the target task. In this paper, we propose a novel approach to adapt the instance embeddings to the target classification task with a #set-to-set# function, yielding embeddings that are task-specific and are discriminative. We empirically investigated various instantiations of such set-to-set functions and observed the Transformer is most effective --- as it naturally satisfies key properties of our desired model. We denote this model as FEAT (few-shot embedding adaptation w/ Transformer) and validate it on both the standard few-shot classification benchmark and four extended few-shot learning settings with essential use cases, i.e., cross-domain, transductive, generalized few-shot learning, and low-shot learning. It archived consistent improvements over baseline models as well as previous methods, and established the new state-of-the-art results on two benchmarks. ![Few-Shot Learning via Transformer](imgs/teaser.PNG) @@ -30,76 +30,133 @@ The MiniImageNet dataset is a subset of the ImageNet that includes a total numbe #### CUB Dataset [Caltech-UCSD Birds (CUB) 200-2011 dataset](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html) is initially designed for fine-grained classification. It contains in total 11,788 images of birds over 200 species. On CUB, we randomly sampled 100 species as SEEN classes, another two 50 species are used as two UNSEEN sets. We crop all images with given bounding box before training. We only test CUB with ConvNet backbone in our work. +#### TieredImageNet Dataset +[TieredImageNet](https://github.com/renmengye/few-shot-ssl-public) is a large-scale dataset with more categories, which contains 351, 97, and 160 categoriesfor model training, validation, and evaluation, respectively. The dataset can also be download from [here](https://github.com/kjunelee/MetaOptNet). +We only test TieredImageNet with ResNet backbone in our work. + Check [this](https://github.com/Sha-Lab/FEAT/blob/master/data/README.md) for details of data downloading and preprocessing. -### Model Evaluation +### Code Structures +To reproduce our experiments with FEAT, please use **train_fsl.py**. There are four parts in the code. + - `model`: It contains the main files of the code, including the few-shot learning trainer, the dataloader, the network architectures, and baseline and comparison models. + - `data`: Images and splits for the data sets. + - `saves`: The pre-trained weights of different networks. + - `checkpoints`: To save the trained models. -The learned model on MiniImageNet and CUB can be found in [this link](https://drive.google.com/open?id=1ZjkiEJh_96VYNWCOXUGsPuesLaFzV_z9). You can run **eval_xxx.py** to evaluate a given model, with options similar to the training scripts as below. For example, for a ConvNet model at "./saves/feat-model/xx.pth", it can be evaluated for 1-shot 5-way tasks by: +### Model Training and Evaluation +Please use **train_fsl.py** and follow the instructions blow. FEAT meta-learns the embedding adaptation process such that all the training instance embeddings in a task is adapted, based on their contextual task information, using Transformer. The file will automatically evaluate the model on the meta-test set with 10,000 tasks after given epoches. - $ python eval_feat.py --model_type ConvNet --dataset MiniImageNet --model_path ./saves/FEAT-Models/MiniIMageNet-Conv-1-Shot-5-Way.pth --shot 1 --way 5 --gpu 0 +#### Arguments +The train_fsl.py takes the following command line options (details are in the `model/utils.py`): -We presume the input model is a GPU stored model. +## Task Related Arguments ## +- `dataset`: Option for the dataset (`MiniImageNet`, `TieredImageNet`, or `CUB`), default to `MiniImageNet` -### Model Training +- `way`: The number of classes in a few-shot task during meta-training, default to `5` -#### FEAT Approach -To reproduce our experiments with FEAT, please use **train_feat.py** and follow the instructions blow. FEAT meta-learns the embedding adaptation process such that all the training instance embeddings in a task is adapted, based on their contextual task information, using Transformer. An extension FEAT* (**train_feat_star.py**), is also included, which incorporates the specific test instance in the context. +- `eval_way`: The number of classes in a few-shot task during meta-test, default to `5` + +- `shot`: Number of instances in each class in a few-shot task during meta-training, default to `1` + +- `eval_shot`: Number of instances in each class in a few-shot task during meta-test, default to `1` -The train_feat.py takes the following command line options: +- `query`: Number of instances in each class to evaluate the performance during meta-training, default to `15` +- `eval_query`: Number of instances in each class to evaluate the performance during meta-test, default to `15` + +## Optimization Related Arguments ## - `max_epoch`: The maximum number of training epochs, default to `200` -- `way`: The number of classes in a few-shot task, default to `5` +- `episodes_per_epoch`: The number of tasks sampled in each epoch, default to `100` + +- `num_eval_episodes`: The number of tasks sampled from the meta-val set to evaluate the performance of the model (note that we fix sampling 10,000 tasks from the meta-test set during final evaluation), default to `200` + +- `lr`: Learning rate for the model, default to `0.0001` with pre-trained weights + +- `lr_mul`: This is specially designed for set-to-set functions like FEAT. The learning rate for the top layer will be multiplied by this value (usually with faster learning rate). Default to `10` -- `shot`: Number of instances in each class in a few-shot task, default to `1` +- `lr_scheduler`: The scheduler to set the learning rate (`step`, `multistep`, or `cosine`), default to `step` -- `query`: Number of instances in each class to evaluate the performance in both meta-training and meta-test stages, default to `15` +- `step_size`: The step scheduler to decrease the learning rate. Set it to a single value if choose the `step` scheduler, and provide multiple values when choose the `multistep` scheduler. Default to `20` -- `lr`: Learning rate for the model, default to `0.0001` with pre-trained model +- `gamma`: Learning rate ratio for `step` or `multistep` scheduler, default to `0.2` -- `step_size`: StepLR learning rate scheduler step, default to `20` +- `fix_BN`: Set the encoder to the evaluation mode during the meta-training. This parameter is useful when meta-learning with the WRN. Default to `False` -- `gamma`: StepLR learning rate ratio, default to `0.2` +- `augment`: Whether to do data augmentation or not during meta-training, default to `False` -- `temperature`: Temperature over the logits, we divide logits with this value, default to `1` +- `mom`: The momentum value for the SGD optimizer, default to `0.9` -- `temperature2`: Temperature over the logits in the regularizer, we divide logits with this value, default to `16`. This is specially designed for FEAT (and in the train_feat.py). +- `weight_decay`: The weight_decay value for SGD optimizer, default to `0.0005` -- `model_type`: Two types of encoder, i.e., the convolution network and ResNet, default to `ConvNet` +## Model Related Arguments ## +- `model_class`: The model to use during meta-learning. We provide implementations for baselines (`MatchNet` and `ProtoNet`), set-to-set functions (`BILSTM`, `DeepSet`, `GCN`, and our `FEAT`). We also include an instance-specific embedding adaptation approach `FEAT`, which is discussed in the old version of the paper. Default to `FEAT` -- `dataset`: Option for the dataset (MiniImageNet or CUB), default to `MiniImageNet` +- `use_euclidean`: Use the euclidean distance or the cosine similarity to compute pairwise distances. We use the euclidean distance in the paper. Default to `False` -- `init_weights`: The path to the initial weights, default to `None` +- `backbone_class`: Types of the encoder, i.e., the convolution network (`ConvNet`), ResNet-12 (`Res12`), or Wide ResNet (`WRN`), default to `ConvNet` -- `gpu`: The index of GPU to use, default to `0` +- `balance`: This is the balance weight for the contrastive regularizer. Default to `0` -- `use_bilstm`: This is specially designed for Matching Network. If this is true, bi-LSTM is used for embedding adaptation. Default to `False` +- `temperature`: Temperature over the logits, we #divide# logits with this value. It is useful when meta-learning with pre-trained weights. Default to `1` -- `lr_mul`: This is specially designed for Matching Network with bi-LSTM and FEAT variants. The learning rate for the top layer will be multiplied by this value (usually with faster learning rate). Default to `10` +- `temperature2`: Temperature over the logits in the regularizer, we divide logits with this value. This is specially designed for the contrastive regularizer. Default to `1` -- `balance`: This is the weights for the FEAT variants regularizer. Default to `0.1` and `10` for FEAT and FEAT* respectively. +## Other Arguments ## +- `orig_imsize`: Whether to resize the images before loading the data into the memory. `-1` means we do not resize the images and do not read all images into the memory. Default to `-1` -Running the command without arguments will train the models with the default hyperparamters values. Loss changes will be recorded as a tensorboard file in the ./runs folder. +- `multi_gpu`: Whether to use multiple gpus during meta-training, default to `False` -For example, to train the 1-shot 5-way FEAT model with ConvNet backbone on MiniImageNet: +- `gpu`: The index of GPU to use. Please provide multiple indexes if choose `multi_gpu`. Default to `0` - $ python train_feat.py --lr 0.0001 --temperature 64 --temperature2 16 --max_epoch 200 --model_type ConvNet --dataset MiniImageNet --init_weights ./saves/initialization/miniimagenet/con-pre.pth --shot 1 --way 5 --gpu 0 --balance 0.1 --step_size 20 --gamma 0.5 --lr_mul 10 +- `log_interval`: How often to log the meta-training information, default to every `50` tasks - $ python train_feat_star.py --lr 0.0001 --temperature 32 --max_epoch 200 --model_type ConvNet --dataset MiniImageNet --init_weights ./saves/initialization/miniimagenet/con-pre.pth --shot 1 --way 5 --gpu 0 --balance 10 --step_size 50 --gamma 0.1 --lr_mul 10 +- `eval_interval`: How often to validate the model over the meta-val set, default to every `1` epoch -to train the 1-shot 5-way FEAT model with ResNet backbone on MiniImageNet: +- `save_dir`: The path to save the learned models, default to `./checkpoints` - $ python train_feat.py --lr 0.0001 --temperature 128 --temperature2 16 --max_epoch 100 --model_type ResNet --dataset MiniImageNet --init_weights ./saves/initialization/miniimagenet/res-pre.pth --shot 1 --way 5 --gpu 0 --balance 0.1 --step_size 10 --gamma 0.5 --lr_mul 10 +Running the command without arguments will train the models with the default hyperparamters values. Loss changes will be recorded as a tensorboard file. - $ python train_feat_star.py --lr 0.0001 --temperature 128 --max_epoch 100 --model_type ResNet --dataset MiniImageNet --init_weights ./saves/initialization/miniimagenet/res-pre.pth --shot 1 --way 5 --gpu 0 --balance 10 --step_size 10 --gamma 0.5 --lr_mul 10 +#### FEAT Approach + +For example, to train the 1-shot/5-shot 5-way FEAT model with ConvNet backbone on MiniImageNet: + + $ python train_fsl.py --max_epoch 200 --model_class FEAT --use_euclidean --backbone_class ConvNet --dataset MiniImageNet --way 5 --eval_way 5 --shot 1 --eval_shot 1 --query 15 --eval_query 15 --balance 1 --temperature 64 --temperature2 16 --lr 0.0001 --lr_mul 10 --lr_scheduler step --step_size 20 --gamma 0.5 --gpu 8 --init_weights ./saves/initialization/miniimagenet/con-pre.pth --eval_interval 1 + $ python train_fsl.py --max_epoch 200 --model_class FEAT --use_euclidean --backbone_class ConvNet --dataset MiniImageNet --way 5 --eval_way 5 --shot 5 --eval_shot 5 --query 15 --eval_query 15 --balance 0.1 --temperature 32 --temperature2 64 --lr 0.0001 --lr_mul 10 --lr_scheduler step --step_size 20 --gamma 0.5 --gpu 14 --init_weights ./saves/initialization/miniimagenet/con-pre.pth --eval_interval 1 + +to train the 1-shot/5-shot 5-way FEAT model with ResNet-12 backbone on MiniImageNet: -#### Baseline Methods -We implement two baseline approaches in this repo, i.e., the [Matching Network](https://arxiv.org/abs/1606.04080) and [Prototypical Network](https://arxiv.org/abs/1703.05175). To train the them on this task, cd into this repo's root folder and execute: + $ python train_fsl.py --max_epoch 200 --model_class FEAT --backbone_class Res12 --dataset MiniImageNet --way 5 --eval_way 5 --shot 1 --eval_shot 1 --query 15 --eval_query 15 --balance 0.01 --temperature 64 --temperature2 64 --lr 0.0002 --lr_mul 10 --lr_scheduler step --step_size 40 --gamma 0.5 --gpu 1 --init_weights ./saves/initialization/miniimagenet/Res12-pre.pth --eval_interval 1 --use_euclidean + $ python train_fsl.py --max_epoch 200 --model_class FEAT --backbone_class Res12 --dataset MiniImageNet --way 5 --eval_way 5 --shot 5 --eval_shot 5 --query 15 --eval_query 15 --balance 0.1 --temperature 64 --temperature2 32 --lr 0.0002 --lr_mul 10 --lr_scheduler step --step_size 40 --gamma 0.5 --gpu 0 --init_weights ./saves/initialization/miniimagenet/Res12-pre.pth --eval_interval 1 --use_euclidean - $ python train_matchnet.py (or python train_protonet.py) +to train the 1-shot/5-shot 5-way FEAT model with ResNet-12 backbone on TieredImageNet: + $ python train_fsl.py --max_epoch 200 --model_class FEAT --backbone_class Res12 --dataset TieredImageNet --way 5 --eval_way 5 --shot 1 --eval_shot 1 --query 15 --eval_query 15 --balance 0.1 --temperature 64 --temperature2 64 --lr 0.0002 --lr_mul 10 --lr_scheduler step --step_size 20 --gamma 0.5 --gpu 0 --init_weights ./saves/initialization/tieredimagenet/Res12-pre.pth --eval_interval 1 --use_euclidean + $ python train_fsl.py --max_epoch 200 --model_class FEAT --backbone_class Res12 --dataset TieredImageNet --way 5 --eval_way 5 --shot 5 --eval_shot 5 --query 15 --eval_query 15 --balance 0.1 --temperature 32 --temperature2 64 --lr 0.0002 --lr_mul 10 --lr_scheduler step --step_size 40 --gamma 0.5 --gpu 0 --init_weights ./saves/initialization/tieredimagenet/Res12-pre.pth --eval_interval 1 --use_euclidean -PS. The train_xxx.py scripts will evaluate the model with best validation accuracy at the end. +#### Results + +Results on the MiniImageNet: +| Setups | 1-Shot 5-Way | 1-Shot 5-Way | 5-Shot 5-Way | 5-Shot 5-Way | +|:--------:|:------------:|:------------:|:------------:|:------------:| +| Backbone | ConvNet | ResNet | ConvNet | ResNet | +|:--------:|:------------:|:------------:|:------------:|:------------:| +| ProtoNet | 52.61 | 62.39 | 71.33 | 80.53 | +| BILSTM | 52.13 | 63.90 | 69.15 | 80.63 | +| DEEPSETS | 54.41 | 64.14 | 70.96 | 80.93 | +| GCN | 53.25 | 64.50 | 70.59 | 81.65 | +|:--------:|:------------:|:------------:|:------------:|:------------:| +| FEAT | 55.15 | 66.78 | 71.61 | 82.05 | + +Results on the TieredImageNet with ResNet-12 backbone: +| Setups | 1-Shot 5-Way | 5-Shot 5-Way | +|:--------:|:------------:|:------------:| +| ProtoNet | 68.23 | 84.03 | +| BILSTM | 68.14 | 84.23 | +| DEEPSETS | 68.59 | 84.36 | +| GCN | 68.20 | 84.64 | +|:--------:|:------------:|:------------:| +| FEAT | 70.80 | 84.79 | ## .bib citation If this repo helps in your work, please cite the following paper: @@ -124,3 +181,6 @@ We thank following repos providing helpful components/functions in our work. - [PFA](https://github.com/joe-siyuan-qiao/FewShot-CVPR/) - [Transformer](https://github.com/jadore801120/attention-is-all-you-need-pytorch) + +- [MetaOptNet](https://github.com/kjunelee/MetaOptNet/) + diff --git a/download_weight.sh b/download_weight.sh index c7c6f65..0bd66ff 100644 --- a/download_weight.sh +++ b/download_weight.sh @@ -3,7 +3,7 @@ function download() { printf "\033[32mstart to download $2 in $current/saves/$1\033[0m\n" [[ -e $1.zip ]] && rm -rf $1.zip - wget -c https://doc-00-7o-docs.googleusercontent.com/docs/securesc/ha0ro937gcuc7l7deffksulhg5h7mbp1/jautjthvgoh3idbpvifflcpu1uo72846/1545379200000/09560182245773775633/*/1DFYbAta5mcMDtu1uW8f-8PFKsrHrTwJ0?e=download -O $1.zip + wget -c https://drive.google.com/uc?export=download&confirm=wWiE&id=1XcUZMNTQ-79_2AkNG3E04zh6bDYnPAMY -O $1.zip if [[ -e $1 ]]; then backup=$1.`date '+%Y%m%d%H%M%S'` echo "backup current $1 directory first" @@ -20,7 +20,4 @@ current=$(pwd) cd saves # Download pre-trained weights in "./saves/initialization". -download "initialization" "pre-trained weights" -echo "" -# Download learned models in "./saves/FEAT-Models" -download "FEAT-Models" "learned models" +download "initialization" "pre-trained weights" \ No newline at end of file diff --git a/eval_feat.py b/eval_feat.py deleted file mode 100644 index 458efac..0000000 --- a/eval_feat.py +++ /dev/null @@ -1,74 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader - -from feat.models.feat import FEAT -from feat.dataloader.samplers import CategoriesSampler -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - parser.add_argument('--model_path', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - args.temperature = 1 - args.head = 1 - pprint(vars(args)) - - set_gpu(args.gpu) - if args.dataset == 'MiniImageNet': - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - model = FEAT(args, dropout = 0.5) - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(args.model_path)['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/eval_feat_star.py b/eval_feat_star.py deleted file mode 100644 index d059a19..0000000 --- a/eval_feat_star.py +++ /dev/null @@ -1,73 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader - -from feat.models.feat_star import FEAT -from feat.dataloader.samplers import CategoriesSampler -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - parser.add_argument('--model_path', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - args.temperature = 1 - pprint(vars(args)) - - set_gpu(args.gpu) - if args.dataset == 'MiniImageNet': - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - model = FEAT(args, dropout = 0.5) - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(args.model_path)['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits, _ = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/eval_matchnet.py b/eval_matchnet.py deleted file mode 100644 index 82efb58..0000000 --- a/eval_matchnet.py +++ /dev/null @@ -1,82 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader -from feat.dataloader.samplers import CategoriesSampler -from feat.models.matchnet import MatchNet -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--use_bilstm', type=bool, default=False) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - parser.add_argument('--model_path', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - args.temperature = 1 - pprint(vars(args)) - - set_gpu(args.gpu) - - if args.dataset == 'MiniImageNet': - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - model = MatchNet(args) - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(args.model_path)['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - label_support = torch.arange(args.way).repeat(args.shot) - label_support = label_support.type(torch.LongTensor) - # transform to one-hot form - label_support_onehot = torch.zeros(args.way * args.shot, args.way) - label_support_onehot.scatter_(1, label_support.unsqueeze(1), 1) - if torch.cuda.is_available(): - label_support_onehot = label_support_onehot.cuda() # KN x N - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits = model(data_shot, data_query) # KqN x KN x 1 - # use logits to weights all labels, KN x N - prediction = torch.sum(torch.mul(logits, label_support_onehot.unsqueeze(0)), 1) # KqN x N - acc = count_acc(prediction, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/eval_protonet.py b/eval_protonet.py deleted file mode 100644 index 7803d68..0000000 --- a/eval_protonet.py +++ /dev/null @@ -1,73 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader -from feat.dataloader.samplers import CategoriesSampler -from feat.models.protonet import ProtoNet -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, compute_confidence_interval -from tensorboardX import SummaryWriter - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - parser.add_argument('--model_path', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - args.temperature = 1 # we set temperature = 1 during test since it does not influence the results - pprint(vars(args)) - - set_gpu(args.gpu) - - if args.dataset == 'MiniImageNet': - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - model = ProtoNet(args) - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(args.model_path)['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - - logits = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/feat/dataloader/cub.py b/feat/dataloader/cub.py deleted file mode 100644 index 69294bf..0000000 --- a/feat/dataloader/cub.py +++ /dev/null @@ -1,60 +0,0 @@ -import os.path as osp -import PIL -from PIL import Image - -import numpy as np -from torch.utils.data import Dataset -from torchvision import transforms - -THIS_PATH = osp.dirname(__file__) -ROOT_PATH = osp.abspath(osp.join(THIS_PATH, '..', '..')) -IMAGE_PATH = osp.join(ROOT_PATH, 'data/cub/images') -SPLIT_PATH = osp.join(ROOT_PATH, 'data/cub/split') - -# This is for the CUB dataset, which does not support the ResNet encoder now -# It is notable, we assume the cub images are cropped based on the given bounding boxes -# The concept labels are based on the attribute value, which are for further use (and not used in this work) -class CUB(Dataset): - - def __init__(self, setname, args): - txt_path = osp.join(SPLIT_PATH, setname + '.csv') - lines = [x.strip() for x in open(txt_path, 'r').readlines()][1:] - - data = [] - label = [] - lb = -1 - self.wnids = [] - - for l in lines: - context = l.split(',') - name = context[0] - wnid = context[1] - path = osp.join(IMAGE_PATH, name) - if wnid not in self.wnids: - self.wnids.append(wnid) - lb += 1 - - data.append(path) - label.append(lb) - - self.data = data - self.label = label - self.num_class = np.unique(np.array(label)).shape[0] - - normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], - std=[0.229, 0.224, 0.225]) - - self.transform = transforms.Compose([ - transforms.Resize(84, interpolation = PIL.Image.BICUBIC), - transforms.CenterCrop(84), - transforms.ToTensor(), - normalize]) - - def __len__(self): - return len(self.data) - - def __getitem__(self, i): - path, label = self.data[i], self.label[i] - image = self.transform(Image.open(path).convert('RGB')) - return image, label - diff --git a/feat/dataloader/mini_imagenet.py b/feat/dataloader/mini_imagenet.py deleted file mode 100644 index c0b9bf8..0000000 --- a/feat/dataloader/mini_imagenet.py +++ /dev/null @@ -1,67 +0,0 @@ -import os.path as osp -from PIL import Image - -from torch.utils.data import Dataset -from torchvision import transforms -import numpy as np - -THIS_PATH = osp.dirname(__file__) -ROOT_PATH = osp.abspath(osp.join(THIS_PATH, '..', '..')) -IMAGE_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/images') -SPLIT_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/split') - -class MiniImageNet(Dataset): - """ Usage: - """ - def __init__(self, setname, args): - csv_path = osp.join(SPLIT_PATH, setname + '.csv') - lines = [x.strip() for x in open(csv_path, 'r').readlines()][1:] - - data = [] - label = [] - lb = -1 - - self.wnids = [] - - for l in lines: - name, wnid = l.split(',') - path = osp.join(IMAGE_PATH, name) - if wnid not in self.wnids: - self.wnids.append(wnid) - lb += 1 - data.append(path) - label.append(lb) - - self.data = data - self.label = label - self.num_class = len(set(label)) - - # Transformation - if args.model_type == 'ConvNet': - image_size = 84 - self.transform = transforms.Compose([ - transforms.Resize(92), - transforms.CenterCrop(image_size), - transforms.ToTensor(), - transforms.Normalize(np.array([0.485, 0.456, 0.406]), - np.array([0.229, 0.224, 0.225])) - ]) - elif args.model_type == 'ResNet': - image_size = 80 - self.transform = transforms.Compose([ - transforms.Resize(92), - transforms.CenterCrop(image_size), - transforms.ToTensor(), - transforms.Normalize(np.array([x / 255.0 for x in [125.3, 123.0, 113.9]]), - np.array([x / 255.0 for x in [63.0, 62.1, 66.7]]))]) - else: - raise ValueError('Non-supported Network Types. Please Revise Data Pre-Processing Scripts.') - - def __len__(self): - return len(self.data) - - def __getitem__(self, i): - path, label = self.data[i], self.label[i] - image = self.transform(Image.open(path).convert('RGB')) - return image, label - diff --git a/feat/dataloader/mini_imagenet_pre.py b/feat/dataloader/mini_imagenet_pre.py deleted file mode 100644 index 4001a08..0000000 --- a/feat/dataloader/mini_imagenet_pre.py +++ /dev/null @@ -1,90 +0,0 @@ -import os.path as osp -import PIL -from PIL import Image - -import torch -from torch.utils.data import Dataset -from torchvision import transforms -import numpy as np - -# use for miniImageNet pre-train -THIS_PATH = osp.dirname(__file__) -ROOT_PATH = osp.abspath(osp.join(THIS_PATH, '..', '..')) -IMAGE_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/images') -SPLIT_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/split') - -class MiniImageNet(Dataset): - - def __init__(self, setname, args): - csv_path = osp.join(SPLIT_PATH, setname + '.csv') - lines = [x.strip() for x in open(csv_path, 'r').readlines()][1:] - - data = [] - label = [] - lb = -1 - - self.wnids = [] - - for l in lines: - name, wnid = l.split(',') - path = osp.join(IMAGE_PATH, name) - if wnid not in self.wnids: - self.wnids.append(wnid) - lb += 1 - data.append(path) - label.append(lb) - - self.data = data - self.label = label - self.num_class = len(set(label)) - - if args.model_type == 'conv': - image_size = 84 - if setname == 'train': - self.transform = transforms.Compose([ - transforms.RandomResizedCrop(image_size), - # transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - # Lighting(0.1, imagenet_pca['eigval'], imagenet_pca['eigvec']), - transforms.Normalize(np.array([0.485, 0.456, 0.406]), - np.array([0.229, 0.224, 0.225])), - - ]) - else: - self.transform = transforms.Compose([ - transforms.Resize(92), - transforms.CenterCrop(image_size), - transforms.ToTensor(), - transforms.Normalize(np.array([0.485, 0.456, 0.406]), - np.array([0.229, 0.224, 0.225])) - ]) - else: - # for resNet - image_size = 80 - mean = [x / 255 for x in [125.3, 123.0, 113.9]] - std = [x / 255 for x in [63.0, 62.1, 66.7]] - if setname == 'train': - self.transform = transforms.Compose([ - # transforms.Resize(92, interpolation = PIL.Image.BICUBIC), - transforms.RandomResizedCrop(image_size), - # transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - # Lighting(0.1, imagenet_pca['eigval'], imagenet_pca['eigvec']), - transforms.Normalize(mean, std)]) - else: - self.transform = transforms.Compose([ - transforms.Resize(92), - transforms.CenterCrop(image_size), - transforms.ToTensor(), - transforms.Normalize(mean, std)]) - - def __len__(self): - return len(self.data) - - def __getitem__(self, i): - path, label = self.data[i], self.label[i] - image = self.transform(Image.open(path).convert('RGB')) - return image, label - diff --git a/feat/dataloader/samplers.py b/feat/dataloader/samplers.py deleted file mode 100644 index 1be174a..0000000 --- a/feat/dataloader/samplers.py +++ /dev/null @@ -1,32 +0,0 @@ -import torch -import numpy as np - - -class CategoriesSampler(): - - def __init__(self, label, n_batch, n_cls, n_per): - self.n_batch = n_batch - self.n_cls = n_cls - self.n_per = n_per - - 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 = [] - classes = torch.randperm(len(self.m_ind))[:self.n_cls] - for c in classes: - l = self.m_ind[c] - pos = torch.randperm(len(l))[:self.n_per] - batch.append(l[pos]) - batch = torch.stack(batch).t().reshape(-1) - yield batch - diff --git a/feat/dataloader/tiered_imagenet.py b/feat/dataloader/tiered_imagenet.py deleted file mode 100644 index 2a83615..0000000 --- a/feat/dataloader/tiered_imagenet.py +++ /dev/null @@ -1,72 +0,0 @@ -from __future__ import print_function - -import os -import os.path -import numpy as np -import random -import pickle -import math -import sys -import torch -import torch.utils.data as data -import torchvision -import torchvision.datasets as datasets -import torchvision.transforms as transforms -from PIL import Image - -# Set the appropriate paths of the datasets here. -_TIERED_IMAGENET_DATASET_DIR = '../data/tieredimagenet/' - -def load_data(file): - try: - with open(file, 'rb') as fo: - data = pickle.load(fo) - return data - except: - with open(file, 'rb') as f: - u = pickle._Unpickler(f) - u.encoding = 'latin1' - data = u.load() - return data - -file_path = {'train':[os.path.join(_TIERED_IMAGENET_DATASET_DIR, 'train_images.npz'), os.path.join(_TIERED_IMAGENET_DATASET_DIR, 'train_labels.pkl')], - 'val':[os.path.join(_TIERED_IMAGENET_DATASET_DIR, 'val_images.npz'), os.path.join(_TIERED_IMAGENET_DATASET_DIR,'val_labels.pkl')], - 'test':[os.path.join(_TIERED_IMAGENET_DATASET_DIR, 'test_images.npz'), os.path.join(_TIERED_IMAGENET_DATASET_DIR, 'test_labels.pkl')]} - -class tieredImageNet(data.Dataset): - def __init__(self, phase='train', data_aug = False): - assert(phase=='train' or phase=='val' or phase=='test') - image_path = file_path[phase][0] - label_path = file_path[phase][1] - - data_train = load_data(label_path) - labels = data_train['labels'] - self.data = np.load(image_path)['images'] - - label = [] - lb = -1 - self.wnids = [] - for wnid in labels: - if wnid not in self.wnids: - self.wnids.append(wnid) - lb += 1 - label.append(lb) - - self.label = label - self.num_class = len(set(label)) - - mean_pix = [x/255.0 for x in [120.39586422, 115.59361427, 104.54012653]] - std_pix = [x/255.0 for x in [70.68188272, 68.27635443, 72.54505529]] - normalize = transforms.Normalize(mean=mean_pix, std=std_pix) - - self.transform = transforms.Compose([ - transforms.ToTensor(), - normalize]) - - def __getitem__(self, index): - img, label = self.data[index], self.label[index] - img = self.transform(Image.fromarray(img)) - return img, label - - def __len__(self): - return len(self.data) \ No newline at end of file diff --git a/feat/models/feat.py b/feat/models/feat.py deleted file mode 100644 index 7bcfa0f..0000000 --- a/feat/models/feat.py +++ /dev/null @@ -1,124 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F -import numpy as np -from feat.utils import euclidean_metric -from scipy.io import loadmat - -class ScaledDotProductAttention(nn.Module): - ''' Scaled Dot-Product Attention ''' - - def __init__(self, temperature, attn_dropout=0.1): - super().__init__() - self.temperature = temperature - self.dropout = nn.Dropout(attn_dropout) - self.softmax = nn.Softmax(dim=2) - - def forward(self, q, k, v): - - attn = torch.bmm(q, k.transpose(1, 2)) - attn = attn / self.temperature - log_attn = F.log_softmax(attn, 2) - attn = self.softmax(attn) - attn = self.dropout(attn) - output = torch.bmm(attn, v) - return output, attn, log_attn - -class MultiHeadAttention(nn.Module): - ''' Multi-Head Attention module ''' - - def __init__(self, args, n_head, d_model, d_k, d_v, dropout=0.1): - super().__init__() - self.n_head = n_head - self.d_k = d_k - self.d_v = d_v - - self.w_qs = nn.Linear(d_model, n_head * d_k) - self.w_ks = nn.Linear(d_model, n_head * d_k) - self.w_vs = nn.Linear(d_model, n_head * d_v) - nn.init.normal_(self.w_qs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) - nn.init.normal_(self.w_ks.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) - nn.init.normal_(self.w_vs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_v))) - - self.attention = ScaledDotProductAttention(temperature=np.power(d_k, 0.5)) - self.layer_norm = nn.LayerNorm(d_model) - - self.fc = nn.Linear(n_head * d_v, d_model) - nn.init.xavier_normal_(self.fc.weight) - self.dropout = nn.Dropout(dropout) - - def forward(self, q, k, v): - d_k, d_v, n_head = self.d_k, self.d_v, self.n_head - sz_b, len_q, _ = q.size() - sz_b, len_k, _ = k.size() - sz_b, len_v, _ = v.size() - - residual = q - q = self.w_qs(q).view(sz_b, len_q, n_head, d_k) - k = self.w_ks(k).view(sz_b, len_k, n_head, d_k) - v = self.w_vs(v).view(sz_b, len_v, n_head, d_v) - - q = q.permute(2, 0, 1, 3).contiguous().view(-1, len_q, d_k) # (n*b) x lq x dk - k = k.permute(2, 0, 1, 3).contiguous().view(-1, len_k, d_k) # (n*b) x lk x dk - v = v.permute(2, 0, 1, 3).contiguous().view(-1, len_v, d_v) # (n*b) x lv x dv - - output, attn, log_attn = self.attention(q, k, v) - - output = output.view(n_head, sz_b, len_q, d_v) - output = output.permute(1, 2, 0, 3).contiguous().view(sz_b, len_q, -1) # b x lq x (n*dv) - - output = self.dropout(self.fc(output)) - output = self.layer_norm(output + residual) - - return output - - -class FEAT(nn.Module): - - def __init__(self, args, dropout=0.2): - super().__init__() - if args.model_type == 'ConvNet': - from feat.networks.convnet import ConvNet - self.encoder = ConvNet() - z_dim = 64 - elif args.model_type == 'ResNet': - from feat.networks.resnet import ResNet - self.encoder = ResNet() - z_dim = 640 - else: - raise ValueError('') - - self.slf_attn = MultiHeadAttention(args, args.head, z_dim, z_dim, z_dim, dropout=dropout) - self.z_dim = z_dim - self.args = args - - def forward(self, support, query, mode = 'test'): - # feature extraction - support = self.encoder(support) - # get mean of the support - proto = support.reshape(self.args.shot, -1, support.shape[-1]).mean(dim=0) # N x d - num_proto = proto.shape[0] - # for query set - query = self.encoder(query) - - # adapt the support set instances - proto = proto.unsqueeze(0) # 1 x N x d - # refine by Transformer - proto = self.slf_attn(proto, proto, proto) - proto = proto.squeeze(0) - - # compute distance for all batches - logitis = euclidean_metric(query, proto) / self.args.temperature - - # transform for all instances in the task - if mode == 'train': - aux_task = torch.cat([support.reshape(self.args.shot, -1, support.shape[-1]), - query.reshape(self.args.query, -1, support.shape[-1])], 0) # (K+Kq) x N x d - aux_task = aux_task.permute([1,0,2]) - aux_emb = self.slf_attn(aux_task, aux_task, aux_task) # N x (K+Kq) x d - # compute class mean - aux_center = torch.mean(aux_emb, 1) # N x d - logitis2 = euclidean_metric(aux_task.permute([1,0,2]).view(-1, self.z_dim), aux_center) / self.args.temperature2 - return logitis, logitis2 - else: - return logitis \ No newline at end of file diff --git a/feat/models/matchnet.py b/feat/models/matchnet.py deleted file mode 100644 index 984d28a..0000000 --- a/feat/models/matchnet.py +++ /dev/null @@ -1,93 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F -from torch.autograd import Variable - -# for Matching Network -# change from https://github.com/gitabcworld/MatchingNetworks/ -# biLSTM is used to implement the embedding adaptation - -class BidirectionalLSTM(nn.Module): - def __init__(self, layer_sizes, batch_size, vector_dim): - super(BidirectionalLSTM, self).__init__() - """ - Initializes a multi layer bidirectional LSTM - :param layer_sizes: A list containing the neuron numbers per layer - e.g. [100, 100, 100] returns a 3 layer, 100 - :param batch_size: The experiments batch size - """ - self.batch_size = batch_size - self.hidden_size = layer_sizes[0] - self.vector_dim = vector_dim - self.num_layers = len(layer_sizes) - - self.lstm = nn.LSTM(input_size=self.vector_dim, - num_layers=self.num_layers, - hidden_size=self.hidden_size, - bidirectional=True) - - def forward(self, inputs): - """ - Runs the bidirectional LSTM, produces outputs and saves both forward and backward states as well as gradients. - :param x: The inputs should be a list of shape [sequence_length, batch_size, 64] - :return: Returns the LSTM outputs, as well as the forward and backward hidden states. - """ - c0 = Variable(torch.rand(self.lstm.num_layers*2, self.batch_size, self.lstm.hidden_size), - requires_grad=False) - h0 = Variable(torch.rand(self.lstm.num_layers*2, self.batch_size, self.lstm.hidden_size), - requires_grad=False) - if torch.cuda.is_available(): - c0 = c0.cuda() - h0 = h0.cuda() - output, (hn, cn) = self.lstm(inputs, (h0, c0)) - return output, hn, cn - - -class MatchNet(nn.Module): - def __init__(self, args): - super(MatchNet, self).__init__() - self.use_bilstm = args.use_bilstm - self.args = args # information about Shot and Way - - if args.model_type == 'ConvNet': - from feat.networks.convnet import ConvNet - self.encoder = ConvNet() - layer_size = 32 - elif args.model_type == 'ResNet': - from feat.networks.resnet import ResNet - self.encoder = ResNet() - layer_size = 320 - else: - raise ValueError('') - - if self.use_bilstm: - self.bilstm = BidirectionalLSTM(layer_sizes=[layer_size], - batch_size=args.query * args.way, - vector_dim=layer_size * 2) - - def forward(self, support_set, query_set): - # produce embeddings for support set images - support_set = self.encoder(support_set) #KN x d - # produce embedding for target images - query_set = self.encoder(query_set) # KqN x d - - num_support = support_set.shape[0] - num_query = query_set.shape[0] - support_extend = support_set.unsqueeze(0).repeat([num_query, 1, 1]) # KqN x KN x d - query_extend = query_set.unsqueeze(1) # KqN x 1 x d - combined = torch.cat([support_extend, query_extend], 1) # KqN x (KN + 1) x d - - if self.use_bilstm: - # FCE embedding - combined = combined.permute([1,0,2]) # (KN + 1) x KqN x d - combined, hn, cn = self.bilstm(combined) - combined = combined.permute([1,0,2]) # KqN x (KN + 1) x d - - # get similarity between support set embeddings and target - refined_support, refined_query = combined.split((self.args.shot * self.args.way), 1) # KqN x - - # compute cos similarity - refined_support = F.normalize(refined_support, dim = 2) # KqN x KN x d - # compute inner product, batch inner product - logitis = torch.bmm(refined_support, refined_query.permute([0,2,1])) / self.args.temperature # KqN x KN x d * KqN x d x 1 - return logitis # KqN x KN x 1 \ No newline at end of file diff --git a/feat/models/protonet.py b/feat/models/protonet.py deleted file mode 100644 index 5f932cb..0000000 --- a/feat/models/protonet.py +++ /dev/null @@ -1,22 +0,0 @@ -import torch.nn as nn -from feat.utils import euclidean_metric - -class ProtoNet(nn.Module): - - def __init__(self, args): - super().__init__() - self.args = args - if args.model_type == 'ConvNet': - from feat.networks.convnet import ConvNet - self.encoder = ConvNet() - elif args.model_type == 'ResNet': - from feat.networks.resnet import ResNet - self.encoder = ResNet() - else: - raise ValueError('') - - def forward(self, data_shot, data_query): - proto = self.encoder(data_shot) - proto = proto.reshape(self.args.shot, self.args.way, -1).mean(dim=0) - logits = euclidean_metric(self.encoder(data_query), proto) / self.args.temperature - return logits \ No newline at end of file diff --git a/feat/utils.py b/feat/utils.py deleted file mode 100644 index d31d986..0000000 --- a/feat/utils.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import shutil -import time -import pprint -import torch -import numpy as np - -def set_gpu(x): - os.environ['CUDA_VISIBLE_DEVICES'] = x - print('using gpu:', x) - - -def ensure_path(path, remove=True): - if os.path.exists(path): - if remove: - if input('{} exists, remove? ([y]/n)'.format(path)) != 'n': - shutil.rmtree(path) - os.mkdir(path) - else: - os.mkdir(path) - -class Averager(): - - def __init__(self): - self.n = 0 - self.v = 0 - - def add(self, x): - self.v = (self.v * self.n + x) / (self.n + 1) - self.n += 1 - - def item(self): - return self.v - - -def count_acc(logits, label): - pred = torch.argmax(logits, dim=1) - if torch.cuda.is_available(): - return (pred == label).type(torch.cuda.FloatTensor).mean().item() - else: - return (pred == label).type(torch.FloatTensor).mean().item() - -def euclidean_metric(a, b): - n = a.shape[0] - m = b.shape[0] - a = a.unsqueeze(1).expand(n, m, -1) - b = b.unsqueeze(0).expand(n, m, -1) - logits = -((a - b)**2).sum(dim=2) - return logits - -class Timer(): - - def __init__(self): - self.o = time.time() - - def measure(self, p=1): - x = (time.time() - self.o) / p - x = int(x) - if x >= 3600: - return '{:.1f}h'.format(x / 3600) - if x >= 60: - return '{}m'.format(round(x / 60)) - return '{}s'.format(x) - -_utils_pp = pprint.PrettyPrinter() -def pprint(x): - _utils_pp.pprint(x) - -def compute_confidence_interval(data): - """ - Compute 95% confidence interval - :param data: An array of mean accuracy (or mAP) across a number of sampled episodes. - :return: the 95% confidence interval for this data. - """ - a = 1.0 * np.array(data) - m = np.mean(a) - std = np.std(a) - pm = 1.96 * (std / np.sqrt(len(a))) - return m, pm diff --git a/imgs/architecture.png b/imgs/architecture.png index 8d86c35b004c3e00d616968a0f1c9f7fafbc1259..f2238055f48c7dc6425e778691d8231f296a43ae 100644 GIT binary patch literal 228942 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

ap_+@aE6+&zVSCePLs4=a<-qM7S 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

CJUV-4z)Zv@U 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

^o8Zkf}cM@?!8yG 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

E-+q_Fz(>yAy3y#ltK4Wy1m01OW64zZoat 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 SQvM@zUwYccx2tbDJ^Cl^u@4^r literal 179072 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 z≦YP7Jw@HXr|=9}+Pu!zHAmpWsuC;8j==7ik6E1hwnjq}h)Pm2srKCLQ^QSM~Qp zxCtJ`hP>p8#Q4aY5px%sjF-BeuJxTKxO$Ez3J+(?d4#x5S%BBJwKRv>5T zg^lwI#|M;0ZZ}$lk_9QCQ_J+v&Ui)Y`9%b$?k}mfjPH?+%bbw*{dsZ2SYx!8Or)Du zy4?8?LK(ZEayM`7Q(MWFI>d6QD@o_Qo>un2WcCSyJ*F$?_*#^4l!+a6{_^{voz>uX zutaXEgECg1ga&l$qgdKC%yRt7%o#AGXf2aIx@TZ<6Ez>IZm6Jl!#g2IvB_(9Q`UD6e~DXC z8QzSb6@T4b0+6?_)xEx@@iax)z|&Tg5ZZ*Gu-JU`}s|1vXIdRBZWDLwDJ#CGmArK2i4 z>)04wTm9!aD>|uL-zvRd{eU`WjzZ7|4>C5DBEQBM^_xGheiTrn(>4;O^!!G!$vx-Z zY$;xBJ^p3N|H%>jaZW}##=U=+_^Qn|a?@|E-7j!uD&OkuKM6j8yorMVH-q#IK!3e3 zbf}Le%mQp^y%GPTgjcCAx5ZDv>HH7HCRz6LIzbSp(VGLqw&fu$`Si#dNB$fSO8OKu zecBI*H9}P77c5!lK_s6^!(RuM>|@E1K_fS*p?()v@6v_VZw0NC`Em<9wtMIpez%%N z`Z$xCR`Qs@w~zOe1zmoJ>(r8EOzq-+s)81!RIRNLwEI0By?>f(sq6Vc$!e4EXeF(d zfcaKnp_Jp?tR2i52R)FyYJL?J1&2QEKTc&5*UMtg@^~59*rNmtuM?{-RA#Nm>4+)+ zO~J(+t;jDD;3trYUhFoJ1`lqxBmt-{Q5)UD7cVy%su#ujfjanIM~O z;@CzRGZJZT6CYbIEEEreIW4R#$z@Vn`v;@Ub3@npMB4QjKkE**R*L6Fe3Kv{)obQy z5$t7=5!O>7zlzq7hL>jg08}Q!`H^mOofch~vaa0tjGn3S8{4T0{BMKr!t-+BgQ>Ks zHy+rhNT2IdJ%`&5_YiBe^_EYvcucZ5A&IQ0=pWMg1@Xod&rhAlSGqk{06 z*#zD z*xFLqQ%0G06TErh9f?7ByTpR$g`aR!4F~|)#AmbfT$@56`<74lx}LudrC46>p&_IM zZ*hVU?JFgkb;$eVs3;c>S3<2f+QCBAL%=e9cdtp+ty{;nCK+@?_H@Mkj3;s1`ASN> zTW96J*q@$^)2s8ij*(GxXT{@WOBx+-lA6hnDdi|q-zO^LNO~RYv!fpA>{`Y!4%Ik5 zI*^elkj;Nu8e5_iY<_FioQys~6h*1SVAZMlUUwoPSY}*WGQV}?IHj-J+tu31518@o285=Xb)F!IHnW>+G_>sp@WOKb4xXA@;ZiBNTQb3 zG(w zk8lje_PtW(>5Y}Qn)d|hXUY}OjectLYGnz*p>U3BGmqMi12gLKP@kv3PesMiK(j=0y{1E=^DZO zTiOXy#G$0%V|<(8=GfjCTx{g?o)(CrWjUOzlZ+06QkfXtW5n#LS@_snR#si@21MaQ z%7xFgU+Fe-k?pv+*I;gD-J!IQ`=`~h^^OK=;609Hc*A)}y>Sl#%0D1Ls56RbBUi;T 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 <4>}7bM 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 0: + return list(zip(*map(scatter_map, obj))) + if isinstance(obj, list) and len(obj) > 0: + return list(map(list, zip(*map(scatter_map, obj)))) + if isinstance(obj, dict) and len(obj) > 0: + return list(map(type(obj), zip(*map(scatter_map, obj.items())))) + return [obj for targets in target_gpus] + + # After scatter_map is called, a scatter_map cell will exist. This cell + # has a reference to the actual function scatter_map, which has references + # to a closure that has a reference to the scatter_map cell (because the + # fn is recursive). To avoid this reference cycle, we set the function to + # None, clearing the cell + try: + return scatter_map(inputs) + finally: + scatter_map = None + +def scatter_kwargs(inputs, kwargs, target_gpus, chunk_sizes, dim=0): + r"""Scatter with support for kwargs dictionary""" + inputs = scatter(inputs, target_gpus, chunk_sizes, dim) if inputs else [] + kwargs = scatter(kwargs, target_gpus, chunk_sizes, dim) if kwargs else [] + if len(inputs) < len(kwargs): + inputs.extend([() for _ in range(len(kwargs) - len(inputs))]) + elif len(kwargs) < len(inputs): + kwargs.extend([{} for _ in range(len(inputs) - len(kwargs))]) + inputs = tuple(inputs) + kwargs = tuple(kwargs) + return inputs, kwargs + +class BalancedDataParallel(DataParallel): + def __init__(self, gpu0_bsz, *args, **kwargs): + self.gpu0_bsz = gpu0_bsz + super().__init__(*args, **kwargs) + + def forward(self, *inputs, **kwargs): + if not self.device_ids: + return self.module(*inputs, **kwargs) + if self.gpu0_bsz == 0: + device_ids = self.device_ids[1:] + else: + device_ids = self.device_ids + inputs, kwargs = self.scatter(inputs, kwargs, device_ids) + if len(self.device_ids) == 1: + return self.module(*inputs[0], **kwargs[0]) + replicas = self.replicate(self.module, self.device_ids) + if self.gpu0_bsz == 0: + replicas = replicas[1:] + outputs = self.parallel_apply(replicas, device_ids, inputs, kwargs) + return self.gather(outputs, self.output_device) + + def parallel_apply(self, replicas, device_ids, inputs, kwargs): + return parallel_apply(replicas, inputs, kwargs, device_ids) + + def scatter(self, inputs, kwargs, device_ids): + bsz = inputs[0].size(self.dim) + num_dev = len(self.device_ids) + gpu0_bsz = self.gpu0_bsz + bsz_unit = (bsz - gpu0_bsz) // (num_dev - 1) + if gpu0_bsz < bsz_unit: + chunk_sizes = [gpu0_bsz] + [bsz_unit] * (num_dev - 1) + delta = bsz - sum(chunk_sizes) + for i in range(delta): + chunk_sizes[i + 1] += 1 + if gpu0_bsz == 0: + chunk_sizes = chunk_sizes[1:] + else: + return super().scatter(inputs, kwargs, device_ids) + return scatter_kwargs(inputs, kwargs, device_ids, chunk_sizes, dim=self.dim) + diff --git a/model/dataloader/cub.py b/model/dataloader/cub.py new file mode 100644 index 0000000..172d020 --- /dev/null +++ b/model/dataloader/cub.py @@ -0,0 +1,123 @@ +import os.path as osp +import PIL +from PIL import Image + +import numpy as np +from torch.utils.data import Dataset +from torchvision import transforms + +THIS_PATH = osp.dirname(__file__) +ROOT_PATH1 = osp.abspath(osp.join(THIS_PATH, '..', '..', '..')) +ROOT_PATH2 = osp.abspath(osp.join(THIS_PATH, '..', '..')) +IMAGE_PATH = osp.join(ROOT_PATH1, 'data/cub') +SPLIT_PATH = osp.join(ROOT_PATH2, 'data/cub/split') +CACHE_PATH = osp.join(ROOT_PATH2, '.cache/') + +# This is for the CUB dataset +# It is notable, we assume the cub images are cropped based on the given bounding boxes +# The concept labels are based on the attribute value, which are for further use (and not used in this work) + +class CUB(Dataset): + + def __init__(self, setname, args, augment=False): + im_size = args.orig_imsize + txt_path = osp.join(SPLIT_PATH, setname + '.csv') + lines = [x.strip() for x in open(txt_path, 'r').readlines()][1:] + cache_path = osp.join( CACHE_PATH, "{}.{}.{}.pt".format(self.__class__.__name__, setname, im_size) ) + + self.use_im_cache = ( im_size != -1 ) # not using cache + if self.use_im_cache: + if not osp.exists(cache_path): + print('* Cache miss... Preprocessing {}...'.format(setname)) + resize_ = identity if im_size < 0 else transforms.Resize(im_size) + data, label = self.parse_csv(txt_path) + self.data = [ resize_(Image.open(path).convert('RGB')) for path in data ] + self.label = label + print('* Dump cache from {}'.format(cache_path)) + torch.save({'data': self.data, 'label': self.label }, cache_path) + else: + print('* Load cache from {}'.format(cache_path)) + cache = torch.load(cache_path) + self.data = cache['data'] + self.label = cache['label'] + else: + self.data, self.label = self.parse_csv(txt_path) + + self.num_class = np.unique(np.array(self.label)).shape[0] + image_size = 84 + + if augment and setname == 'train': + transforms_list = [ + transforms.RandomResizedCrop(image_size), + transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + ] + else: + transforms_list = [ + transforms.Resize(92), + transforms.CenterCrop(image_size), + transforms.ToTensor(), + ] + + # Transformation + if args.backbone_class == 'ConvNet': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([0.485, 0.456, 0.406]), + np.array([0.229, 0.224, 0.225])) + ]) + elif args.backbone_class == 'Res12': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([x / 255.0 for x in [120.39586422, 115.59361427, 104.54012653]]), + np.array([x / 255.0 for x in [70.68188272, 68.27635443, 72.54505529]])) + ]) + elif args.backbone_class == 'Res18': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + elif args.backbone_class == 'WRN': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + else: + raise ValueError('Non-supported Network Types. Please Revise Data Pre-Processing Scripts.') + + def parse_csv(self, txt_path): + data = [] + label = [] + lb = -1 + self.wnids = [] + lines = [x.strip() for x in open(txt_path, 'r').readlines()][1:] + + for l in lines: + context = l.split(',') + name = context[0] + wnid = context[1] + path = osp.join(IMAGE_PATH, name) + if wnid not in self.wnids: + self.wnids.append(wnid) + lb += 1 + + data.append(path) + label.append(lb) + + return data, label + + + def __len__(self): + return len(self.data) + + def __getitem__(self, i): + data, label = self.data[i], self.label[i] + if self.use_im_cache: + image = self.transform(data) + else: + image = self.transform(Image.open(data).convert('RGB')) + return image, label + diff --git a/model/dataloader/mini_imagenet.py b/model/dataloader/mini_imagenet.py new file mode 100644 index 0000000..6263a98 --- /dev/null +++ b/model/dataloader/mini_imagenet.py @@ -0,0 +1,122 @@ +import torch +import os.path as osp +from PIL import Image + +from torch.utils.data import Dataset +from torchvision import transforms +from tqdm import tqdm +import numpy as np + +THIS_PATH = osp.dirname(__file__) +ROOT_PATH = osp.abspath(osp.join(THIS_PATH, '..', '..')) +ROOT_PATH2 = osp.abspath(osp.join(THIS_PATH, '..', '..', '..')) +IMAGE_PATH1 = osp.join(ROOT_PATH2, 'data/miniimagenet/images') +SPLIT_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/split') +CACHE_PATH = osp.join(ROOT_PATH, '.cache/') + +def identity(x): + return x + +class MiniImageNet(Dataset): + """ Usage: + """ + def __init__(self, setname, args, augment=False): + im_size = args.orig_imsize + csv_path = osp.join(SPLIT_PATH, setname + '.csv') + cache_path = osp.join( CACHE_PATH, "{}.{}.{}.pt".format(self.__class__.__name__, setname, im_size) ) + + self.use_im_cache = ( im_size != -1 ) # not using cache + if self.use_im_cache: + if not osp.exists(cache_path): + print('* Cache miss... Preprocessing {}...'.format(setname)) + resize_ = identity if im_size < 0 else transforms.Resize(im_size) + data, label = self.parse_csv(csv_path, setname) + self.data = [ resize_(Image.open(path).convert('RGB')) for path in data ] + self.label = label + print('* Dump cache from {}'.format(cache_path)) + torch.save({'data': self.data, 'label': self.label }, cache_path) + else: + print('* Load cache from {}'.format(cache_path)) + cache = torch.load(cache_path) + self.data = cache['data'] + self.label = cache['label'] + else: + self.data, self.label = self.parse_csv(csv_path, setname) + + self.num_class = len(set(self.label)) + + image_size = 84 + if augment and setname == 'train': + transforms_list = [ + transforms.RandomResizedCrop(image_size), + transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + ] + else: + transforms_list = [ + transforms.Resize(92), + transforms.CenterCrop(image_size), + transforms.ToTensor(), + ] + + # Transformation + if args.backbone_class == 'ConvNet': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([0.485, 0.456, 0.406]), + np.array([0.229, 0.224, 0.225])) + ]) + elif args.backbone_class == 'Res12': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([x / 255.0 for x in [120.39586422, 115.59361427, 104.54012653]]), + np.array([x / 255.0 for x in [70.68188272, 68.27635443, 72.54505529]])) + ]) + elif args.backbone_class == 'Res18': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + elif args.backbone_class == 'WRN': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + else: + raise ValueError('Non-supported Network Types. Please Revise Data Pre-Processing Scripts.') + + def parse_csv(self, csv_path, setname): + lines = [x.strip() for x in open(csv_path, 'r').readlines()][1:] + + data = [] + label = [] + lb = -1 + + self.wnids = [] + + for l in tqdm(lines, ncols=64): + name, wnid = l.split(',') + path = osp.join(IMAGE_PATH1, name) + if wnid not in self.wnids: + self.wnids.append(wnid) + lb += 1 + data.append( path ) + label.append(lb) + + return data, label + + def __len__(self): + return len(self.data) + + def __getitem__(self, i): + data, label = self.data[i], self.label[i] + if self.use_im_cache: + image = self.transform(data) + else: + image = self.transform(Image.open(data).convert('RGB')) + + return image, label + diff --git a/model/dataloader/samplers.py b/model/dataloader/samplers.py new file mode 100644 index 0000000..9c7613b --- /dev/null +++ b/model/dataloader/samplers.py @@ -0,0 +1,92 @@ +import torch +import numpy as np + + +class CategoriesSampler(): + + def __init__(self, label, n_batch, n_cls, n_per): + self.n_batch = n_batch + self.n_cls = n_cls + self.n_per = n_per + + 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 = [] + classes = torch.randperm(len(self.m_ind))[:self.n_cls] + for c in classes: + l = self.m_ind[c] + pos = torch.randperm(len(l))[:self.n_per] + batch.append(l[pos]) + batch = torch.stack(batch).t().reshape(-1) + yield batch + + +class RandomSampler(): + + def __init__(self, label, n_batch, n_per): + self.n_batch = n_batch + self.n_per = n_per + self.label = np.array(label) + self.num_label = self.label.shape[0] + + def __len__(self): + return self.n_batch + + def __iter__(self): + for i_batch in range(self.n_batch): + batch = torch.randperm(self.num_label)[:self.n_per] + yield batch + + +# sample for each class +class ClassSampler(): + + def __init__(self, label, n_per=None): + self.n_per = n_per + 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 len(self.m_ind) + + def __iter__(self): + classes = torch.arange(len(self.m_ind)) + for c in classes: + l = self.m_ind[int(c)] + if self.n_per is None: + pos = torch.randperm(len(l)) + else: + pos = torch.randperm(len(l))[:self.n_per] + yield l[pos] + + +# for ResNet Fine-Tune, which output the same index of task examples several times +class InSetSampler(): + + def __init__(self, n_batch, n_sbatch, pool): # pool is a tensor + self.n_batch = n_batch + self.n_sbatch = n_sbatch + self.pool = pool + self.pool_size = pool.shape[0] + + def __len__(self): + return self.n_batch + + def __iter__(self): + for i_batch in range(self.n_batch): + batch = self.pool[torch.randperm(self.pool_size)[:self.n_sbatch]] + yield batch \ No newline at end of file diff --git a/model/dataloader/tiered_imagenet.py b/model/dataloader/tiered_imagenet.py new file mode 100644 index 0000000..decfee5 --- /dev/null +++ b/model/dataloader/tiered_imagenet.py @@ -0,0 +1,120 @@ +from __future__ import print_function + +import os +import os.path as osp +import numpy as np +import pickle +import sys +import torch +import torch.utils.data as data +import torchvision.transforms as transforms +from PIL import Image + +# Set the appropriate paths of the datasets here. +THIS_PATH = osp.dirname(__file__) +ROOT_PATH1 = osp.abspath(osp.join(THIS_PATH, '..', '..', '..')) +ROOT_PATH2 = osp.abspath(osp.join(THIS_PATH, '..', '..')) +IMAGE_PATH = osp.join(ROOT_PATH1, 'data/tieredimagenet/') +SPLIT_PATH = osp.join(ROOT_PATH2, 'data/miniimagenet/split') + +def buildLabelIndex(labels): + label2inds = {} + for idx, label in enumerate(labels): + if label not in label2inds: + label2inds[label] = [] + label2inds[label].append(idx) + + return label2inds + + +def load_data(file): + try: + with open(file, 'rb') as fo: + data = pickle.load(fo) + return data + except: + with open(file, 'rb') as f: + u = pickle._Unpickler(f) + u.encoding = 'latin1' + data = u.load() + return data + +file_path = {'train':[os.path.join(IMAGE_PATH, 'train_images.npz'), os.path.join(IMAGE_PATH, 'train_labels.pkl')], + 'val':[os.path.join(IMAGE_PATH, 'val_images.npz'), os.path.join(IMAGE_PATH,'val_labels.pkl')], + 'test':[os.path.join(IMAGE_PATH, 'test_images.npz'), os.path.join(IMAGE_PATH, 'test_labels.pkl')]} + +class tieredImageNet(data.Dataset): + def __init__(self, setname, args, augment=False): + assert(setname=='train' or setname=='val' or setname=='test') + image_path = file_path[setname][0] + label_path = file_path[setname][1] + + data_train = load_data(label_path) + labels = data_train['labels'] + self.data = np.load(image_path)['images'] + label = [] + lb = -1 + self.wnids = [] + for wnid in labels: + if wnid not in self.wnids: + self.wnids.append(wnid) + lb += 1 + label.append(lb) + + self.label = label + self.num_class = len(set(label)) + + if augment and setname == 'train': + transforms_list = [ + transforms.RandomCrop(84, padding=8), + transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + ] + else: + transforms_list = [ + transforms.ToTensor(), + ] + + # Transformation + if args.backbone_class == 'ConvNet': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([0.485, 0.456, 0.406]), + np.array([0.229, 0.224, 0.225])) + ]) + elif args.backbone_class == 'ResNet': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([x / 255.0 for x in [125.3, 123.0, 113.9]]), + np.array([x / 255.0 for x in [63.0, 62.1, 66.7]])) + ]) + elif args.backbone_class == 'Res12': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(np.array([x / 255.0 for x in [120.39586422, 115.59361427, 104.54012653]]), + np.array([x / 255.0 for x in [70.68188272, 68.27635443, 72.54505529]])) + ]) + elif args.backbone_class == 'Res18': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + elif args.backbone_class == 'WRN': + self.transform = transforms.Compose( + transforms_list + [ + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + else: + raise ValueError('Non-supported Network Types. Please Revise Data Pre-Processing Scripts.') + + + def __getitem__(self, index): + img, label = self.data[index], self.label[index] + img = self.transform(Image.fromarray(img)) + return img, label + + def __len__(self): + return len(self.data) diff --git a/model/logger.py b/model/logger.py new file mode 100644 index 0000000..aa7c940 --- /dev/null +++ b/model/logger.py @@ -0,0 +1,44 @@ +import json +import os.path as osp +import numpy as np +from collections import defaultdict, OrderedDict +from tensorboardX import SummaryWriter + +class ConfigEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, type): + return {'$class': o.__module__ + "." + o.__name__} + elif isinstance(o, Enum): + return { + '$enum': o.__module__ + "." + o.__class__.__name__ + '.' + o.name + } + elif callable(o): + return { + '$function': o.__module__ + "." + o.__name__ + } + return json.JSONEncoder.default(self, o) + +class Logger(object): + def __init__(self, args, log_dir, **kwargs): + self.logger_path = osp.join(log_dir, 'scalars.json') + self.tb_logger = SummaryWriter( + logdir=osp.join(log_dir, 'tflogger'), + **kwargs, + ) + self.log_config(vars(args)) + + self.scalars = defaultdict(OrderedDict) + + def add_scalar(self, key, value, counter): + assert self.scalars[key].get(counter, None) is None, 'counter should be distinct' + self.scalars[key][counter] = value + self.tb_logger.add_scalar(key, value, counter) + + def log_config(self, variant_data): + config_filepath = osp.join(osp.dirname(self.logger_path), 'configs.json') + with open(config_filepath, "w") as fd: + json.dump(variant_data, fd, indent=2, sort_keys=True, cls=ConfigEncoder) + + def dump(self): + with open(self.logger_path, 'w') as fd: + json.dump(self.scalars, fd, indent=2) \ No newline at end of file diff --git a/model/models/__init__.py b/model/models/__init__.py new file mode 100644 index 0000000..4ac637b --- /dev/null +++ b/model/models/__init__.py @@ -0,0 +1 @@ +from model.models.base import FewShotModel diff --git a/model/models/base.py b/model/models/base.py new file mode 100644 index 0000000..58987e7 --- /dev/null +++ b/model/models/base.py @@ -0,0 +1,58 @@ +import torch +import torch.nn as nn +import numpy as np +from sklearn.svm import LinearSVC +from sklearn.linear_model import LogisticRegression +from sklearn.model_selection import GridSearchCV + +class FewShotModel(nn.Module): + def __init__(self, args): + super().__init__() + self.args = args + if args.backbone_class == 'ConvNet': + from model.networks.convnet import ConvNet + self.encoder = ConvNet() + elif args.backbone_class == 'Res12': + hdim = 640 + from model.networks.res12 import ResNet + self.encoder = ResNet() + elif args.backbone_class == 'Res18': + hdim = 512 + from model.networks.res18 import ResNet + self.encoder = ResNet() + elif args.backbone_class == 'WRN': + hdim = 640 + from model.networks.WRN28 import Wide_ResNet + self.encoder = Wide_ResNet(28, 10, 0.5) # we set the dropout=0.5 directly here, it may achieve better results by tunning the dropout + else: + raise ValueError('') + + def split_instances(self, data): + args = self.args + if self.training: + return (torch.Tensor(np.arange(args.way*args.shot)).long().view(1, args.shot, args.way), + torch.Tensor(np.arange(args.way*args.shot, args.way * (args.shot + args.query))).long().view(1, args.query, args.way)) + else: + return (torch.Tensor(np.arange(args.eval_way*args.eval_shot)).long().view(1, args.eval_shot, args.eval_way), + torch.Tensor(np.arange(args.eval_way*args.eval_shot, args.eval_way * (args.eval_shot + args.eval_query))).long().view(1, args.eval_query, args.eval_way)) + + def forward(self, x, get_feature=False): + if get_feature: + # get feature with the provided embeddings + return self.encoder(x) + else: + # feature extraction + x = x.squeeze(0) + instance_embs = self.encoder(x) + num_inst = instance_embs.shape[0] + # split support query set for few-shot data + support_idx, query_idx = self.split_instances(x) + if self.training: + logits, logits_reg = self._forward(instance_embs, support_idx, query_idx) + return logits, logits_reg + else: + logits = self._forward(instance_embs, support_idx, query_idx) + return logits + + def _forward(self, x, support_idx, query_idx): + raise NotImplementedError('Suppose to be implemented by subclass') \ No newline at end of file diff --git a/model/models/bilstm.py b/model/models/bilstm.py new file mode 100644 index 0000000..08cabbc --- /dev/null +++ b/model/models/bilstm.py @@ -0,0 +1,122 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F +from torch.autograd import Variable + +from model.models import FewShotModel + +class BidirectionalLSTM(nn.Module): + def __init__(self, layer_sizes, vector_dim): + super(BidirectionalLSTM, self).__init__() + """ + Initializes a multi layer bidirectional LSTM + :param layer_sizes: A list containing the neuron numbers per layer + e.g. [100, 100, 100] returns a 3 layer, 100 + :param batch_size: The experiments batch size + """ + self.hidden_size = layer_sizes[0] + self.vector_dim = vector_dim + self.num_layers = len(layer_sizes) + + self.lstm = nn.LSTM(input_size=self.vector_dim, + num_layers=self.num_layers, + hidden_size=self.hidden_size, + bidirectional=True) + + def forward(self, inputs, batch_size): + """ + Runs the bidirectional LSTM, produces outputs and saves both forward and backward states as well as gradients. + :param x: The inputs should be a list of shape [sequence_length, batch_size, 64] + :return: Returns the LSTM outputs, as well as the forward and backward hidden states. + """ + c0 = Variable(torch.rand(self.lstm.num_layers*2, batch_size, self.lstm.hidden_size), + requires_grad=False) + h0 = Variable(torch.rand(self.lstm.num_layers*2, batch_size, self.lstm.hidden_size), + requires_grad=False) + if torch.cuda.is_available(): + c0 = c0.cuda() + h0 = h0.cuda() + output, (hn, cn) = self.lstm(inputs, (h0, c0)) + # residual addition + output = output + inputs + return output # , hn, cn + + +class BILSTM(FewShotModel): + def __init__(self, args): + super().__init__(args) + if args.backbone_class == 'ConvNet': + hdim = 64 + elif args.backbone_class == 'Res12': + hdim = 640 + elif args.backbone_class == 'Res18': + hdim = 512 + elif args.backbone_class == 'WRN': + hdim = 640 + else: + raise ValueError('') + + self.bilstm = BidirectionalLSTM(layer_sizes=[hdim // 2], + vector_dim = hdim) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.contiguous().view(-1)].contiguous().view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.contiguous().view(-1)].contiguous().view( *(query_idx.shape + (-1,))) + + # get mean of the support + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + proto = self.bilstm(proto.permute([1, 0, 2]), num_batch) + proto = proto.permute([1, 0, 2]) + if self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + proto = proto.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) + + # for regularization + if self.training: + aux_task = torch.cat([support.view(1, self.args.shot, self.args.way, emb_dim), + query.view(1, self.args.query, self.args.way, emb_dim)], 1) # T x (K+Kq) x N x d + num_query = np.prod(aux_task.shape[1:3]) + aux_task = aux_task.permute([0, 2, 1, 3]) + aux_task = aux_task.contiguous().view(-1, self.args.shot + self.args.query, emb_dim) + # apply the transformation over the Aug Task + aux_emb = self.bilstm(aux_task.permute([1, 0, 2]), num_batch * self.args.way) # T x N x (K+Kq) x d + aux_emb = aux_emb.permute([1, 0, 2]) + # compute class mean + aux_emb = aux_emb.view(num_batch, self.args.way, self.args.shot + self.args.query, emb_dim) + aux_center = torch.mean(aux_emb, 2) # T x N x d + + if self.args.use_euclidean: + aux_task = aux_task.contiguous().view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + aux_center = aux_center.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + aux_center = aux_center.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits_reg = - torch.sum((aux_center - aux_task) ** 2, 2) / self.args.temperature2 + else: + aux_center = F.normalize(aux_center, dim=-1) # normalize for cosine distance + aux_task = aux_task.contiguous().view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits_reg = torch.bmm(aux_task, aux_center.permute([0,2,1])) / self.args.temperature2 + logits_reg = logits_reg.view(-1, num_proto) + + return logits, logits_reg + else: + return logits diff --git a/feat/models/classifier.py b/model/models/classifier.py similarity index 53% rename from feat/models/classifier.py rename to model/models/classifier.py index 9b9feca..a3ffedc 100644 --- a/feat/models/classifier.py +++ b/model/models/classifier.py @@ -1,7 +1,7 @@ import torch import torch.nn as nn import numpy as np -from feat.utils import euclidean_metric +from model.utils import euclidean_metric import torch.nn.functional as F class Classifier(nn.Module): @@ -9,14 +9,22 @@ class Classifier(nn.Module): def __init__(self, args): super().__init__() self.args = args - if args.model_type == 'ConvNet': + if args.backbone_class == 'ConvNet': + from model.networks.convnet import ConvNet hdim = 64 - from feat.networks.convnet import ConvNet self.encoder = ConvNet() - elif args.model_type == 'ResNet': + elif args.backbone_class == 'Res12': hdim = 640 - from feat.networks.resnet import ResNet as ResNet + from model.networks.res12 import ResNet self.encoder = ResNet() + elif args.backbone_class == 'Res18': + hdim = 512 + from model.networks.res18 import ResNet + self.encoder = ResNet() + elif args.backbone_class == 'WRN': + hdim = 640 + from model.networks.WRN28 import Wide_ResNet + self.encoder = Wide_ResNet(28, 10, 0.5) else: raise ValueError('') @@ -33,7 +41,8 @@ def forward_proto(self, data_shot, data_query, way = None): way = self.args.num_class proto = self.encoder(data_shot) proto = proto.reshape(self.args.shot, way, -1).mean(dim=0) - query = self.encoder(data_query) - logits = euclidean_metric(query, proto) - return logits \ No newline at end of file + + logits_dist = euclidean_metric(query, proto) + logits_sim = torch.mm(query, F.normalize(proto, p=2, dim=-1).t()) + return logits_dist, logits_sim \ No newline at end of file diff --git a/model/models/deepset.py b/model/models/deepset.py new file mode 100644 index 0000000..067a0af --- /dev/null +++ b/model/models/deepset.py @@ -0,0 +1,118 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel + +class DeepSetsFunc(nn.Module): + def __init__(self, z_dim): + super(DeepSetsFunc, self).__init__() + """ + DeepSets Function + """ + self.gen1 = nn.Linear(z_dim, z_dim * 4) + self.gen2 = nn.Linear(z_dim*4, z_dim) + self.gen3 = nn.Linear(z_dim * 2, z_dim * 4) + self.gen4 = nn.Linear(z_dim*4, z_dim) + self.z_dim = z_dim + + def forward(self, set_input): + """ + set_input, seq_length, set_size, dim + """ + set_length, set_size, dim = set_input.shape + assert(dim == self.z_dim) + mask_one = torch.ones(set_size, set_size) - torch.eye(set_size, set_size) + mask_one = mask_one.view(1, set_size, set_size, 1) + if torch.cuda.is_available(): + mask_one = mask_one.cuda() + + combined_mean = torch.mul(set_input.unsqueeze(2), mask_one).max(1)[0] # 75 x 6 x 64, we can also try max here + # do a bilinear transformation + combined_mean = F.relu(self.gen1(combined_mean.view(-1, self.z_dim))) + combined_mean = self.gen2(combined_mean) + combined_mean_cat = torch.cat([set_input.contiguous().view(-1, self.z_dim), combined_mean], 1) + # do linear transformation + combined_mean_cat = F.relu(self.gen3(combined_mean_cat)) + combined_mean_cat = self.gen4(combined_mean_cat) + + combined_mean_cat = combined_mean_cat.view(-1, set_size, self.z_dim) + set_output = set_input + combined_mean_cat + return set_output + + +class DeepSet(FewShotModel): + def __init__(self, args): + super().__init__(args) + if args.backbone_class == 'ConvNet': + hdim = 64 + elif args.backbone_class == 'Res12': + hdim = 640 + elif args.backbone_class == 'Res18': + hdim = 512 + elif args.backbone_class == 'WRN': + hdim = 640 + else: + raise ValueError('') + + self.set_func = DeepSetsFunc(hdim) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.contiguous().view(-1)].contiguous().view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.contiguous().view(-1)].contiguous().view( *(query_idx.shape + (-1,))) + + # get mean of the support + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + proto = self.set_func(proto) + if self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + proto = proto.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) + + # for regularization + if self.training: + aux_task = torch.cat([support.view(1, self.args.shot, self.args.way, emb_dim), + query.view(1, self.args.query, self.args.way, emb_dim)], 1) # T x (K+Kq) x N x d + num_query = np.prod(aux_task.shape[1:3]) + aux_task = aux_task.permute([0, 2, 1, 3]) + aux_task = aux_task.contiguous().view(-1, self.args.shot + self.args.query, emb_dim) + # apply the transformation over the Aug Task + aux_emb = self.set_func(aux_task) # T x N x (K+Kq) x d + # compute class mean + aux_emb = aux_emb.view(num_batch, self.args.way, self.args.shot + self.args.query, emb_dim) + aux_center = torch.mean(aux_emb, 2) # T x N x d + + if self.args.use_euclidean: + aux_task = aux_task.contiguous().view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + aux_center = aux_center.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + aux_center = aux_center.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits_reg = - torch.sum((aux_center - aux_task) ** 2, 2) / self.args.temperature2 + else: + aux_center = F.normalize(aux_center, dim=-1) # normalize for cosine distance + aux_task = aux_task.contiguous().view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits_reg = torch.bmm(aux_task, aux_center.permute([0,2,1])) / self.args.temperature2 + logits_reg = logits_reg.view(-1, num_proto) + + return logits, logits_reg + else: + return logits diff --git a/model/models/feat.py b/model/models/feat.py new file mode 100644 index 0000000..3e6d875 --- /dev/null +++ b/model/models/feat.py @@ -0,0 +1,148 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel + +class ScaledDotProductAttention(nn.Module): + ''' Scaled Dot-Product Attention ''' + + def __init__(self, temperature, attn_dropout=0.1): + super().__init__() + self.temperature = temperature + self.dropout = nn.Dropout(attn_dropout) + self.softmax = nn.Softmax(dim=2) + + def forward(self, q, k, v): + + attn = torch.bmm(q, k.transpose(1, 2)) + attn = attn / self.temperature + log_attn = F.log_softmax(attn, 2) + attn = self.softmax(attn) + attn = self.dropout(attn) + output = torch.bmm(attn, v) + return output, attn, log_attn + +class MultiHeadAttention(nn.Module): + ''' Multi-Head Attention module ''' + + def __init__(self, n_head, d_model, d_k, d_v, dropout=0.1): + super().__init__() + self.n_head = n_head + self.d_k = d_k + self.d_v = d_v + + self.w_qs = nn.Linear(d_model, n_head * d_k, bias=False) + self.w_ks = nn.Linear(d_model, n_head * d_k, bias=False) + self.w_vs = nn.Linear(d_model, n_head * d_v, bias=False) + nn.init.normal_(self.w_qs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) + nn.init.normal_(self.w_ks.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) + nn.init.normal_(self.w_vs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_v))) + + self.attention = ScaledDotProductAttention(temperature=np.power(d_k, 0.5)) + self.layer_norm = nn.LayerNorm(d_model) + + self.fc = nn.Linear(n_head * d_v, d_model) + nn.init.xavier_normal_(self.fc.weight) + self.dropout = nn.Dropout(dropout) + + def forward(self, q, k, v): + d_k, d_v, n_head = self.d_k, self.d_v, self.n_head + sz_b, len_q, _ = q.size() + sz_b, len_k, _ = k.size() + sz_b, len_v, _ = v.size() + + residual = q + q = self.w_qs(q).view(sz_b, len_q, n_head, d_k) + k = self.w_ks(k).view(sz_b, len_k, n_head, d_k) + v = self.w_vs(v).view(sz_b, len_v, n_head, d_v) + + q = q.permute(2, 0, 1, 3).contiguous().view(-1, len_q, d_k) # (n*b) x lq x dk + k = k.permute(2, 0, 1, 3).contiguous().view(-1, len_k, d_k) # (n*b) x lk x dk + v = v.permute(2, 0, 1, 3).contiguous().view(-1, len_v, d_v) # (n*b) x lv x dv + + output, attn, log_attn = self.attention(q, k, v) + + output = output.view(n_head, sz_b, len_q, d_v) + output = output.permute(1, 2, 0, 3).contiguous().view(sz_b, len_q, -1) # b x lq x (n*dv) + + output = self.dropout(self.fc(output)) + output = self.layer_norm(output + residual) + + return output + +class FEAT(FewShotModel): + def __init__(self, args): + super().__init__(args) + if args.backbone_class == 'ConvNet': + hdim = 64 + elif args.backbone_class == 'Res12': + hdim = 640 + elif args.backbone_class == 'Res18': + hdim = 512 + elif args.backbone_class == 'WRN': + hdim = 640 + else: + raise ValueError('') + + self.slf_attn = MultiHeadAttention(1, hdim, hdim, hdim, dropout=0.5) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.contiguous().view(-1)].contiguous().view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.contiguous().view(-1)].contiguous().view( *(query_idx.shape + (-1,))) + + # get mean of the support + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + proto = self.slf_attn(proto, proto, proto) + if self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + proto = proto.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) + + # for regularization + if self.training: + aux_task = torch.cat([support.view(1, self.args.shot, self.args.way, emb_dim), + query.view(1, self.args.query, self.args.way, emb_dim)], 1) # T x (K+Kq) x N x d + num_query = np.prod(aux_task.shape[1:3]) + aux_task = aux_task.permute([0, 2, 1, 3]) + aux_task = aux_task.contiguous().view(-1, self.args.shot + self.args.query, emb_dim) + # apply the transformation over the Aug Task + aux_emb = self.slf_attn(aux_task, aux_task, aux_task) # T x N x (K+Kq) x d + # compute class mean + aux_emb = aux_emb.view(num_batch, self.args.way, self.args.shot + self.args.query, emb_dim) + aux_center = torch.mean(aux_emb, 2) # T x N x d + + if self.args.use_euclidean: + aux_task = aux_task.permute([1,0,2]).contiguous().view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + aux_center = aux_center.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + aux_center = aux_center.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits_reg = - torch.sum((aux_center - aux_task) ** 2, 2) / self.args.temperature2 + else: + aux_center = F.normalize(aux_center, dim=-1) # normalize for cosine distance + aux_task = aux_task.permute([1,0,2]).contiguous().view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits_reg = torch.bmm(aux_task, aux_center.permute([0,2,1])) / self.args.temperature2 + logits_reg = logits_reg.view(-1, num_proto) + + return logits, logits_reg + else: + return logits diff --git a/feat/models/feat_star.py b/model/models/featstar.py similarity index 54% rename from feat/models/feat_star.py rename to model/models/featstar.py index c471d97..31f1ab7 100644 --- a/feat/models/feat_star.py +++ b/model/models/featstar.py @@ -1,7 +1,11 @@ import torch import torch.nn as nn -import torch.nn.functional as F import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel + +# No-Reg for FEAT-STAR here class ScaledDotProductAttention(nn.Module): ''' Scaled Dot-Product Attention ''' @@ -31,9 +35,9 @@ def __init__(self, n_head, d_model, d_k, d_v, dropout=0.1): self.d_k = d_k self.d_v = d_v - self.w_qs = nn.Linear(d_model, n_head * d_k) - self.w_ks = nn.Linear(d_model, n_head * d_k) - self.w_vs = nn.Linear(d_model, n_head * d_v) + self.w_qs = nn.Linear(d_model, n_head * d_k, bias=False) + self.w_ks = nn.Linear(d_model, n_head * d_k, bias=False) + self.w_vs = nn.Linear(d_model, n_head * d_v, bias=False) nn.init.normal_(self.w_qs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) nn.init.normal_(self.w_ks.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_k))) nn.init.normal_(self.w_vs.weight, mean=0, std=np.sqrt(2.0 / (d_model + d_v))) @@ -44,7 +48,7 @@ def __init__(self, n_head, d_model, d_k, d_v, dropout=0.1): self.fc = nn.Linear(n_head * d_v, d_model) nn.init.xavier_normal_(self.fc.weight) self.dropout = nn.Dropout(dropout) - + def forward(self, q, k, v): d_k, d_v, n_head = self.d_k, self.d_v, self.n_head sz_b, len_q, _ = q.size() @@ -68,46 +72,58 @@ def forward(self, q, k, v): output = self.dropout(self.fc(output)) output = self.layer_norm(output + residual) - return output, attn, log_attn - - -class FEAT(nn.Module): - - def __init__(self, args, dropout=0.2): - super().__init__() - if args.model_type == 'ConvNet': - from feat.networks.convnet import ConvNet - self.encoder = ConvNet() - z_dim = 64 - elif args.model_type == 'ResNet': - from feat.networks.resnet import ResNet - self.encoder = ResNet() - z_dim = 640 + return output + +class FEATSTAR(FewShotModel): + def __init__(self, args): + super().__init__(args) + if args.backbone_class == 'ConvNet': + hdim = 64 + elif args.backbone_class == 'Res12': + hdim = 640 + elif args.backbone_class == 'Res18': + hdim = 512 + elif args.backbone_class == 'WRN': + hdim = 640 else: raise ValueError('') + + self.slf_attn = MultiHeadAttention(1, hdim, hdim, hdim, dropout=0.5) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) - self.slf_attn = MultiHeadAttention(1, z_dim, z_dim, z_dim, dropout=dropout) - self.args = args - - def forward(self, support, query): - # feature extraction - support = self.encoder(support) + # organize support/query data + support = instance_embs[support_idx.contiguous().view(-1)].contiguous().view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.contiguous().view(-1)].contiguous().view( *(query_idx.shape + (-1,))) + # get mean of the support - proto = support.reshape(self.args.shot, -1, support.shape[-1]).mean(dim=0) # N x d - num_proto = proto.shape[0] - # for query set - query = self.encoder(query) - - # combine all query set with the proto - num_query = query.shape[0] - proto = proto.unsqueeze(0).repeat([num_query, 1, 1]) # NK x N x d - query = query.unsqueeze(1) # NK x 1 x d + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + query = query.view(-1, emb_dim).unsqueeze(1) + + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + proto = proto.view(num_batch*num_query, num_proto, emb_dim) + + # refine by Transformer combined = torch.cat([proto, query], 1) # Nk x (N + 1) x d, batch_size = NK + combined = self.slf_attn(combined, combined, combined) + # compute distance for all batches + proto, query = combined.split(num_proto, 1) - # refine by Transformer - combined, enc_slf_attn, enc_slf_log_attn = self.slf_attn(combined, combined, combined) + if self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: # cosine similarity: more memory efficient + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) - # compute distance for all batches - refined_support, refined_query = combined.split(self.args.way, 1) - logitis = -torch.sum((refined_support - refined_query) ** 2, 2) / self.args.temperature - return logitis, enc_slf_log_attn \ No newline at end of file + return logits, None diff --git a/model/models/graphnet.py b/model/models/graphnet.py new file mode 100644 index 0000000..39d60e5 --- /dev/null +++ b/model/models/graphnet.py @@ -0,0 +1,176 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel + +import math +from torch.nn.parameter import Parameter +from torch.nn.modules.module import Module +from itertools import permutations +import scipy.sparse as sp + +class GraphConvolution(Module): + """ + Simple GCN layer, similar to https://arxiv.org/abs/1609.02907 + """ + + def __init__(self, in_features, out_features, bias=True): + super(GraphConvolution, self).__init__() + self.in_features = in_features + self.out_features = out_features + self.weight = Parameter(torch.FloatTensor(in_features, out_features)) + if bias: + self.bias = Parameter(torch.FloatTensor(out_features)) + else: + self.register_parameter('bias', None) + self.reset_parameters() + + def reset_parameters(self): + stdv = 1. / math.sqrt(self.weight.size(1)) + self.weight.data.uniform_(-stdv, stdv) + if self.bias is not None: + self.bias.data.uniform_(-stdv, stdv) + + def forward(self, input, adj): + support = torch.mm(input, self.weight) + output = torch.spmm(adj, support) + if self.bias is not None: + return output + self.bias + else: + return output + + def __repr__(self): + return self.__class__.__name__ + ' (' \ + + str(self.in_features) + ' -> ' \ + + str(self.out_features) + ')' + + +def normalize(mx): + """Row-normalize sparse matrix""" + rowsum = np.array(mx.sum(1)) + r_inv = np.power(rowsum, -1).flatten() + r_inv[np.isinf(r_inv)] = 0. + r_mat_inv = sp.diags(r_inv) + mx = r_mat_inv.dot(mx) + return mx + + +def sparse_mx_to_torch_sparse_tensor(sparse_mx): + """Convert a scipy sparse matrix to a torch sparse tensor.""" + sparse_mx = sparse_mx.tocoo().astype(np.float32) + indices = torch.from_numpy( + np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64)) + values = torch.from_numpy(sparse_mx.data) + shape = torch.Size(sparse_mx.shape) + if torch.cuda.is_available(): + return torch.sparse.FloatTensor(indices, values, shape).cuda() + else: + return torch.sparse.FloatTensor(indices, values, shape) + +class GraphFunc(nn.Module): + def __init__(self, z_dim): + super(GraphFunc, self).__init__() + """ + DeepSets Function + """ + self.gc1 = GraphConvolution(z_dim, z_dim * 4) + self.gc2 = GraphConvolution(z_dim * 4, z_dim) + self.z_dim = z_dim + + def forward(self, graph_input_raw, graph_label): + """ + set_input, seq_length, set_size, dim + """ + set_length, set_size, dim = graph_input_raw.shape + assert(dim == self.z_dim) + set_output_list = [] + + for g_index in range(set_length): + graph_input = graph_input_raw[g_index, :] + # construct the adj matrix + unique_class = np.unique(graph_label) + edge_set = [] + for c in unique_class: + current_index = np.where(graph_label == c)[0].tolist() + if len(current_index) > 1: + edge_set.append(np.array(list(permutations(current_index, 2)))) + + if len(edge_set) == 0: + adj = sp.coo_matrix((np.array([0]), (np.array([0]), np.array([0]))), + shape=(graph_label.shape[0], graph_label.shape[0]), + dtype=np.float32) + else: + edge_set = np.concatenate(edge_set, 0) + adj = sp.coo_matrix((np.ones(edge_set.shape[0]), (edge_set[:, 0], edge_set[:, 1])), + shape=(graph_label.shape[0], graph_label.shape[0]), + dtype=np.float32) + adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) + adj = normalize(adj + sp.eye(adj.shape[0])) + adj = sparse_mx_to_torch_sparse_tensor(adj) + + # do GCN process + residual = graph_input + graph_input = F.relu(self.gc1(graph_input, adj)) + graph_input = F.dropout(graph_input, 0.5, training=self.training) + graph_input = self.gc2(graph_input, adj) + set_output = residual + graph_input + set_output_list.append(set_output) + + return torch.stack(set_output_list) + +class GCN(FewShotModel): + def __init__(self, args): + super().__init__(args) + if args.backbone_class == 'ConvNet': + hdim = 64 + elif args.backbone_class == 'Res12': + hdim = 640 + elif args.backbone_class == 'Res18': + hdim = 512 + elif args.backbone_class == 'WRN': + hdim = 640 + else: + raise ValueError('') + + self.graph_func = GraphFunc(hdim) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.contiguous().view(-1)].contiguous().view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.contiguous().view(-1)].contiguous().view( *(query_idx.shape + (-1,))) + + # get mean of the support + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + if self.training: + graph_label = torch.arange(self.args.way).long() + else: + graph_label = torch.arange(self.args.eval_way).long() + proto = self.graph_func(proto, graph_label) + if self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim).contiguous() + proto = proto.view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) + + # do not use contrastive regularization for GCN (since there are only one sinlge instances class in each auxiliary task) + if self.training: + return logits, None + else: + return logits diff --git a/model/models/matchnet.py b/model/models/matchnet.py new file mode 100644 index 0000000..9dd6fcb --- /dev/null +++ b/model/models/matchnet.py @@ -0,0 +1,54 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel +from model.utils import one_hot + +# Note: This is the MatchingNet without FCE +# it predicts an instance based on nearest neighbor rule (not Nearest center mean) + +class MatchNet(FewShotModel): + def __init__(self, args): + super().__init__(args) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.flatten()].view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.flatten()].view( *(query_idx.shape + (-1,))) + + if self.training: + label_support = torch.arange(self.args.way).repeat(self.args.shot).type(torch.LongTensor) + label_support_onehot = one_hot(label_support, self.args.way) + else: + label_support = torch.arange(self.args.eval_way).repeat(self.args.eval_shot).type(torch.LongTensor) + label_support_onehot = one_hot(label_support, self.args.eval_way) + if torch.cuda.is_available(): + label_support_onehot = label_support_onehot.cuda() # KN x N + + # get mean of the support + num_batch = support.shape[0] + num_way = support.shape[2] + num_support = np.prod(support.shape[1:3]) + num_query = np.prod(query_idx.shape[-2:]) + support = support.view(num_batch, num_support, emb_dim) # Ntask x NK x d + label_support_onehot = label_support_onehot.unsqueeze(0).repeat(num_batch, 1, 1) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + + support = F.normalize(support, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + # (num_batch, num_emb, num_proto) * (num_batch, num_query*num_proto, num_emb) -> (num_batch, num_query*num_proto, num_proto) + logits = torch.bmm(query, support.permute([0,2,1])) + logits = torch.bmm(logits, label_support_onehot) / self.args.temperature # KqN x N + logits = logits.view(-1, num_way) + + if self.training: + return logits, None + else: + return logits diff --git a/model/models/protonet.py b/model/models/protonet.py new file mode 100644 index 0000000..7c7e0a0 --- /dev/null +++ b/model/models/protonet.py @@ -0,0 +1,47 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.nn.functional as F + +from model.models import FewShotModel + +# Note: As in Protonet, we use Euclidean Distances here, you can change to the Cosine Similarity by replace +# TRUE in line 30 as self.args.use_euclidean + +class ProtoNet(FewShotModel): + def __init__(self, args): + super().__init__(args) + + def _forward(self, instance_embs, support_idx, query_idx): + emb_dim = instance_embs.size(-1) + + # organize support/query data + support = instance_embs[support_idx.flatten()].view(*(support_idx.shape + (-1,))) + query = instance_embs[query_idx.flatten()].view( *(query_idx.shape + (-1,))) + + # get mean of the support + proto = support.mean(dim=1) # Ntask x NK x d + num_batch = proto.shape[0] + num_proto = proto.shape[1] + num_query = np.prod(query_idx.shape[-2:]) + + # query: (num_batch, num_query, num_proto, num_emb) + # proto: (num_batch, num_proto, num_emb) + if True: # self.args.use_euclidean: + query = query.view(-1, emb_dim).unsqueeze(1) # (Nbatch*Nq*Nw, 1, d) + proto = proto.unsqueeze(1).expand(num_batch, num_query, num_proto, emb_dim) + proto = proto.contiguous().view(num_batch*num_query, num_proto, emb_dim) # (Nbatch x Nq, Nk, d) + + logits = - torch.sum((proto - query) ** 2, 2) / self.args.temperature + else: # cosine similarity: more memory efficient + proto = F.normalize(proto, dim=-1) # normalize for cosine distance + query = query.view(num_batch, -1, emb_dim) # (Nbatch, Nq*Nw, d) + + # (num_batch, num_emb, num_proto) * (num_batch, num_query*num_proto, num_emb) -> (num_batch, num_query*num_proto, num_proto) + logits = torch.bmm(query, proto.permute([0,2,1])) / self.args.temperature + logits = logits.view(-1, num_proto) + + if self.training: + return logits, None + else: + return logits diff --git a/feat/networks/WRN28.py b/model/networks/WRN28.py similarity index 96% rename from feat/networks/WRN28.py rename to model/networks/WRN28.py index 5211cd6..3f8e222 100644 --- a/feat/networks/WRN28.py +++ b/model/networks/WRN28.py @@ -1,81 +1,81 @@ -import torch -import torch.nn as nn -import torch.nn.init as init -import torch.nn.functional as F -from torch.autograd import Variable - -import sys -import numpy as np - -def conv3x3(in_planes, out_planes, stride=1): - return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=True) - -def conv_init(m): - classname = m.__class__.__name__ - if classname.find('Conv') != -1: - init.xavier_uniform(m.weight, gain=np.sqrt(2)) - init.constant(m.bias, 0) - elif classname.find('BatchNorm') != -1: - init.constant(m.weight, 1) - init.constant(m.bias, 0) - -class wide_basic(nn.Module): - def __init__(self, in_planes, planes, dropout_rate, stride=1): - super(wide_basic, self).__init__() - self.bn1 = nn.BatchNorm2d(in_planes) - self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, padding=1, bias=True) - self.dropout = nn.Dropout(p=dropout_rate) - self.bn2 = nn.BatchNorm2d(planes) - self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=True) - - self.shortcut = nn.Sequential() - if stride != 1 or in_planes != planes: - self.shortcut = nn.Sequential( - nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=True), - ) - - def forward(self, x): - out = self.dropout(self.conv1(F.relu(self.bn1(x)))) - out = self.conv2(F.relu(self.bn2(out))) - out += self.shortcut(x) - - return out - -class Wide_ResNet(nn.Module): - def __init__(self, depth, widen_factor, dropout_rate): - super(Wide_ResNet, self).__init__() - self.in_planes = 16 - - assert ((depth-4)%6 ==0), 'Wide-resnet depth should be 6n+4' - n = int((depth-4)/6) - k = widen_factor - - print('| Wide-Resnet %dx%d' %(depth, k)) - nStages = [16, 16*k, 32*k, 64*k] - - self.conv1 = conv3x3(3,nStages[0]) - self.layer1 = self._wide_layer(wide_basic, nStages[1], n, dropout_rate, stride=1) - self.layer2 = self._wide_layer(wide_basic, nStages[2], n, dropout_rate, stride=2) - self.layer3 = self._wide_layer(wide_basic, nStages[3], n, dropout_rate, stride=2) - self.bn1 = nn.BatchNorm2d(nStages[3], momentum=0.9) - - def _wide_layer(self, block, planes, num_blocks, dropout_rate, stride): - strides = [stride] + [1]*(num_blocks-1) - layers = [] - - for stride in strides: - layers.append(block(self.in_planes, planes, dropout_rate, stride)) - self.in_planes = planes - - return nn.Sequential(*layers) - - def forward(self, x): - out = self.conv1(x) - out = self.layer1(out) - out = self.layer2(out) - out = self.layer3(out) - out = F.relu(self.bn1(out)) - out = F.avg_pool2d(out, 21) - out = out.view(out.size(0), -1) - +import torch +import torch.nn as nn +import torch.nn.init as init +import torch.nn.functional as F +from torch.autograd import Variable + +import sys +import numpy as np + +def conv3x3(in_planes, out_planes, stride=1): + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=True) + +def conv_init(m): + classname = m.__class__.__name__ + if classname.find('Conv') != -1: + init.xavier_uniform(m.weight, gain=np.sqrt(2)) + init.constant(m.bias, 0) + elif classname.find('BatchNorm') != -1: + init.constant(m.weight, 1) + init.constant(m.bias, 0) + +class wide_basic(nn.Module): + def __init__(self, in_planes, planes, dropout_rate, stride=1): + super(wide_basic, self).__init__() + self.bn1 = nn.BatchNorm2d(in_planes) + self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, padding=1, bias=True) + self.dropout = nn.Dropout(p=dropout_rate) + self.bn2 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=True) + + self.shortcut = nn.Sequential() + if stride != 1 or in_planes != planes: + self.shortcut = nn.Sequential( + nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=True), + ) + + def forward(self, x): + out = self.dropout(self.conv1(F.relu(self.bn1(x)))) + out = self.conv2(F.relu(self.bn2(out))) + out += self.shortcut(x) + + return out + +class Wide_ResNet(nn.Module): + def __init__(self, depth, widen_factor, dropout_rate): + super(Wide_ResNet, self).__init__() + self.in_planes = 16 + + assert ((depth-4)%6 ==0), 'Wide-resnet depth should be 6n+4' + n = int((depth-4)/6) + k = widen_factor + + print('| Wide-Resnet %dx%d' %(depth, k)) + nStages = [16, 16*k, 32*k, 64*k] + + self.conv1 = conv3x3(3,nStages[0]) + self.layer1 = self._wide_layer(wide_basic, nStages[1], n, dropout_rate, stride=1) + self.layer2 = self._wide_layer(wide_basic, nStages[2], n, dropout_rate, stride=2) + self.layer3 = self._wide_layer(wide_basic, nStages[3], n, dropout_rate, stride=2) + self.bn1 = nn.BatchNorm2d(nStages[3], momentum=0.9) + + def _wide_layer(self, block, planes, num_blocks, dropout_rate, stride): + strides = [stride] + [1]*(num_blocks-1) + layers = [] + + for stride in strides: + layers.append(block(self.in_planes, planes, dropout_rate, stride)) + self.in_planes = planes + + return nn.Sequential(*layers) + + def forward(self, x): + out = self.conv1(x) + out = self.layer1(out) + out = self.layer2(out) + out = self.layer3(out) + out = F.relu(self.bn1(out)) + out = F.avg_pool2d(out, 21) + out = out.view(out.size(0), -1) + return out \ No newline at end of file diff --git a/feat/networks/convnet.py b/model/networks/convnet.py similarity index 100% rename from feat/networks/convnet.py rename to model/networks/convnet.py diff --git a/model/networks/dropblock.py b/model/networks/dropblock.py new file mode 100644 index 0000000..fc24c12 --- /dev/null +++ b/model/networks/dropblock.py @@ -0,0 +1,61 @@ +import torch +import torch.nn.functional as F +from torch import nn +from torch.distributions import Bernoulli + + +class DropBlock(nn.Module): + def __init__(self, block_size): + super(DropBlock, self).__init__() + + self.block_size = block_size + + def forward(self, x, gamma): + # shape: (bsize, channels, height, width) + + if self.training: + batch_size, channels, height, width = x.shape + bernoulli = Bernoulli(gamma) + mask = bernoulli.sample((batch_size, channels, height - (self.block_size - 1), width - (self.block_size - 1))) + if torch.cuda.is_available(): + mask = mask.cuda() + block_mask = self._compute_block_mask(mask) + countM = block_mask.size()[0] * block_mask.size()[1] * block_mask.size()[2] * block_mask.size()[3] + count_ones = block_mask.sum() + + return block_mask * x * (countM / count_ones) + else: + return x + + def _compute_block_mask(self, mask): + left_padding = int((self.block_size-1) / 2) + right_padding = int(self.block_size / 2) + + batch_size, channels, height, width = mask.shape + non_zero_idxs = mask.nonzero() + nr_blocks = non_zero_idxs.shape[0] + + offsets = torch.stack( + [ + torch.arange(self.block_size).view(-1, 1).expand(self.block_size, self.block_size).reshape(-1), # - left_padding, + torch.arange(self.block_size).repeat(self.block_size), #- left_padding + ] + ).t() + offsets = torch.cat((torch.zeros(self.block_size**2, 2).long(), offsets.long()), 1) + if torch.cuda.is_available(): + offsets = offsets.cuda() + + if nr_blocks > 0: + non_zero_idxs = non_zero_idxs.repeat(self.block_size ** 2, 1) + offsets = offsets.repeat(nr_blocks, 1).view(-1, 4) + offsets = offsets.long() + + block_idxs = non_zero_idxs + offsets + #block_idxs += left_padding + padded_mask = F.pad(mask, (left_padding, right_padding, left_padding, right_padding)) + padded_mask[block_idxs[:, 0], block_idxs[:, 1], block_idxs[:, 2], block_idxs[:, 3]] = 1. + else: + padded_mask = F.pad(mask, (left_padding, right_padding, left_padding, right_padding)) + + block_mask = 1 - padded_mask#[:height, :width] + return block_mask diff --git a/model/networks/res12.py b/model/networks/res12.py new file mode 100644 index 0000000..919ed82 --- /dev/null +++ b/model/networks/res12.py @@ -0,0 +1,125 @@ +import torch.nn as nn +import torch +import torch.nn.functional as F +from model.networks.dropblock import DropBlock + +# This ResNet network was designed following the practice of the following papers: +# TADAM: Task dependent adaptive metric for improved few-shot learning (Oreshkin et al., in NIPS 2018) and +# A Simple Neural Attentive Meta-Learner (Mishra et al., in ICLR 2018). + +def conv3x3(in_planes, out_planes, stride=1): + """3x3 convolution with padding""" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=1, bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None, drop_rate=0.0, drop_block=False, block_size=1): + super(BasicBlock, self).__init__() + self.conv1 = conv3x3(inplanes, planes) + self.bn1 = nn.BatchNorm2d(planes) + self.relu = nn.LeakyReLU(0.1) + self.conv2 = conv3x3(planes, planes) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = conv3x3(planes, planes) + self.bn3 = nn.BatchNorm2d(planes) + self.maxpool = nn.MaxPool2d(stride) + self.downsample = downsample + self.stride = stride + self.drop_rate = drop_rate + self.num_batches_tracked = 0 + self.drop_block = drop_block + self.block_size = block_size + self.DropBlock = DropBlock(block_size=self.block_size) + + def forward(self, x): + self.num_batches_tracked += 1 + + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + out += residual + out = self.relu(out) + out = self.maxpool(out) + + if self.drop_rate > 0: + if self.drop_block == True: + feat_size = out.size()[2] + keep_rate = max(1.0 - self.drop_rate / (20*2000) * (self.num_batches_tracked), 1.0 - self.drop_rate) + gamma = (1 - keep_rate) / self.block_size**2 * feat_size**2 / (feat_size - self.block_size + 1)**2 + out = self.DropBlock(out, gamma=gamma) + else: + out = F.dropout(out, p=self.drop_rate, training=self.training, inplace=True) + + return out + + +class ResNet(nn.Module): + + def __init__(self, block=BasicBlock, keep_prob=1.0, avg_pool=True, drop_rate=0.1, dropblock_size=5): + self.inplanes = 3 + super(ResNet, self).__init__() + + self.layer1 = self._make_layer(block, 64, stride=2, drop_rate=drop_rate) + self.layer2 = self._make_layer(block, 160, stride=2, drop_rate=drop_rate) + self.layer3 = self._make_layer(block, 320, stride=2, drop_rate=drop_rate, drop_block=True, block_size=dropblock_size) + self.layer4 = self._make_layer(block, 640, stride=2, drop_rate=drop_rate, drop_block=True, block_size=dropblock_size) + if avg_pool: + self.avgpool = nn.AvgPool2d(5, stride=1) + self.keep_prob = keep_prob + self.keep_avg_pool = avg_pool + self.dropout = nn.Dropout(p=1 - self.keep_prob, inplace=False) + self.drop_rate = drop_rate + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='leaky_relu') + elif isinstance(m, nn.BatchNorm2d): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + def _make_layer(self, block, planes, stride=1, drop_rate=0.0, drop_block=False, block_size=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=1, bias=False), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample, drop_rate, drop_block, block_size)) + self.inplanes = planes * block.expansion + + return nn.Sequential(*layers) + + def forward(self, x): + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + if self.keep_avg_pool: + x = self.avgpool(x) + x = x.view(x.size(0), -1) + return x + + +def Res12(keep_prob=1.0, avg_pool=False, **kwargs): + """Constructs a ResNet-12 model. + """ + model = ResNet(BasicBlock, keep_prob=keep_prob, avg_pool=avg_pool, **kwargs) + return model diff --git a/feat/networks/resnet.py b/model/networks/res18.py similarity index 51% rename from feat/networks/resnet.py rename to model/networks/res18.py index c53f186..3f4fb28 100644 --- a/feat/networks/resnet.py +++ b/model/networks/res18.py @@ -1,12 +1,20 @@ -# ResNet Wide Version as in Qiao's Paper import torch.nn as nn +__all__ = ['resnet10', 'resnet18', 'resnet34', 'resnet50', 'resnet101', + 'resnet152'] + + def conv3x3(in_planes, out_planes, stride=1): """3x3 convolution with padding""" return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False) +def conv1x1(in_planes, out_planes, stride=1): + """1x1 convolution""" + return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False) + + class BasicBlock(nn.Module): expansion = 1 @@ -21,7 +29,7 @@ def __init__(self, inplanes, planes, stride=1, downsample=None): self.stride = stride def forward(self, x): - residual = x + identity = x out = self.conv1(x) out = self.bn1(out) @@ -31,9 +39,9 @@ def forward(self, x): out = self.bn2(out) if self.downsample is not None: - residual = self.downsample(x) + identity = self.downsample(x) - out += residual + out += identity out = self.relu(out) return out @@ -44,19 +52,18 @@ class Bottleneck(nn.Module): def __init__(self, inplanes, planes, stride=1, downsample=None): super(Bottleneck, self).__init__() - self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False) + self.conv1 = conv1x1(inplanes, planes) self.bn1 = nn.BatchNorm2d(planes) - self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, - padding=1, bias=False) + self.conv2 = conv3x3(planes, planes, stride) self.bn2 = nn.BatchNorm2d(planes) - self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False) + self.conv3 = conv1x1(planes, planes * self.expansion) self.bn3 = nn.BatchNorm2d(planes * self.expansion) self.relu = nn.ReLU(inplace=True) self.downsample = downsample self.stride = stride def forward(self, x): - residual = x + identity = x out = self.conv1(x) out = self.bn1(out) @@ -70,9 +77,9 @@ def forward(self, x): out = self.bn3(out) if self.downsample is not None: - residual = self.downsample(x) + identity = self.downsample(x) - out += residual + out += identity out = self.relu(out) return out @@ -80,20 +87,19 @@ def forward(self, x): class ResNet(nn.Module): - def __init__(self, block=BasicBlock, layers=[4,4,4]): + def __init__(self, block=BasicBlock, layers=[2, 2, 2, 2], zero_init_residual=False): super(ResNet, self).__init__() - cfg = [160, 320, 640] - self.inplanes = iChannels = int(cfg[0]/2) - self.conv1 = nn.Conv2d(3, iChannels, kernel_size=3, stride=1, padding=1) - self.bn1 = nn.BatchNorm2d(iChannels) + self.inplanes = 64 + self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, + bias=False) + self.bn1 = nn.BatchNorm2d(64) self.relu = nn.ReLU(inplace=True) - self.layer1 = self._make_layer(block, cfg[0], layers[0], stride=2) - self.layer2 = self._make_layer(block, cfg[1], layers[1], stride=2) - self.layer3 = self._make_layer(block, cfg[2], layers[2], stride=2) - self.avgpool = nn.AvgPool2d(10, stride=1) - # 512 * block.expansion - # self.FC = nn.Linear(cfg[2], num_classes) - + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2) + self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) + for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') @@ -101,19 +107,28 @@ def __init__(self, block=BasicBlock, layers=[4,4,4]): nn.init.constant_(m.weight, 1) nn.init.constant_(m.bias, 0) + # Zero-initialize the last BN in each residual branch, + # so that the residual branch starts with zeros, and each residual block behaves like an identity. + # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677 + if zero_init_residual: + for m in self.modules(): + if isinstance(m, Bottleneck): + nn.init.constant_(m.bn3.weight, 0) + elif isinstance(m, BasicBlock): + nn.init.constant_(m.bn2.weight, 0) + def _make_layer(self, block, planes, blocks, stride=1): downsample = None if stride != 1 or self.inplanes != planes * block.expansion: downsample = nn.Sequential( - nn.Conv2d(self.inplanes, planes * block.expansion, - kernel_size=1, stride=stride, bias=False), + conv1x1(self.inplanes, planes * block.expansion, stride), nn.BatchNorm2d(planes * block.expansion), ) layers = [] layers.append(block(self.inplanes, planes, stride, downsample)) self.inplanes = planes * block.expansion - for i in range(1, blocks): + for _ in range(1, blocks): layers.append(block(self.inplanes, planes)) return nn.Sequential(*layers) @@ -122,13 +137,55 @@ def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) - + x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) + x = self.layer4(x) x = self.avgpool(x) x = x.view(x.size(0), -1) - - # no FC here + return x + + +def resnet10(**kwargs): + """Constructs a ResNet-10 model. + """ + model = ResNet(BasicBlock, [1, 1, 1, 1], **kwargs) + return model + + +def resnet18(**kwargs): + """Constructs a ResNet-18 model. + """ + model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs) + return model + + +def resnet34(**kwargs): + """Constructs a ResNet-34 model. + """ + model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs) + return model + + +def resnet50(**kwargs): + """Constructs a ResNet-50 model. + """ + model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs) + return model + + +def resnet101(**kwargs): + """Constructs a ResNet-101 model. + """ + model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs) + return model + + +def resnet152(**kwargs): + """Constructs a ResNet-152 model. + """ + model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs) + return model \ No newline at end of file diff --git a/feat/models/__init__.py b/model/trainer/__init__.py similarity index 100% rename from feat/models/__init__.py rename to model/trainer/__init__.py diff --git a/model/trainer/base.py b/model/trainer/base.py new file mode 100644 index 0000000..a9b9e52 --- /dev/null +++ b/model/trainer/base.py @@ -0,0 +1,97 @@ +import abc +import torch +import os.path as osp + +from model.utils import ( + ensure_path, + Averager, Timer, count_acc, + compute_confidence_interval, +) +from model.logger import Logger + +class Trainer(object, metaclass=abc.ABCMeta): + def __init__(self, args): + self.args = args + # ensure_path( + # self.args.save_path, + # scripts_to_save=['model/models', 'model/networks', __file__], + # ) + self.logger = Logger(args, osp.join(args.save_path)) + + self.train_step = 0 + self.train_epoch = 0 + self.max_steps = args.episodes_per_epoch * args.max_epoch + self.dt, self.ft = Averager(), Averager() + self.bt, self.ot = Averager(), Averager() + self.timer = Timer() + + # train statistics + self.trlog = {} + self.trlog['max_acc'] = 0.0 + self.trlog['max_acc_epoch'] = 0 + self.trlog['max_acc_interval'] = 0.0 + + @abc.abstractmethod + def train(self): + pass + + @abc.abstractmethod + def evaluate(self, data_loader): + pass + + @abc.abstractmethod + def evaluate_test(self, data_loader): + pass + + @abc.abstractmethod + def final_record(self): + pass + + def try_evaluate(self, epoch): + args = self.args + if self.train_epoch % args.eval_interval == 0: + vl, va, vap = self.evaluate(self.val_loader) + self.logger.add_scalar('val_loss', float(vl), self.train_epoch) + self.logger.add_scalar('val_acc', float(va), self.train_epoch) + print('epoch {}, val, loss={:.4f} acc={:.4f}+{:.4f}'.format(epoch, vl, va, vap)) + + if va >= self.trlog['max_acc']: + self.trlog['max_acc'] = va + self.trlog['max_acc_interval'] = vap + self.trlog['max_acc_epoch'] = self.train_epoch + self.save_model('max_acc') + + def try_logging(self, tl1, tl2, ta, tg=None): + args = self.args + if self.train_step % args.log_interval == 0: + print('epoch {}, train {:06g}/{:06g}, total loss={:.4f}, loss={:.4f} acc={:.4f}, lr={:.4g}' + .format(self.train_epoch, + self.train_step, + self.max_steps, + tl1.item(), tl2.item(), ta.item(), + self.optimizer.param_groups[0]['lr'])) + self.logger.add_scalar('train_total_loss', tl1.item(), self.train_step) + self.logger.add_scalar('train_loss', tl2.item(), self.train_step) + self.logger.add_scalar('train_acc', ta.item(), self.train_step) + if tg is not None: + self.logger.add_scalar('grad_norm', tg.item(), self.train_step) + print('data_timer: {:.2f} sec, ' \ + 'forward_timer: {:.2f} sec,' \ + 'backward_timer: {:.2f} sec, ' \ + 'optim_timer: {:.2f} sec'.format( + self.dt.item(), self.ft.item(), + self.bt.item(), self.ot.item()) + ) + self.logger.dump() + + def save_model(self, name): + torch.save( + dict(params=self.model.state_dict()), + osp.join(self.args.save_path, name + '.pth') + ) + + def __str__(self): + return "{}({})".format( + self.__class__.__name__, + self.model.__class__.__name__ + ) diff --git a/model/trainer/fsl_trainer.py b/model/trainer/fsl_trainer.py new file mode 100644 index 0000000..87ab378 --- /dev/null +++ b/model/trainer/fsl_trainer.py @@ -0,0 +1,208 @@ +import time +import os.path as osp +import numpy as np + +import torch +import torch.nn.functional as F + +from model.trainer.base import Trainer +from model.trainer.helpers import ( + get_dataloader, prepare_model, prepare_optimizer, +) +from model.utils import ( + pprint, ensure_path, + Averager, Timer, count_acc, one_hot, + compute_confidence_interval, +) +from tensorboardX import SummaryWriter +from collections import deque +from tqdm import tqdm + +class FSLTrainer(Trainer): + def __init__(self, args): + super().__init__(args) + + self.train_loader, self.val_loader, self.test_loader = get_dataloader(args) + self.model, self.para_model = prepare_model(args) + self.optimizer, self.lr_scheduler = prepare_optimizer(self.model, args) + + def prepare_label(self): + args = self.args + + # prepare one-hot label + label = torch.arange(args.way, dtype=torch.int16).repeat(args.query) + label_aux = torch.arange(args.way, dtype=torch.int8).repeat(args.shot + args.query) + + label = label.type(torch.LongTensor) + label_aux = label_aux.type(torch.LongTensor) + + if torch.cuda.is_available(): + label = label.cuda() + label_aux = label_aux.cuda() + + return label, label_aux + + def train(self): + args = self.args + self.model.train() + if self.args.fix_BN: + self.model.encoder.eval() + + # start FSL training + label, label_aux = self.prepare_label() + for epoch in range(1, args.max_epoch + 1): + self.train_epoch += 1 + self.model.train() + if self.args.fix_BN: + self.model.encoder.eval() + + tl1 = Averager() + tl2 = Averager() + ta = Averager() + + start_tm = time.time() + for batch in self.train_loader: + self.train_step += 1 + + if torch.cuda.is_available(): + data, gt_label = [_.cuda() for _ in batch] + else: + data, gt_label = batch[0], batch[1] + + data_tm = time.time() + self.dt.add(data_tm - start_tm) + + # get saved centers + logits, reg_logits = self.para_model(data) + if reg_logits is not None: + loss = F.cross_entropy(logits, label) + total_loss = loss + args.balance * F.cross_entropy(reg_logits, label_aux) + else: + loss = F.cross_entropy(logits, label) + total_loss = F.cross_entropy(logits, label) + + tl2.add(loss) + forward_tm = time.time() + self.ft.add(forward_tm - data_tm) + acc = count_acc(logits, label) + + tl1.add(total_loss.item()) + ta.add(acc) + + self.optimizer.zero_grad() + total_loss.backward() + backward_tm = time.time() + self.bt.add(backward_tm - forward_tm) + + self.optimizer.step() + optimizer_tm = time.time() + self.ot.add(optimizer_tm - backward_tm) + + # refresh start_tm + start_tm = time.time() + + self.lr_scheduler.step() + self.try_evaluate(epoch) + + print('ETA:{}/{}'.format( + self.timer.measure(), + self.timer.measure(self.train_epoch / args.max_epoch)) + ) + + torch.save(self.trlog, osp.join(args.save_path, 'trlog')) + self.save_model('epoch-last') + + def evaluate(self, data_loader): + # restore model args + args = self.args + # evaluation mode + self.model.eval() + record = np.zeros((args.num_eval_episodes, 2)) # loss and acc + label = torch.arange(args.eval_way, dtype=torch.int16).repeat(args.eval_query) + label = label.type(torch.LongTensor) + if torch.cuda.is_available(): + label = label.cuda() + print('best epoch {}, best val acc={:.4f} + {:.4f}'.format( + self.trlog['max_acc_epoch'], + self.trlog['max_acc'], + self.trlog['max_acc_interval'])) + with torch.no_grad(): + for i, batch in enumerate(data_loader, 1): + if torch.cuda.is_available(): + data, _ = [_.cuda() for _ in batch] + else: + data = batch[0] + + logits = self.model(data) + loss = F.cross_entropy(logits, label) + acc = count_acc(logits, label) + record[i-1, 0] = loss.item() + record[i-1, 1] = acc + + assert(i == record.shape[0]) + vl, _ = compute_confidence_interval(record[:,0]) + va, vap = compute_confidence_interval(record[:,1]) + + # train mode + self.model.train() + if self.args.fix_BN: + self.model.encoder.eval() + + return vl, va, vap + + def evaluate_test(self): + # restore model args + args = self.args + # evaluation mode + self.model.load_state_dict(torch.load(osp.join(self.args.save_path, 'max_acc.pth'))['params']) + self.model.eval() + record = np.zeros((10000, 2)) # loss and acc + label = torch.arange(args.eval_way, dtype=torch.int16).repeat(args.eval_query) + label = label.type(torch.LongTensor) + if torch.cuda.is_available(): + label = label.cuda() + print('best epoch {}, best val acc={:.4f} + {:.4f}'.format( + self.trlog['max_acc_epoch'], + self.trlog['max_acc'], + self.trlog['max_acc_interval'])) + with torch.no_grad(): + for i, batch in tqdm(enumerate(self.test_loader, 1)): + if torch.cuda.is_available(): + data, _ = [_.cuda() for _ in batch] + else: + data = batch[0] + + logits = self.model(data) + loss = F.cross_entropy(logits, label) + acc = count_acc(logits, label) + record[i-1, 0] = loss.item() + record[i-1, 1] = acc + assert(i == record.shape[0]) + vl, _ = compute_confidence_interval(record[:,0]) + va, vap = compute_confidence_interval(record[:,1]) + + self.trlog['test_acc'] = va + self.trlog['test_acc_interval'] = vap + self.trlog['test_loss'] = vl + + print('best epoch {}, best val acc={:.4f} + {:.4f}\n'.format( + self.trlog['max_acc_epoch'], + self.trlog['max_acc'], + self.trlog['max_acc_interval'])) + print('Test acc={:.4f} + {:.4f}\n'.format( + self.trlog['test_acc'], + self.trlog['test_acc_interval'])) + + return vl, va, vap + + def final_record(self): + # save the best performance in a txt file + + with open(osp.join(self.args.save_path, '{}+{}'.format(self.trlog['test_acc'], self.trlog['test_acc_interval'])), 'w') as f: + f.write('best epoch {}, best val acc={:.4f} + {:.4f}\n'.format( + self.trlog['max_acc_epoch'], + self.trlog['max_acc'], + self.trlog['max_acc_interval'])) + f.write('Test acc={:.4f} + {:.4f}\n'.format( + self.trlog['test_acc'], + self.trlog['test_acc_interval'])) \ No newline at end of file diff --git a/model/trainer/helpers.py b/model/trainer/helpers.py new file mode 100644 index 0000000..bf7dd37 --- /dev/null +++ b/model/trainer/helpers.py @@ -0,0 +1,159 @@ +import torch +import torch.nn as nn +import numpy as np +import torch.optim as optim +from torch.utils.data import DataLoader +from model.dataloader.samplers import CategoriesSampler, RandomSampler, ClassSampler +from model.models.protonet import ProtoNet +from model.models.matchnet import MatchNet +from model.models.feat import FEAT +from model.models.featstar import FEATSTAR +from model.models.deepset import DeepSet +from model.models.bilstm import BILSTM +from model.models.graphnet import GCN + +class MultiGPUDataloader: + def __init__(self, dataloader, num_device): + self.dataloader = dataloader + self.num_device = num_device + + def __len__(self): + return len(self.dataloader) // self.num_device + + def __iter__(self): + data_iter = iter(self.dataloader) + done = False + + while not done: + try: + output_batch = ([], []) + for _ in range(self.num_device): + batch = next(data_iter) + for i, v in enumerate(batch): + output_batch[i].append(v[None]) + + yield ( torch.cat(_, dim=0) for _ in output_batch ) + except StopIteration: + done = True + return + +def get_dataloader(args): + if args.dataset == 'MiniImageNet': + # Handle MiniImageNet + from model.dataloader.mini_imagenet import MiniImageNet as Dataset + elif args.dataset == 'CUB': + from model.dataloader.cub import CUB as Dataset + elif args.dataset == 'TieredImageNet': + from model.dataloader.tiered_imagenet import tieredImageNet as Dataset + else: + raise ValueError('Non-supported Dataset.') + + num_device = torch.cuda.device_count() + num_episodes = args.episodes_per_epoch*num_device if args.multi_gpu else args.episodes_per_epoch + num_workers=args.num_workers*num_device if args.multi_gpu else args.num_workers + trainset = Dataset('train', args, augment=args.augment) + args.num_class = trainset.num_class + train_sampler = CategoriesSampler(trainset.label, + num_episodes, + max(args.way, args.num_classes), + args.shot + args.query) + + train_loader = DataLoader(dataset=trainset, + num_workers=num_workers, + batch_sampler=train_sampler, + pin_memory=True) + + #if args.multi_gpu and num_device > 1: + #train_loader = MultiGPUDataloader(train_loader, num_device) + #args.way = args.way * num_device + + valset = Dataset('val', args) + val_sampler = CategoriesSampler(valset.label, + args.num_eval_episodes, + args.eval_way, args.eval_shot + args.eval_query) + val_loader = DataLoader(dataset=valset, + batch_sampler=val_sampler, + num_workers=args.num_workers, + pin_memory=True) + + + testset = Dataset('test', args) + test_sampler = CategoriesSampler(testset.label, + 10000, # args.num_eval_episodes, + args.eval_way, args.eval_shot + args.eval_query) + test_loader = DataLoader(dataset=testset, + batch_sampler=test_sampler, + num_workers=args.num_workers, + pin_memory=True) + + return train_loader, val_loader, test_loader + +def prepare_model(args): + model = eval(args.model_class)(args) + + # load pre-trained model (no FC weights) + if args.init_weights is not None: + model_dict = model.state_dict() + pretrained_dict = torch.load(args.init_weights)['params'] + if args.backbone_class == 'ConvNet': + pretrained_dict = {'encoder.'+k: v for k, v in pretrained_dict.items()} + pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} + print(pretrained_dict.keys()) + model_dict.update(pretrained_dict) + model.load_state_dict(model_dict) + + if torch.cuda.is_available(): + torch.backends.cudnn.benchmark = True + + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + model = model.to(device) + if args.multi_gpu: + model.encoder = nn.DataParallel(model.encoder, dim=0) + para_model = model.to(device) + else: + para_model = model.to(device) + + return model, para_model + +def prepare_optimizer(model, args): + top_para = [v for k,v in model.named_parameters() if 'encoder' not in k] + # as in the literature, we use ADAM for ConvNet and SGD for other backbones + if args.backbone_class == 'ConvNet': + optimizer = optim.Adam( + [{'params': model.encoder.parameters()}, + {'params': top_para, 'lr': args.lr * args.lr_mul}], + lr=args.lr, + # weight_decay=args.weight_decay, do not use weight_decay here + ) + else: + optimizer = optim.SGD( + [{'params': model.encoder.parameters()}, + {'params': top_para, 'lr': args.lr * args.lr_mul}], + lr=args.lr, + momentum=args.mom, + nesterov=True, + weight_decay=args.weight_decay + ) + + if args.lr_scheduler == 'step': + lr_scheduler = optim.lr_scheduler.StepLR( + optimizer, + step_size=int(args.step_size), + gamma=args.gamma + ) + elif args.lr_scheduler == 'multistep': + lr_scheduler = optim.lr_scheduler.MultiStepLR( + optimizer, + milestones=[int(_) for _ in args.step_size.split(',')], + gamma=args.gamma, + ) + elif args.lr_scheduler == 'cosine': + lr_scheduler = optim.lr_scheduler.CosineAnnealingLR( + optimizer, + args.max_epoch, + eta_min=0 # a tuning parameter + ) + else: + raise ValueError('No Such Scheduler') + + return optimizer, lr_scheduler diff --git a/model/utils.py b/model/utils.py new file mode 100644 index 0000000..3c497b5 --- /dev/null +++ b/model/utils.py @@ -0,0 +1,184 @@ +import os +import shutil +import time +import pprint +import torch +import argparse +import numpy as np + +def one_hot(indices, depth): + """ + Returns a one-hot tensor. + This is a PyTorch equivalent of Tensorflow's tf.one_hot. + + Parameters: + indices: a (n_batch, m) Tensor or (m) Tensor. + depth: a scalar. Represents the depth of the one hot dimension. + Returns: a (n_batch, m, depth) Tensor or (m, depth) Tensor. + """ + + encoded_indicies = torch.zeros(indices.size() + torch.Size([depth])) + if indices.is_cuda: + encoded_indicies = encoded_indicies.cuda() + index = indices.view(indices.size()+torch.Size([1])) + encoded_indicies = encoded_indicies.scatter_(1,index,1) + + return encoded_indicies + +def set_gpu(x): + os.environ['CUDA_VISIBLE_DEVICES'] = x + print('using gpu:', x) + +def ensure_path(dir_path, scripts_to_save=None): + if os.path.exists(dir_path): + if input('{} exists, remove? ([y]/n)'.format(dir_path)) != 'n': + shutil.rmtree(dir_path) + os.mkdir(dir_path) + else: + os.mkdir(dir_path) + + print('Experiment dir : {}'.format(dir_path)) + if scripts_to_save is not None: + script_path = os.path.join(dir_path, 'scripts') + if not os.path.exists(script_path): + os.makedirs(script_path) + for src_file in scripts_to_save: + dst_file = os.path.join(dir_path, 'scripts', os.path.basename(src_file)) + print('copy {} to {}'.format(src_file, dst_file)) + if os.path.isdir(src_file): + shutil.copytree(src_file, dst_file) + else: + shutil.copyfile(src_file, dst_file) + +class Averager(): + + def __init__(self): + self.n = 0 + self.v = 0 + + def add(self, x): + self.v = (self.v * self.n + x) / (self.n + 1) + self.n += 1 + + def item(self): + return self.v + + +def count_acc(logits, label): + pred = torch.argmax(logits, dim=1) + if torch.cuda.is_available(): + return (pred == label).type(torch.cuda.FloatTensor).mean().item() + else: + return (pred == label).type(torch.FloatTensor).mean().item() + +def euclidean_metric(a, b): + n = a.shape[0] + m = b.shape[0] + a = a.unsqueeze(1).expand(n, m, -1) + b = b.unsqueeze(0).expand(n, m, -1) + logits = -((a - b)**2).sum(dim=2) + return logits + +class Timer(): + + def __init__(self): + self.o = time.time() + + def measure(self, p=1): + x = (time.time() - self.o) / p + x = int(x) + if x >= 3600: + return '{:.1f}h'.format(x / 3600) + if x >= 60: + return '{}m'.format(round(x / 60)) + return '{}s'.format(x) + +_utils_pp = pprint.PrettyPrinter() +def pprint(x): + _utils_pp.pprint(x) + +def compute_confidence_interval(data): + """ + Compute 95% confidence interval + :param data: An array of mean accuracy (or mAP) across a number of sampled episodes. + :return: the 95% confidence interval for this data. + """ + a = 1.0 * np.array(data) + m = np.mean(a) + std = np.std(a) + pm = 1.96 * (std / np.sqrt(len(a))) + return m, pm + +def postprocess_args(args): + args.num_classes = args.way + save_path1 = '-'.join([args.dataset, args.model_class, args.backbone_class, '{:02d}w{:02d}s{:02}q'.format(args.way, args.shot, args.query)]) + save_path2 = '_'.join([str('_'.join(args.step_size.split(','))), str(args.gamma), + 'lr{:.2g}mul{:.2g}'.format(args.lr, args.lr_mul), + str(args.lr_scheduler), + 'T1{}T2{}'.format(args.temperature, args.temperature2), + 'b{}'.format(args.balance), + 'bsz{:03d}'.format( max(args.way, args.num_classes)*(args.shot+args.query) ), + # str(time.strftime('%Y%m%d_%H%M%S')) + ]) + if args.init_weights is not None: + save_path1 += '-Pre' + if args.use_euclidean: + save_path1 += '-DIS' + else: + save_path1 += '-SIM' + + if args.fix_BN: + save_path2 += '-FBN' + if not args.augment: + save_path2 += '-NoAug' + + if not os.path.exists(os.path.join(args.save_dir, save_path1)): + os.mkdir(os.path.join(args.save_dir, save_path1)) + args.save_path = os.path.join(args.save_dir, save_path1, save_path2) + return args + +def get_command_line_parser(): + parser = argparse.ArgumentParser() + parser.add_argument('--max_epoch', type=int, default=200) + parser.add_argument('--episodes_per_epoch', type=int, default=100) + parser.add_argument('--num_eval_episodes', type=int, default=600) + parser.add_argument('--model_class', type=str, default='FEAT', + choices=['MatchNet', 'ProtoNet', 'BILSTM', 'DeepSet', 'GCN', 'FEAT', 'FEATSTAR']) # None for MatchNet or ProtoNet + parser.add_argument('--use_euclidean', action='store_true', default=False) + parser.add_argument('--backbone_class', type=str, default='Res12', + choices=['ConvNet', 'Res12', 'Res18', 'WRN']) + parser.add_argument('--dataset', type=str, default='MiniImageNet', + choices=['MiniImageNet', 'TieredImageNet', 'CUB']) + + parser.add_argument('--way', type=int, default=5) + parser.add_argument('--eval_way', type=int, default=5) + parser.add_argument('--shot', type=int, default=1) + parser.add_argument('--eval_shot', type=int, default=1) + parser.add_argument('--query', type=int, default=15) + parser.add_argument('--eval_query', type=int, default=15) + parser.add_argument('--balance', type=float, default=0) + parser.add_argument('--temperature', type=float, default=1) + parser.add_argument('--temperature2', type=float, default=1) # the temperature in the + + # optimization parameters + parser.add_argument('--orig_imsize', type=int, default=-1) # -1 for no cache, and -2 for no resize, only for MiniImageNet and CUB + parser.add_argument('--lr', type=float, default=0.0001) + parser.add_argument('--lr_mul', type=float, default=10) + parser.add_argument('--lr_scheduler', type=str, default='step', choices=['multistep', 'step', 'cosine']) + parser.add_argument('--step_size', type=str, default='20') + parser.add_argument('--gamma', type=float, default=0.2) + parser.add_argument('--fix_BN', action='store_true', default=False) # means we do not update the running mean/var in BN, not to freeze BN + parser.add_argument('--augment', action='store_true', default=False) + parser.add_argument('--multi_gpu', action='store_true', default=False) + parser.add_argument('--gpu', default='0') + parser.add_argument('--init_weights', type=str, default=None) + + # usually untouched parameters + parser.add_argument('--mom', type=float, default=0.9) + parser.add_argument('--weight_decay', type=float, default=0.0005) # we find this weight decay value works the best + parser.add_argument('--num_workers', type=int, default=4) + parser.add_argument('--log_interval', type=int, default=50) + parser.add_argument('--eval_interval', type=int, default=1) + parser.add_argument('--save_dir', type=str, default='./checkpoints') + + return parser \ No newline at end of file diff --git a/pretrain.py b/pretrain.py index 89aee75..d89a8de 100644 --- a/pretrain.py +++ b/pretrain.py @@ -1,60 +1,64 @@ import argparse +import os import os.path as osp import shutil import torch import torch.nn.functional as F from torch.utils.data import DataLoader -from feat.models.classifier import Classifier -from feat.dataloader.samplers import CategoriesSampler -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric +from model.models.classifier import Classifier +from model.dataloader.samplers import CategoriesSampler +from model.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric from tensorboardX import SummaryWriter from tqdm import tqdm -# pre-train backbone +# pre-train model, compute validation acc after 500 epoches if __name__ == '__main__': parser = argparse.ArgumentParser() - parser.add_argument('--batch_size', type=int, default=128) - parser.add_argument('--max_epoch', type=int, default=200) + parser.add_argument('--batch_size', type=int, default=16) + parser.add_argument('--max_epoch', type=int, default=500) parser.add_argument('--lr', type=float, default=0.001) parser.add_argument('--ngpu', type=int, default=1, help='0 = CPU.') - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'TieredImagenet']) - parser.add_argument('--model_type', type=str, default='ResNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--schedule', type=int, nargs='+', default=[30, 50, 80], help='Decrease learning rate at these epochs.') + parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'TieredImagenet', 'CUB']) + parser.add_argument('--backbone_class', type=str, default='Res12', choices=['ConvNet', 'Res12']) + parser.add_argument('--schedule', type=int, nargs='+', default=[75, 150, 300], help='Decrease learning rate at these epochs.') parser.add_argument('--gamma', type=float, default=0.1) + parser.add_argument('--query', type=int, default=15) parser.add_argument('--resume', type=bool, default=False) args = parser.parse_args() + args.orig_imsize = -1 pprint(vars(args)) - save_path1 = '-'.join([args.dataset, args.model_type, 'Pre']) - save_path2 = '_'.join([str(args.lr), str(args.gamma)]) + save_path1 = '-'.join([args.dataset, args.backbone_class, 'Pre']) + save_path2 = '_'.join([str(args.lr), str(args.gamma), str(args.schedule)]) args.save_path = osp.join(save_path1, save_path2) - ensure_path(save_path1, remove=False) + if not osp.exists(save_path1): + os.mkdir(save_path1) ensure_path(args.save_path) if args.dataset == 'MiniImageNet': # Handle MiniImageNet - from feat.dataloader.mini_imagenet_pre import MiniImageNet as Dataset + from model.dataloader.mini_imagenet import MiniImageNet as Dataset elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset + from model.dataloader.cub import CUB as Dataset elif args.dataset == 'TieredImagenet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset + from model.dataloader.tiered_imagenet import tieredImageNet as Dataset else: raise ValueError('Non-supported Dataset.') - trainset = Dataset('train', args) + trainset = Dataset('train', args, augment=True) train_loader = DataLoader(dataset=trainset, batch_size=args.batch_size, shuffle=True, num_workers=8, pin_memory=True) args.num_class = trainset.num_class valset = Dataset('val', args) - val_sampler = CategoriesSampler(valset.label, 200, valset.num_class, 1 + 15) # test on 16-way 1-shot + val_sampler = CategoriesSampler(valset.label, 200, valset.num_class, 1 + args.query) # test on 16-way 1-shot val_loader = DataLoader(dataset=valset, batch_sampler=val_sampler, num_workers=8, pin_memory=True) args.way = valset.num_class args.shot = 1 # construct model model = Classifier(args) - if args.model_type == 'ConvNet': + if 'Conv' in args.backbone_class: optimizer = torch.optim.Adam(model.parameters(), lr=args.lr, weight_decay=0.0005) - elif args.model_type == 'ResNet': + elif 'Res' in args.backbone_class: optimizer = torch.optim.SGD(model.parameters(), lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) else: raise ValueError('No Such Encoder') @@ -63,7 +67,7 @@ if torch.cuda.is_available(): torch.backends.cudnn.benchmark = True if args.ngpu > 1: - model = torch.nn.DataParallel(model, device_ids=list(range(args.ngpu))) + model.encoder = torch.nn.DataParallel(model.encoder, device_ids=list(range(args.ngpu))) model = model.cuda() criterion = criterion.cuda() @@ -76,7 +80,8 @@ def save_checkpoint(is_best, filename='checkpoint.pth.tar'): 'args': args, 'state_dict': model.state_dict(), 'trlog': trlog, - 'val_acc': trlog['max_acc'], + 'val_acc_dist': trlog['max_acc_dist'], + 'val_acc_sim': trlog['max_acc_sim'], 'optimizer' : optimizer.state_dict(), 'global_count': global_count} @@ -100,16 +105,20 @@ def save_checkpoint(is_best, filename='checkpoint.pth.tar'): trlog = {} trlog['args'] = vars(args) trlog['train_loss'] = [] - trlog['val_loss'] = [] + trlog['val_loss_dist'] = [] + trlog['val_loss_sim'] = [] trlog['train_acc'] = [] - trlog['val_acc'] = [] - trlog['max_acc'] = 0.0 - trlog['max_acc_epoch'] = 0 + trlog['val_acc_sim'] = [] + trlog['val_acc_dist'] = [] + trlog['max_acc_dist'] = 0.0 + trlog['max_acc_dist_epoch'] = 0 + trlog['max_acc_sim'] = 0.0 + trlog['max_acc_sim_epoch'] = 0 initial_lr = args.lr global_count = 0 timer = Timer() - writer = SummaryWriter(logdir=args.save_path) # should change to log_dir for previous version tensorboardX + writer = SummaryWriter(logdir=args.save_path) for epoch in range(init_epoch, args.max_epoch + 1): # refine the step-size if epoch in args.schedule: @@ -134,7 +143,8 @@ def save_checkpoint(is_best, filename='checkpoint.pth.tar'): acc = count_acc(logits, label) writer.add_scalar('data/loss', float(loss), global_count) writer.add_scalar('data/acc', float(acc), global_count) - print('epoch {}, train {}/{}, loss={:.4f} acc={:.4f}'.format(epoch, i, len(train_loader), loss.item(), acc)) + if (i-1) % 100 == 0: + print('epoch {}, train {}/{}, loss={:.4f} acc={:.4f}'.format(epoch, i, len(train_loader), loss.item(), acc)) tl.add(loss.item()) ta.add(acc) @@ -147,13 +157,16 @@ def save_checkpoint(is_best, filename='checkpoint.pth.tar'): ta = ta.item() # do not do validation in first 500 epoches - if epoch > 30 or epoch % 5 == 0: + if epoch > 100 or (epoch-1) % 5 == 0: model.eval() - vl = Averager() - va = Averager() - print('best epoch {}, current best val acc={:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'])) + vl_dist = Averager() + va_dist = Averager() + vl_sim = Averager() + va_sim = Averager() + print('[Dist] best epoch {}, current best val acc={:.4f}'.format(trlog['max_acc_dist_epoch'], trlog['max_acc_dist'])) + print('[Sim] best epoch {}, current best val acc={:.4f}'.format(trlog['max_acc_sim_epoch'], trlog['max_acc_sim'])) # test performance with Few-Shot - label = torch.arange(valset.num_class).repeat(15) + label = torch.arange(valset.num_class).repeat(args.query) if torch.cuda.is_available(): label = label.type(torch.cuda.LongTensor) else: @@ -165,31 +178,44 @@ def save_checkpoint(is_best, filename='checkpoint.pth.tar'): else: data, _ = batch data_shot, data_query = data[:valset.num_class], data[valset.num_class:] # 16-way test - if args.ngpu > 1: - logits = model.module.forward_proto(data_shot, data_query, valset.num_class) - else: - logits = model.forward_proto(data_shot, data_query, valset.num_class) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - vl.add(loss.item()) - va.add(acc) + logits_dist, logits_sim = model.forward_proto(data_shot, data_query, valset.num_class) + loss_dist = F.cross_entropy(logits_dist, label) + acc_dist = count_acc(logits_dist, label) + loss_sim = F.cross_entropy(logits_sim, label) + acc_sim = count_acc(logits_sim, label) + vl_dist.add(loss_dist.item()) + va_dist.add(acc_dist) + vl_sim.add(loss_sim.item()) + va_sim.add(acc_sim) - vl = vl.item() - va = va.item() - writer.add_scalar('data/val_loss', float(vl), epoch) - writer.add_scalar('data/val_acc', float(va), epoch) - print('epoch {}, val, loss={:.4f} acc={:.4f}'.format(epoch, vl, va)) + vl_dist = vl_dist.item() + va_dist = va_dist.item() + vl_sim = vl_sim.item() + va_sim = va_sim.item() + writer.add_scalar('data/val_loss_dist', float(vl_dist), epoch) + writer.add_scalar('data/val_acc_dist', float(va_dist), epoch) + writer.add_scalar('data/val_loss_sim', float(vl_sim), epoch) + writer.add_scalar('data/val_acc_sim', float(va_sim), epoch) + print('epoch {}, val, loss_dist={:.4f} acc_dist={:.4f} loss_sim={:.4f} acc_sim={:.4f}'.format(epoch, vl_dist, va_dist, vl_sim, va_sim)) - if va > trlog['max_acc']: - trlog['max_acc'] = va - trlog['max_acc_epoch'] = epoch - save_model('max_acc') + if va_dist > trlog['max_acc_dist']: + trlog['max_acc_dist'] = va_dist + trlog['max_acc_dist_epoch'] = epoch + save_model('max_acc_dist') save_checkpoint(True) + + if va_sim > trlog['max_acc_sim']: + trlog['max_acc_sim'] = va_sim + trlog['max_acc_sim_epoch'] = epoch + save_model('max_acc_sim') + save_checkpoint(True) trlog['train_loss'].append(tl) trlog['train_acc'].append(ta) - trlog['val_loss'].append(vl) - trlog['val_acc'].append(va) + trlog['val_loss_dist'].append(vl_dist) + trlog['val_acc_dist'].append(va_dist) + trlog['val_loss_sim'].append(vl_sim) + trlog['val_acc_sim'].append(va_sim) save_model('epoch-last') print('ETA:{}/{}'.format(timer.measure(), timer.measure(epoch / args.max_epoch))) diff --git a/train_feat.py b/train_feat.py deleted file mode 100644 index 4caa271..0000000 --- a/train_feat.py +++ /dev/null @@ -1,227 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader - -from feat.models.feat import FEAT -from feat.dataloader.samplers import CategoriesSampler -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--max_epoch', type=int, default=200) - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=5) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--lr', type=float, default=0.0001) - parser.add_argument('--lr_mul', type=float, default=10) # lr is the basic learning rate, while lr * lr_mul is the lr for other parts - parser.add_argument('--temperature', type=float, default=16) - parser.add_argument('--temperature2', type=float, default=1) - parser.add_argument('--balance', type=float, default=10) - parser.add_argument('--step_size', type=int, default=10) - parser.add_argument('--gamma', type=float, default=0.5) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - # MiniImageNet, ConvNet, './saves/initialization/miniimagenet/con-pre.pth' - # MiniImageNet, ResNet, './saves/initialization/miniimagenet/res-pre.pth' - # CUB, ConvNet, './saves/initialization/cub/con-pre.pth' - parser.add_argument('--init_weights', type=str, default=None) - parser.add_argument('--head', type=int, default=1) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - pprint(vars(args)) - - set_gpu(args.gpu) - save_path1 = '-'.join([args.dataset, args.model_type, 'FEAT', str(args.shot), str(args.way)]) - save_path2 = '_'.join([str(args.step_size), str(args.gamma), str(args.lr), - str(args.balance), str(args.temperature), str(args.temperature2), str(args.head)]) - args.save_path = osp.join(save_path1, save_path2) - ensure_path(save_path1, remove=False) - ensure_path(args.save_path) - - if args.dataset == 'MiniImageNet': - # Handle MiniImageNet - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - trainset = Dataset('train', args) - train_sampler = CategoriesSampler(trainset.label, 100, args.way, args.shot + args.query) - train_loader = DataLoader(dataset=trainset, batch_sampler=train_sampler, num_workers=8, pin_memory=True) - - valset = Dataset('val', args) - val_sampler = CategoriesSampler(valset.label, 600, args.way, args.shot + args.query) - val_loader = DataLoader(dataset=valset, batch_sampler=val_sampler, num_workers=8, pin_memory=True) - - model = FEAT(args, dropout = 0.5) - if args.model_type == 'ConvNet': - optimizer = torch.optim.Adam([{'params': model.encoder.parameters()}, - {'params': model.slf_attn.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr) - elif args.model_type == 'ResNet': - optimizer = torch.optim.SGD([{'params': model.encoder.parameters()}, - {'params': model.slf_attn.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) - else: - raise ValueError('No Such Encoder') - - lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=args.step_size, gamma=args.gamma) - - # load pre-trained model (no FC weights) - model_dict = model.state_dict() - if args.init_weights is not None: - pretrained_dict = torch.load(args.init_weights)['params'] - # remove weights for FC - pretrained_dict = {'encoder.'+k: v for k, v in pretrained_dict.items()} - pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} - print(pretrained_dict.keys()) - model_dict.update(pretrained_dict) - model.load_state_dict(model_dict) - - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - def save_model(name): - torch.save(dict(params=model.state_dict()), osp.join(args.save_path, name + '.pth')) - - trlog = {} - trlog['args'] = vars(args) - trlog['train_loss'] = [] - trlog['val_loss'] = [] - trlog['train_acc'] = [] - trlog['val_acc'] = [] - trlog['max_acc'] = 0.0 - trlog['max_acc_epoch'] = 0 - - timer = Timer() - global_count = 0 - writer = SummaryWriter(logdir=args.save_path) # should be changed to logdir in the latest version - - label = torch.arange(args.way, dtype=torch.int8).repeat(args.query).type(torch.LongTensor) - label_aux = torch.arange(args.way, dtype=torch.int8).repeat(args.shot + args.query).type(torch.LongTensor) - if torch.cuda.is_available(): - label = label.cuda() - label_aux = label_aux.cuda() - - for epoch in range(1, args.max_epoch + 1): - lr_scheduler.step() - model.train() - tl = Averager() - ta = Averager() - - for i, batch in enumerate(train_loader, 1): - global_count = global_count + 1 - if torch.cuda.is_available(): - data, index_label = batch[0].cuda(), batch[1].cuda() - else: - data, index_label = batch[0], batch[1] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - logits, logits2 = model(data_shot, data_query, 'train') - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - writer.add_scalar('data/loss', float(loss), global_count) - writer.add_scalar('data/acc', float(acc), global_count) - - total_loss = loss + args.balance * F.cross_entropy(logits2, label_aux) - writer.add_scalar('data/total_loss', float(total_loss), global_count) - print('epoch {}, train {}/{}, total loss={:.4f}, loss={:.4f} acc={:.4f}' - .format(epoch, i, len(train_loader), total_loss.item(), loss.item(), acc)) - - tl.add(total_loss.item()) - ta.add(acc) - - optimizer.zero_grad() - total_loss.backward() - optimizer.step() - - tl = tl.item() - ta = ta.item() - - model.eval() - - vl = Averager() - va = Averager() - - print('best epoch {}, best val acc={:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'])) - with torch.no_grad(): - for i, batch in enumerate(val_loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - logits = model(data_shot, data_query) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - vl.add(loss.item()) - va.add(acc) - - vl = vl.item() - va = va.item() - writer.add_scalar('data/val_loss', float(vl), epoch) - writer.add_scalar('data/val_acc', float(va), epoch) - print('epoch {}, val, loss={:.4f} acc={:.4f}'.format(epoch, vl, va)) - - if va >= trlog['max_acc']: - trlog['max_acc'] = va - trlog['max_acc_epoch'] = epoch - save_model('max_acc') - - trlog['train_loss'].append(tl) - trlog['train_acc'].append(ta) - trlog['val_loss'].append(vl) - trlog['val_acc'].append(va) - - torch.save(trlog, osp.join(args.save_path, 'trlog')) - - save_model('epoch-last') - - print('ETA:{}/{}'.format(timer.measure(), timer.measure(epoch / args.max_epoch))) - writer.close() - - # Test Phase - trlog = torch.load(osp.join(args.save_path, 'trlog')) - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(osp.join(args.save_path, 'max_acc' + '.pth'))['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Val Best Epoch {}, Acc {:.4f}, Test Acc {:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'], ave_acc.item())) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) - - import pdb - pdb.set_trace() \ No newline at end of file diff --git a/train_feat_star.py b/train_feat_star.py deleted file mode 100644 index 23548ec..0000000 --- a/train_feat_star.py +++ /dev/null @@ -1,237 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader - -from feat.models.feat_star import FEAT -from feat.dataloader.samplers import CategoriesSampler -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--max_epoch', type=int, default=200) - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--lr', type=float, default=0.0001) - parser.add_argument('--lr_mul', type=float, default=10) # lr is the basic learning rate, while lr * lr_mul is the lr for other parts - parser.add_argument('--temperature', type=float, default=1) - parser.add_argument('--balance', type=float, default=10) - parser.add_argument('--step_size', type=int, default=10) - parser.add_argument('--gamma', type=float, default=0.5) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - # MiniImageNet, ConvNet, './saves/initialization/miniimagenet/con-pre.pth' - # MiniImageNet, ResNet, './saves/initialization/miniimagenet/res-pre.pth' - # CUB, ConvNet, './saves/initialization/cub/con-pre.pth' - parser.add_argument('--init_weights', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - pprint(vars(args)) - - set_gpu(args.gpu) - save_path1 = '-'.join([args.dataset, args.model_type, 'FEATSTAR']) - save_path2 = '_'.join([str(args.shot), str(args.query), str(args.way), - str(args.step_size), str(args.gamma), str(args.lr), str(args.balance), str(args.temperature)]) - args.save_path = osp.join(save_path1, save_path2) - ensure_path(save_path1, remove=False) - ensure_path(args.save_path) - - if args.dataset == 'MiniImageNet': - # Handle MiniImageNet - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - trainset = Dataset('train', args) - train_sampler = CategoriesSampler(trainset.label, 100, args.way, args.shot + args.query) - train_loader = DataLoader(dataset=trainset, batch_sampler=train_sampler, num_workers=8, pin_memory=True) - - valset = Dataset('val', args) - val_sampler = CategoriesSampler(valset.label, 500, args.way, args.shot + args.query) - val_loader = DataLoader(dataset=valset, batch_sampler=val_sampler, num_workers=8, pin_memory=True) - - model = FEAT(args, dropout = 0.5) - if args.model_type == 'ConvNet': - optimizer = torch.optim.Adam([{'params': model.encoder.parameters()}, - {'params': model.slf_attn.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr) - elif args.model_type == 'ResNet': - optimizer = torch.optim.SGD([{'params': model.encoder.parameters()}, - {'params': model.slf_attn.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) - else: - raise ValueError('No Such Encoder') - - lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=args.step_size, gamma=args.gamma) - - # load pre-trained model (no FC weights) - model_dict = model.state_dict() - if args.init_weights is not None: - pretrained_dict = torch.load(args.init_weights)['params'] - # remove weights for FC - pretrained_dict = {'encoder.'+k: v for k, v in pretrained_dict.items()} - pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} - print(pretrained_dict.keys()) - model_dict.update(pretrained_dict) - model.load_state_dict(model_dict) - - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - def save_model(name): - torch.save(dict(params=model.state_dict()), osp.join(args.save_path, name + '.pth')) - - trlog = {} - trlog['args'] = vars(args) - trlog['train_loss'] = [] - trlog['val_loss'] = [] - trlog['train_acc'] = [] - trlog['val_acc'] = [] - trlog['max_acc'] = 0.0 - trlog['max_acc_epoch'] = 0 - - timer = Timer() - global_count = 0 - writer = SummaryWriter(logdir=args.save_path) # should be changed to logdir in the latest version - - # construct attention label - att_label_basis = [] - for i in range(args.way): - temp = torch.eye(args.way + 1) - temp[i, i] = 0.5 - temp[-1, -1] = 0.5 - temp[i, -1] = 0.5 - temp[-1, i] = 0.5 - att_label_basis.append(temp) - - label = torch.arange(args.way, dtype=torch.int8).repeat(args.query) - att_label = torch.zeros(label.shape[0], args.way + 1, args.way + 1) - for i in range(att_label.shape[0]): - att_label[i,:] = att_label_basis[label[i].item()] - label = label.type(torch.LongTensor) - if torch.cuda.is_available(): - label = label.cuda() - att_label = att_label.cuda() - - for epoch in range(1, args.max_epoch + 1): - lr_scheduler.step() - model.train() - tl = Averager() - ta = Averager() - - for i, batch in enumerate(train_loader, 1): - global_count = global_count + 1 - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - logits, att = model(data_shot, data_query) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - writer.add_scalar('data/loss', float(loss), global_count) - writer.add_scalar('data/acc', float(acc), global_count) - - # attention loss, NK x (N+1) x (N + 1) - loss_att = F.kl_div(att.view(-1, args.way + 1), att_label.view(-1, args.way + 1)) - total_loss = loss + args.balance * loss_att - writer.add_scalar('data/total_loss', float(total_loss), global_count) - print('epoch {}, train {}/{}, total loss={:.4f}, loss={:.4f} acc={:.4f}' - .format(epoch, i, len(train_loader), total_loss.item(), loss.item(), acc)) - - tl.add(total_loss.item()) - ta.add(acc) - - optimizer.zero_grad() - total_loss.backward() - optimizer.step() - - tl = tl.item() - ta = ta.item() - - model.eval() - - vl = Averager() - va = Averager() - - print('best epoch {}, best val acc={:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'])) - with torch.no_grad(): - for i, batch in enumerate(val_loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - logits, _ = model(data_shot, data_query) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - vl.add(loss.item()) - va.add(acc) - - vl = vl.item() - va = va.item() - writer.add_scalar('data/val_loss', float(vl), epoch) - writer.add_scalar('data/val_acc', float(va), epoch) - print('epoch {}, val, loss={:.4f} acc={:.4f}'.format(epoch, vl, va)) - - if va >= trlog['max_acc']: - trlog['max_acc'] = va - trlog['max_acc_epoch'] = epoch - save_model('max_acc') - - trlog['train_loss'].append(tl) - trlog['train_acc'].append(ta) - trlog['val_loss'].append(vl) - trlog['val_acc'].append(va) - - torch.save(trlog, osp.join(args.save_path, 'trlog')) - - save_model('epoch-last') - - print('ETA:{}/{}'.format(timer.measure(), timer.measure(epoch / args.max_epoch))) - writer.close() - - # Test Phase - trlog = torch.load(osp.join(args.save_path, 'trlog')) - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(osp.join(args.save_path, 'max_acc' + '.pth'))['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits, _ = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - - m, pm = compute_confidence_interval(test_acc_record) - print('Val Best Epoch {}, Acc {:.4f}, Test Acc {:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'], ave_acc.item())) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/train_fsl.py b/train_fsl.py new file mode 100644 index 0000000..f3eec3c --- /dev/null +++ b/train_fsl.py @@ -0,0 +1,25 @@ +import numpy as np +import torch +from model.trainer.fsl_trainer import FSLTrainer +from model.utils import ( + pprint, set_gpu, + get_command_line_parser, + postprocess_args, +) +# from ipdb import launch_ipdb_on_exception + +if __name__ == '__main__': + parser = get_command_line_parser() + args = postprocess_args(parser.parse_args()) + # with launch_ipdb_on_exception(): + pprint(vars(args)) + + set_gpu(args.gpu) + trainer = FSLTrainer(args) + trainer.train() + trainer.evaluate_test() + trainer.final_record() + print(args.save_path) + + + diff --git a/train_matchnet.py b/train_matchnet.py deleted file mode 100644 index da9fb2f..0000000 --- a/train_matchnet.py +++ /dev/null @@ -1,245 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader -from feat.dataloader.samplers import CategoriesSampler -from feat.models.matchnet import MatchNet -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, euclidean_metric, compute_confidence_interval -from tensorboardX import SummaryWriter - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--max_epoch', type=int, default=200) - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--lr', type=float, default=0.0001) - parser.add_argument('--lr_mul', type=float, default=1) # lr is the basic learning rate, while lr * lr_mul is the lr for other parts - parser.add_argument('--step_size', type=int, default=10) - parser.add_argument('--gamma', type=float, default=0.2) - parser.add_argument('--temperature', type=float, default=1) - parser.add_argument('--use_bilstm', type=bool, default=False) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - # MiniImageNet, ConvNet, './saves/initialization/miniimagenet/con-pre.pth' - # MiniImageNet, ResNet, './saves/initialization/miniimagenet/res-pre.pth' - # CUB, ConvNet, './saves/initialization/cub/con-pre.pth' - parser.add_argument('--init_weights', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - pprint(vars(args)) - - set_gpu(args.gpu) - save_path1 = '-'.join([args.dataset, args.model_type, 'MatchNet']) - save_path2 = '_'.join([str(args.shot), str(args.query), str(args.way), - str(args.step_size), str(args.gamma), str(args.lr), str(args.temperature)]) - if args.use_bilstm: - save_path2 = save_path2 + '_' + str(args.lr_mul) + '_BiLSTM' - args.save_path = osp.join(save_path1, save_path2) - ensure_path(save_path1, remove=False) - ensure_path(args.save_path) - - if args.dataset == 'MiniImageNet': - # Handle MiniImageNet - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - trainset = Dataset('train', args) - train_sampler = CategoriesSampler(trainset.label, 100, args.way, args.shot + args.query) - train_loader = DataLoader(dataset=trainset, batch_sampler=train_sampler, num_workers=8, pin_memory=True) - - valset = Dataset('val', args) - val_sampler = CategoriesSampler(valset.label, 500, args.way, args.shot + args.query) - val_loader = DataLoader(dataset=valset, batch_sampler=val_sampler, num_workers=8, pin_memory=True) - - model = MatchNet(args) - if args.model_type == 'ConvNet': - if args.use_bilstm: - optimizer = torch.optim.Adam([{'params': model.encoder.parameters()}, - {'params': model.bilstm.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr) - else: - optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) - elif args.model_type == 'ResNet': - if args.use_bilstm: - optimizer = torch.optim.SGD([{'params': model.encoder.parameters()}, - {'params': model.bilstm.parameters(), 'lr': args.lr * args.lr_mul}], lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) - else: - optimizer = torch.optim.SGD(model.parameters(), lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) - else: - raise ValueError('No Such Encoder') - - lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=args.step_size, gamma=args.gamma) - - # load pre-trained model (no FC weights) - model_dict = model.state_dict() - if args.init_weights is not None: - pretrained_dict = torch.load(args.init_weights)['params'] - # remove weights for FC - pretrained_dict = {'encoder.'+k: v for k, v in pretrained_dict.items()} - pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} - print(pretrained_dict.keys()) - model_dict.update(pretrained_dict) - model.load_state_dict(model_dict) - - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - def save_model(name): - torch.save(dict(params=model.state_dict()), osp.join(args.save_path, name + '.pth')) - - trlog = {} - trlog['args'] = vars(args) - trlog['train_loss'] = [] - trlog['val_loss'] = [] - trlog['train_acc'] = [] - trlog['val_acc'] = [] - trlog['max_acc'] = 0.0 - trlog['max_acc_epoch'] = 0 - - timer = Timer() - global_count = 0 - writer = SummaryWriter(logdir=args.save_path) - - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - label_support = torch.arange(args.way).repeat(args.shot) - label_support = label_support.type(torch.LongTensor) - # transform to one-hot form - label_support_onehot = torch.zeros(args.way * args.shot, args.way) - label_support_onehot.scatter_(1, label_support.unsqueeze(1), 1) - if torch.cuda.is_available(): - label_support_onehot = label_support_onehot.cuda() # KN x N - - for epoch in range(1, args.max_epoch + 1): - lr_scheduler.step() - model.train() - tl = Averager() - ta = Averager() - - for i, batch in enumerate(train_loader, 1): - global_count = global_count + 1 - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - - logits = model(data_shot, data_query) # KqN x KN x 1 - # use logits to weights all labels, KN x N - prediction = torch.sum(torch.mul(logits, label_support_onehot.unsqueeze(0)), 1) # KqN x N - # compute loss - loss = F.cross_entropy(prediction, label) - acc = count_acc(prediction, label) - writer.add_scalar('data/loss', float(loss), global_count) - writer.add_scalar('data/acc', float(acc), global_count) - print('epoch {}, train {}/{}, loss={:.4f} acc={:.4f}' - .format(epoch, i, len(train_loader), loss.item(), acc)) - - tl.add(loss.item()) - ta.add(acc) - - optimizer.zero_grad() - loss.backward() - optimizer.step() - - tl = tl.item() - ta = ta.item() - - model.eval() - - vl = Averager() - va = Averager() - - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - print('best epoch {}, best val acc={:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'])) - with torch.no_grad(): - for i, batch in enumerate(val_loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - - logits = model(data_shot, data_query) # KqN x KN x 1 - # use logits to weights all labels, KN x N - prediction = torch.sum(torch.mul(logits, label_support_onehot.unsqueeze(0)), 1) # KqN x N - # compute loss - loss = F.cross_entropy(prediction, label) - acc = count_acc(prediction, label) - vl.add(loss.item()) - va.add(acc) - - vl = vl.item() - va = va.item() - writer.add_scalar('data/val_loss', float(vl), epoch) - writer.add_scalar('data/val_acc', float(va), epoch) - print('epoch {}, val, loss={:.4f} acc={:.4f}'.format(epoch, vl, va)) - - if va > trlog['max_acc']: - trlog['max_acc'] = va - trlog['max_acc_epoch'] = epoch - save_model('max_acc') - - trlog['train_loss'].append(tl) - trlog['train_acc'].append(ta) - trlog['val_loss'].append(vl) - trlog['val_acc'].append(va) - - torch.save(trlog, osp.join(args.save_path, 'trlog')) - - save_model('epoch-last') - - print('ETA:{}/{}'.format(timer.measure(), timer.measure(epoch / args.max_epoch))) - writer.close() - - # Test Phase - trlog = torch.load(osp.join(args.save_path, 'trlog')) - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(osp.join(args.save_path, 'max_acc' + '.pth'))['params']) - model.eval() - - ave_acc = Averager() - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - logits = model(data_shot, data_query) # KqN x KN x 1 - # use logits to weights all labels, KN x N - prediction = torch.sum(torch.mul(logits, label_support_onehot.unsqueeze(0)), 1) # KqN x N - acc = count_acc(prediction, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Val Best Acc {:.4f}, Test Acc {:.4f}'.format(trlog['max_acc'], ave_acc.item())) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file diff --git a/train_protonet.py b/train_protonet.py deleted file mode 100644 index 509328c..0000000 --- a/train_protonet.py +++ /dev/null @@ -1,222 +0,0 @@ -import argparse -import os.path as osp - -import numpy as np -import torch -import torch.nn.functional as F -from torch.utils.data import DataLoader -from feat.dataloader.samplers import CategoriesSampler -from feat.models.protonet import ProtoNet -from feat.utils import pprint, set_gpu, ensure_path, Averager, Timer, count_acc, compute_confidence_interval -from tensorboardX import SummaryWriter - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--max_epoch', type=int, default=200) - parser.add_argument('--shot', type=int, default=1) - parser.add_argument('--query', type=int, default=15) - parser.add_argument('--way', type=int, default=5) - parser.add_argument('--lr', type=float, default=0.0001) - parser.add_argument('--step_size', type=int, default=10) - parser.add_argument('--gamma', type=float, default=0.2) - parser.add_argument('--temperature', type=float, default=1) - parser.add_argument('--model_type', type=str, default='ConvNet', choices=['ConvNet', 'ResNet']) - parser.add_argument('--dataset', type=str, default='MiniImageNet', choices=['MiniImageNet', 'CUB', 'TieredImageNet']) - # MiniImageNet, ConvNet, './saves/initialization/miniimagenet/con-pre.pth' - # MiniImageNet, ResNet, './saves/initialization/miniimagenet/res-pre.pth' - # CUB, ConvNet, './saves/initialization/cub/con-pre.pth' - parser.add_argument('--init_weights', type=str, default=None) - parser.add_argument('--gpu', default='0') - args = parser.parse_args() - pprint(vars(args)) - - set_gpu(args.gpu) - save_path1 = '-'.join([args.dataset, args.model_type, 'ProtoNet']) - save_path2 = '_'.join([str(args.shot), str(args.query), str(args.way), - str(args.step_size), str(args.gamma), str(args.lr), str(args.temperature)]) - args.save_path = osp.join(save_path1, save_path2) - ensure_path(save_path1, remove=False) - ensure_path(args.save_path) - - if args.dataset == 'MiniImageNet': - # Handle MiniImageNet - from feat.dataloader.mini_imagenet import MiniImageNet as Dataset - elif args.dataset == 'CUB': - from feat.dataloader.cub import CUB as Dataset - elif args.dataset == 'TieredImageNet': - from feat.dataloader.tiered_imagenet import tieredImageNet as Dataset - else: - raise ValueError('Non-supported Dataset.') - - trainset = Dataset('train', args) - train_sampler = CategoriesSampler(trainset.label, 100, args.way, args.shot + args.query) - train_loader = DataLoader(dataset=trainset, batch_sampler=train_sampler, num_workers=8, pin_memory=True) - - valset = Dataset('val', args) - val_sampler = CategoriesSampler(valset.label, 500, args.way, args.shot + args.query) - val_loader = DataLoader(dataset=valset, batch_sampler=val_sampler, num_workers=8, pin_memory=True) - - model = ProtoNet(args) - if args.model_type == 'ConvNet': - optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) - elif args.model_type == 'ResNet': - optimizer = torch.optim.SGD(model.parameters(), lr=args.lr, momentum=0.9, nesterov=True, weight_decay=0.0005) - else: - raise ValueError('No Such Encoder') - lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=args.step_size, gamma=args.gamma) - - # load pre-trained model (no FC weights) - model_dict = model.state_dict() - if args.init_weights is not None: - pretrained_dict = torch.load(args.init_weights)['params'] - # remove weights for FC - pretrained_dict = {'encoder.'+k: v for k, v in pretrained_dict.items()} - pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} - print(pretrained_dict.keys()) - model_dict.update(pretrained_dict) - model.load_state_dict(model_dict) - - if torch.cuda.is_available(): - torch.backends.cudnn.benchmark = True - model = model.cuda() - - def save_model(name): - torch.save(dict(params=model.state_dict()), osp.join(args.save_path, name + '.pth')) - - trlog = {} - trlog['args'] = vars(args) - trlog['train_loss'] = [] - trlog['val_loss'] = [] - trlog['train_acc'] = [] - trlog['val_acc'] = [] - trlog['max_acc'] = 0.0 - trlog['max_acc_epoch'] = 0 - - timer = Timer() - global_count = 0 - writer = SummaryWriter(logdir=args.save_path) - - for epoch in range(1, args.max_epoch + 1): - lr_scheduler.step() - model.train() - tl = Averager() - ta = Averager() - - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - for i, batch in enumerate(train_loader, 1): - global_count = global_count + 1 - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - logits = model(data_shot, data_query) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - writer.add_scalar('data/loss', float(loss), global_count) - writer.add_scalar('data/acc', float(acc), global_count) - print('epoch {}, train {}/{}, loss={:.4f} acc={:.4f}' - .format(epoch, i, len(train_loader), loss.item(), acc)) - - tl.add(loss.item()) - ta.add(acc) - - optimizer.zero_grad() - loss.backward() - optimizer.step() - - tl = tl.item() - ta = ta.item() - - model.eval() - - vl = Averager() - va = Averager() - - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - print('best epoch {}, best val acc={:.4f}'.format(trlog['max_acc_epoch'], trlog['max_acc'])) - with torch.no_grad(): - for i, batch in enumerate(val_loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - p = args.shot * args.way - data_shot, data_query = data[:p], data[p:] - - logits = model(data_shot, data_query) - loss = F.cross_entropy(logits, label) - acc = count_acc(logits, label) - vl.add(loss.item()) - va.add(acc) - - vl = vl.item() - va = va.item() - writer.add_scalar('data/val_loss', float(vl), epoch) - writer.add_scalar('data/val_acc', float(va), epoch) - print('epoch {}, val, loss={:.4f} acc={:.4f}'.format(epoch, vl, va)) - - if va > trlog['max_acc']: - trlog['max_acc'] = va - trlog['max_acc_epoch'] = epoch - save_model('max_acc') - - trlog['train_loss'].append(tl) - trlog['train_acc'].append(ta) - trlog['val_loss'].append(vl) - trlog['val_acc'].append(va) - - torch.save(trlog, osp.join(args.save_path, 'trlog')) - - save_model('epoch-last') - - print('ETA:{}/{}'.format(timer.measure(), timer.measure(epoch / args.max_epoch))) - writer.close() - - # Test Phase - trlog = torch.load(osp.join(args.save_path, 'trlog')) - test_set = Dataset('test', args) - sampler = CategoriesSampler(test_set.label, 10000, args.way, args.shot + args.query) - loader = DataLoader(test_set, batch_sampler=sampler, num_workers=8, pin_memory=True) - test_acc_record = np.zeros((10000,)) - - model.load_state_dict(torch.load(osp.join(args.save_path, 'max_acc' + '.pth'))['params']) - model.eval() - - ave_acc = Averager() - label = torch.arange(args.way).repeat(args.query) - if torch.cuda.is_available(): - label = label.type(torch.cuda.LongTensor) - else: - label = label.type(torch.LongTensor) - - with torch.no_grad(): - for i, batch in enumerate(loader, 1): - if torch.cuda.is_available(): - data, _ = [_.cuda() for _ in batch] - else: - data = batch[0] - k = args.way * args.shot - data_shot, data_query = data[:k], data[k:] - - logits = model(data_shot, data_query) - acc = count_acc(logits, label) - ave_acc.add(acc) - test_acc_record[i-1] = acc - print('batch {}: {:.2f}({:.2f})'.format(i, ave_acc.item() * 100, acc * 100)) - - m, pm = compute_confidence_interval(test_acc_record) - print('Val Best Acc {:.4f}, Test Acc {:.4f}'.format(trlog['max_acc'], ave_acc.item())) - print('Test Acc {:.4f} + {:.4f}'.format(m, pm)) \ No newline at end of file

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