Skip to content

Commit 6e27907

Browse files
authored
Release v0.2.2 => v1.0.0
* Rename AbstractMetaLearner to FewShotClassifier * Remove episodic training logic from few-shot classifiers * Make FewShotClassifier support backbones on CUDA at initialization * Add 4 new methods: Finetune, Transductive Finetuning, TIM and BD-CSPN * Add SOTA ResNets for Few-Shot Learning * Make modules parameterizable in Relation Networks and Matching Networks * Add abstract class FewShotDataset for all few-shot datasets * Make transforms parameterizable in EasySet * Add format restrictions in EasySet * Add TieredImageNet and CUB constructors using EasySet * Add Danish Fungi dataset * Add MiniImageNet * Add notebooks for episodic training and classical training * Add Python 3.9 support
2 parents 13221f9 + baabd9f commit 6e27907

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+62741
-732
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.2.2
2+
current_version = 1.0.0
33
commit = True
44
tag = False
55

.circleci/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ workflows:
7979
- install:
8080
matrix:
8181
parameters:
82-
python-version: ["3.6.13", "3.7.10", "3.8.8"]
82+
python-version: ["3.6.13", "3.7.10", "3.8.8", "3.9.11"]
8383
- lint:
8484
requires:
8585
- install
8686
- test:
8787
matrix:
8888
parameters:
89-
python-version: ["3.6.13", "3.7.10", "3.8.8"]
89+
python-version: ["3.6.13", "3.7.10", "3.8.8", "3.9.11"]
9090
requires:
9191
- install

.pylintrc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ suggestion-mode=yes
3838
# active Python interpreter and may run arbitrary code.
3939
unsafe-load-any-extension=no
4040

41+
# As a temporary workaround for https://github.com/PyCQA/pylint/issues/4577
42+
init-hook = "import astroid; astroid.context.InferenceContext.max_inferred = 500"
43+
4144

4245
[MESSAGES CONTROL]
4346

@@ -380,7 +383,7 @@ logging-modules=logging
380383
[DESIGN]
381384

382385
# Maximum number of arguments for function / method
383-
max-args=8
386+
max-args=10
384387

385388
# Maximum number of attributes for a class (see R0902).
386389
max-attributes=10
@@ -472,4 +475,4 @@ known-third-party=enchant
472475

473476
# Exceptions that will emit a warning when being caught. Defaults to
474477
# "Exception"
475-
overgeneral-exceptions=Exception
478+
overgeneral-exceptions=Exception

README.md

Lines changed: 93 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# Easy Few-Shot Learning
2-
![Python Versions](https://img.shields.io/badge/python-3.6%20|%203.7%20|%203.8-%23EBBD68.svg)
2+
![Python Versions](https://img.shields.io/pypi/pyversions/easyfsl?style=flat)
33
![CircleCI](https://img.shields.io/circleci/build/github/sicara/easy-few-shot-learning)
44
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)
55
![License: MIT](https://img.shields.io/badge/license-MIT-green)
6-
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/sicara/easy-few-shot-learning/blob/master/notebooks/my_first_few_shot_classifier.ipynb)
76

87
Ready-to-use code and tutorial notebooks to boost your way into few-shot image classification.
98
This repository is made for you if:
@@ -18,130 +17,131 @@ of code to be covered by a tutorial.
1817
### Notebooks: learn and practice
1918
You want to learn few-shot learning and don't know where to start? Start with our tutorial.
2019

21-
- **[First steps into few-shot image classification](notebooks/my_first_few_shot_classifier.ipynb)**
22-
20+
- **[First steps into few-shot image classification](notebooks/my_first_few_shot_classifier.ipynb)**:
21+
basically Few-Shot Learning 101, in less than 15mn.
22+
2323
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/sicara/easy-few-shot-learning/blob/master/notebooks/my_first_few_shot_classifier.ipynb)
2424

25+
- **[Example of episodic training](notebooks/episodic_training.ipynb)**:
26+
use it as a starting point if you want to design a script for episodic training using EasyFSL.
27+
28+
- **[Example of classical training](notebooks/episodic_training.ipynb)**:
29+
use it as a starting point if you want to design a script for classical training using EasyFSL.
30+
2531
### Code that you can use and understand
2632

27-
**Models:**
33+
**State-Of-The-Art Few-Shot Learning methods:**
2834

29-
- [AbstractMetaLearner](easyfsl/methods/abstract_meta_learner.py): an abstract class with methods that can be used for
30-
any meta-trainable algorithm
35+
- [FewShotClassifier](easyfsl/methods/few_shot_classifier.py): an abstract class with methods that can be used for
36+
any few-shot classification algorithm
3137
- [Prototypical Networks](easyfsl/methods/prototypical_networks.py)
3238
- [Matching Networks](easyfsl/methods/matching_networks.py)
3339
- [Relation Networks](easyfsl/methods/relation_networks.py)
40+
- [Fine-Tune](easyfsl/methods/finetune.py)
41+
- [BD-CSPN](easyfsl/methods/bd_cspn.py)
42+
- [Transductive Fine-Tuning](easyfsl/methods/transductive_finetuning.py)
43+
- [Transductive Information Maximization](easyfsl/methods/tim.py)
44+
45+
To reproduce their results, you can use the [standard network architectures](easyfsl/modules/predesigned_modules.py)
46+
used in Few-Shot Learning research. They're also a feature of EasyFSL!
3447

3548
**Tools for data loading:**
3649

37-
- [EasySet](easyfsl/data_tools/easy_set.py): a ready-to-use Dataset object to handle datasets of images with a class-wise directory split
38-
- [TaskSampler](easyfsl/data_tools/task_sampler.py): samples batches in the shape of few-shot classification tasks
50+
Data loading in FSL is a bit different from standard classification because we sample batches of
51+
instances in the shape of few-shot classification tasks. No sweat! In EasyFSL you have:
52+
53+
- [TaskSampler](easyfsl/samplers/task_sampler.py): an extension of the standard PyTorch Sampler object, to sample batches in the shape of few-shot classification tasks
54+
- [FewShotDataset](easyfsl/datasets/few_shot_dataset.py): an abstract class to standardize the interface of any dataset you'd like to use
55+
- [EasySet](easyfsl/datasets/easy_set.py): a ready-to-use FewShotDataset object to handle datasets of images with a class-wise directory split
56+
57+
**And also:** [some utilities](easyfsl/utils.py) that I felt I often used in my research, so I'm sharing with you.
3958

4059
### Datasets to test your model
4160

42-
- [CU-Birds](http://www.vision.caltech.edu/visipedia/CUB-200.html): we provide [a script](scripts/download_CUB.sh) to download
43-
and extract the dataset, along with [(train / val / test) split](data/CUB) along classes. The dataset is
44-
ready-to-use with [EasySet](easyfsl/data_tools/easy_set.py).
45-
- [tieredImageNet](https://paperswithcode.com/dataset/tieredimagenet): we provide the
46-
[train, val and test specification files](data/tiered_imagenet) to be used by [EasySet](easyfsl/data_tools/easy_set.py).
47-
To use it, you need the [ILSVRC2015](https://image-net.org/challenges/LSVRC/index.php) dataset. Once you have
48-
downloaded and extracted the dataset, ensure that its localisation on disk is consistent with the class paths
49-
specified in the specification files.
61+
There are enough datasets used in Few-Shot Learning for anyone to get lost in them. They're all here,
62+
explicited, downloadable and easy-to-use, in EasyFSL.
5063

51-
## QuickStart
52-
1. Install the package with pip:
53-
54-
```pip install easyfsl```
64+
**[CU-Birds](http://www.vision.caltech.edu/visipedia/CUB-200.html)**
5565

56-
Note: alternatively, you can clone the repository so that you can modify the code as you wish.
57-
58-
2. Download [CU-Birds](http://www.vision.caltech.edu/visipedia/CUB-200.html) and the few-shot train/val/test split:
66+
We provide [a script](scripts/download_CUB.sh) to download and extract the dataset,
67+
along with the standard [(train / val / test) split](data/CUB) along classes.
68+
Once you've downloaded the dataset, you can instantiate the Dataset objects in your code
69+
with this super complicated process:
5970

71+
```python
72+
from easyfsl.datasets import CUB
73+
74+
train_set = CUB(split="train", training=True)
75+
test_set = CUB(split="test", training=False)
6076
```
61-
mkdir -p data/CUB && cd data/CUB
62-
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1GDr1OkoXdhaXWGA8S3MAq3a522Tak-nx' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1GDr1OkoXdhaXWGA8S3MAq3a522Tak-nx" -O images.tgz
63-
rm -rf /tmp/cookies.txt
64-
tar --exclude='._*' -zxvf images.tgz
65-
wget https://raw.githubusercontent.com/sicara/easy-few-shot-learning/master/data/CUB/train.json
66-
wget https://raw.githubusercontent.com/sicara/easy-few-shot-learning/master/data/CUB/val.json
67-
wget https://raw.githubusercontent.com/sicara/easy-few-shot-learning/master/data/CUB/test.json
68-
cd ...
69-
```
70-
71-
3. Check that you have a 680,9MB `images` folder in `./data/CUB` along with three JSON files.
7277

73-
4. From the training subset of CUB, create a dataloader that yields few-shot classification tasks:
78+
**[tieredImageNet](https://paperswithcode.com/dataset/tieredimagenet)**
79+
80+
To use it, you need the [ILSVRC2015](https://image-net.org/challenges/LSVRC/index.php) dataset. Once you have
81+
downloaded and extracted the dataset, ensure that its localisation on disk is consistent with the class paths
82+
specified in the [specification files](data/tiered_imagenet). Then:
83+
7484
```python
75-
from easyfsl.data_tools import EasySet, TaskSampler
76-
from torch.utils.data import DataLoader
77-
78-
train_set = EasySet(specs_file="./data/CUB/train.json", training=True)
79-
train_sampler = TaskSampler(
80-
train_set, n_way=5, n_shot=5, n_query=10, n_tasks=40000
81-
)
82-
train_loader = DataLoader(
83-
train_set,
84-
batch_sampler=train_sampler,
85-
num_workers=12,
86-
pin_memory=True,
87-
collate_fn=train_sampler.episodic_collate_fn,
88-
)
85+
from easyfsl.datasets import TieredImageNet
86+
87+
train_set = TieredImageNet(split="train", training=True)
88+
test_set = TieredImageNet(split="test", training=False)
8989
```
9090

91-
5. Create and train a model
91+
**[miniImageNet](https://paperswithcode.com/dataset/miniimagenet)**
92+
93+
Same as tieredImageNet, we provide the [specification files](data/mini_imagenet),
94+
but you need the [ILSVRC2015](https://image-net.org/challenges/LSVRC/index.php) dataset.
95+
Once you have it:
9296

9397
```python
94-
from easyfsl.methods import PrototypicalNetworks
95-
from torch import nn
96-
from torch.optim import Adam
97-
from torchvision.models import resnet18
98+
from easyfsl.datasets import MiniImageNet
99+
100+
train_set = MiniImageNet(root="where/imagenet/is", split="train", training=True)
101+
test_set = MiniImageNet(root="where/imagenet/is", split="test", training=False)
102+
```
98103

99-
convolutional_network = resnet18(pretrained=False)
100-
convolutional_network.fc = nn.Flatten()
101-
model = PrototypicalNetworks(convolutional_network).cuda()
104+
Since miniImageNet is relatively small, you can also load it on RAM directly at instantiation simply by
105+
adding `load_on_ram=True` to the constructor.
106+
It takes a few minutes but it can make your training significantly faster!
102107

103-
optimizer = Adam(params=model.parameters())
108+
**[Danish Fungi](https://paperswithcode.com/paper/danish-fungi-2020-not-just-another-image)**
104109

105-
model.fit(train_loader, optimizer)
106-
```
107-
**Note:** you can also define a validation data loader and use as an additional argument to `fit`
108-
in order to use validation during your training.
110+
I've recently started using it as a Few-Shot Learning benchmarks, and I can tell you it's a great
111+
playing field. To use it, first download the data:
109112

110-
**Troubleshooting:** a ResNet18 with a batch size of (5 * (5+10)) = 75 would use about 4.2GB on your GPU.
111-
If you don't have it, switch to CPU, choose a smaller model or reduce the batch size (in `TaskSampler` above).
113+
```shell
114+
# Download the original dataset (/!\ 110GB)
115+
wget http://ptak.felk.cvut.cz/plants/DanishFungiDataset/DF20-train_val.tar.gz
116+
# Or alternatively the images reduced to 300px (6.5Gb)
117+
wget http://ptak.felk.cvut.cz/plants/DanishFungiDataset/DF20-300px.tar.gz
118+
# And finally download the metadata (83Mb) to data/fungi/
119+
wget https://public-sicara.s3.eu-central-1.amazonaws.com/easy-fsl/DF20_metadata.csv -O data/fungi/DF20_metadata.csv
120+
```
112121

113-
6. Evaluate your model on the test set
122+
And then instantiate the dataset with the same process as always:
114123

115124
```python
116-
test_set = EasySet(specs_file="./data/CUB/test.json", training=False)
117-
test_sampler = TaskSampler(
118-
test_set, n_way=5, n_shot=5, n_query=10, n_tasks=100
119-
)
120-
test_loader = DataLoader(
121-
test_set,
122-
batch_sampler=test_sampler,
123-
num_workers=12,
124-
pin_memory=True,
125-
collate_fn=test_sampler.episodic_collate_fn,
126-
)
127-
128-
accuracy = model.evaluate(test_loader)
129-
print(f"Average accuracy : {(100 * accuracy):.2f}")
125+
from easyfsl.datasets import DanishFungi
126+
127+
dataset = DanishFungi(root="where/fungi/is")
130128
```
131129

132-
## Roadmap
133-
134-
- [ ] Integrate more methods:
135-
- [X] Matching Networks
136-
- [X] Relation Networks
137-
- [ ] MAML
138-
- [ ] Transductive Propagation Network
139-
- [ ] TADAM
140-
- [ ] Integrate non-episodic training
141-
- [ ] Integrate more benchmarks:
142-
- [X] tieredImageNet
143-
- [ ] miniImageNet
144-
- [ ] Meta-Dataset
130+
Note that I didn't specify a train and test set because the CSV I gave you describes the whole dataset.
131+
I recommend to use it to test models with weights trained on an other dataset (like ImageNet).
132+
But if you want to propose a train/val/test split along classes, you're welcome to contribute!
133+
134+
## QuickStart
135+
136+
137+
1. Install the package: ```pip install easyfsl``` \
138+
Note: alternatively, you can clone the repository so that you can modify the code as you wish.
139+
140+
2. [Download your data](#datasets-to-test-your-model).
141+
142+
3. Design your training and evaluation scripts. You can use our example notebooks for
143+
[episodic training](notebooks/episodic_training.ipynb)
144+
or [classical training](notebooks/classical_training.ipynb)
145145

146146
## Contribute
147147
This project is very open to contributions! You can help in various ways:

data/fungi/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
DF20_metadata.csv
2+
3+
images/

0 commit comments

Comments
 (0)