lif31up commited on
Commit
1338dec
Β·
1 Parent(s): 552ac99
Files changed (2) hide show
  1. README.md +96 -64
  2. config.py +18 -0
README.md CHANGED
@@ -1,81 +1,113 @@
1
- ---
2
- datasets:
3
- - GATE-engine/omniglot
4
- language:
5
- - ko
6
- pipeline_tag: image-classification
7
- tags:
8
- - pytorch
9
- - few-shot-learning
10
- - one-shot-learning
11
- - meta-learning
12
- ---
13
- `torch` `torchvision` `tqdm`
14
 
15
- This implementation is inspired by **"Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks" (2017)**.
16
- * **task**: classifying image with few dataset.
17
- * **dataset**: downloaded from `torch` dataset library.
18
 
19
  ## Model-Agnostic Meta-Learning for Few-Shot Image Classification
20
- This repository implements a Model-Agnostic Meta-Learning (MAML) algorithm for few-shot image classification tasks using PyTorch. MAML is designed to address the challenge of adapting to new tasks with limited examples by learning an initialization that enables fast adaptation with minimal gradient steps.
21
 
22
- Few-shot learning focuses on enabling models to generalize to new tasks with only a few labeled examples. MAML achieves this by optimizing for a set of parameters that can quickly adapt to new tasks through gradient-based updates, allowing the model to efficiently learn from limited data.
 
23
 
24
- > You can access the full documentation here: [gitbook](https://lif31up.gitbook.io/lif31up/meta-learning/model-agnostic-meta-learning-for-fast-adaption-of-deep-networks)
25
 
26
- > You can access the test result on colab here: [colab](https://colab.research.google.com/drive/1ZmtP8rMZsSN_yA6tz3IKQU0ECXeAI018#scrollTo=iMjrWpR0FxHn)
 
27
 
28
- ## Instruction
29
- Organize your dataset into a structure compatible with PyTorch's ImageFolder:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  ```
31
- dataset/
32
- β”œβ”€β”€ class1/
33
- β”‚ β”œβ”€β”€ img1.jpg
34
- β”‚ β”œβ”€β”€ img2.jpg
35
- β”‚ └── ...
36
- β”œβ”€β”€ class2/
37
- β”‚ β”œβ”€β”€ img1.jpg
38
- β”‚ β”œβ”€β”€ img2.jpg
39
- β”‚ └── ...
40
- └── ...
41
- ```
42
-
43
  ### Training
44
- Run the training script with desired parameters:
45
- ```Shell
46
- python run.py train --dataset_path path/to/your/dataset --save_to /path/to/save/model --n_way 5 --k_shot 2 --n_query 4 --epochs 1 --iters 4
47
- ```
48
- * `path`: Path to your dataset.
49
- * `save_to`: path to save the trained model.
50
- * `n_way`: number of classes in each episode.
51
- * `k_shot`: Number of support samples per class.
52
- * `n-_query`: Number of query samples per class.
53
-
54
- > change training configuration from `config.py`
55
-
56
 
 
 
 
57
  ### Evaluation
58
- ```Shell
59
- python run.py --dataset path/to/your/dataset --model path/to/saved/model.pth --n_way 5
 
60
  # output example:
61
- # seen classes: [10, 11, 18, 1, 3]
62
- # unseen classes: [19, 1, 4, 2, 13]
63
- # accuracy: 1.0000(10/10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  ```
65
- * `model`: Path to your model.
66
- * `dataset`: Path to your dataset.
67
 
68
- ### Download Omniglot Dataset
69
- ```Shell
70
- pyhton download --path ./somewhre/your/dataset/
 
 
 
 
 
 
 
 
 
71
  ```
72
- * `path`: Path to your dataset.
73
 
74
- ---
75
- ### More Explanation
76
- **Model-Agnostic Meta-Learning(MAML)** is a powerful approach for few-shot learning, where the objective is to enable rapid adaptation to new tasks with very few labeled examples. The key idea behind MAML is to learn a model initialization that can be quickly fine-tuned on new tasks using only a small number of gradient updates, allowing efficient generalization to unseen data.
77
 
78
- * **Task-Specific Adaptation:** Instead of learning fixed representations, MAML optimizes model parameters that can be rapidly adapted to different tasks with gradient-based updates.
79
- * **Inner-Loop Optimization:** For each task, the model is fine-tuned on a small support set using a few gradient steps to minimize task-specific loss.
80
- * **Meta-Update (Outer Loop):** After task-specific updates, gradients are computed based on query set performance, and the initial model parameters are updated to improve adaptability across tasks.
81
- * **Optimization:** The model is trained using second-order gradient updates (or first-order approximations) to optimize for fast adaptation while maintaining generalization ability.
 
 
 
 
 
 
 
 
 
1
+ This implementation is inspired by [**"Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks"**](https://arxiv.org/abs/1703.05175) (2017) by Jake Snell, Kevin Swersky, Richard S. Zemel.
2
+ * **Note & Reference:** [GitBook](https://lif31up.gitbook.io/lif31up/few-shot-learning/model-agnostic-meta-learning-for-fast-adaptation-of-deep-networks)
3
+ * **Quickstart on Colab:** [Colab]()
 
 
 
 
 
 
 
 
 
 
4
 
5
+ | | 5 Way ACC (5 shot) | 5 Way ACC(1 shot) |
6
+ |------------|--------------------|------------------|
7
+ |**Omniglot**|`100%` **(100/100)**|`96%` **(96/100)**|
8
 
9
  ## Model-Agnostic Meta-Learning for Few-Shot Image Classification
10
+ This repository implements a Model-Agnostic Meta-Learning (MAML) algorithm for few-shot image classification tasks using PyTorch.
11
 
12
+ * **Task**: classifying image with few dataset.
13
+ * **Dataset**: `omniglot futurama`
14
 
15
+ Few-shot learning focuses on enabling models to generalize to new tasks with only a few labeled examples. MAML achieves this by optimizing for a set of parameters that can quickly adapt to new tasks through gradient-based updates, allowing the model to efficiently learn from limited data.
16
 
17
+ * **Inner-Loop Fast Adaption:** For each task, the model is fine-tuned on a small support set using a few gradient steps to minimize task-specific loss.
18
+ * **Meta-Update (Outer Loop):** After task-specific updates, gradients are computed based on query set performance, and the initial model parameters are updated to improve adaptability across tasks.
19
 
20
+ ---
21
+ ### Configuration
22
+ confing.py contains the configuration settings for the model, including the framework, dimensions, learning rate, and other hyperparameters
23
+ ```python
24
+ CONFIG = {
25
+ "version": "1.0.1",
26
+ # framework
27
+ "n_way": 5,
28
+ "k_shot": 1,
29
+ "n_query": 2,
30
+ # model
31
+ "inpt_dim": 3,
32
+ "hidn_dim": 6,
33
+ "oupt_dim": 5,
34
+ # hp
35
+ "iters": 5,
36
+ "epochs": 10,
37
+ "batch_size": 8,
38
+ "inner_batch_size": 5,
39
+ "alpha": 1e-2,
40
+ "beta": 1e-4,
41
+ } # CONFIG
42
  ```
 
 
 
 
 
 
 
 
 
 
 
 
43
  ### Training
44
+ train.py is a script to train the model on the omniglot dataset. It includes the training loop, evaluation, and saving the model checkpoints.
45
+ ```python
46
+ if __name__ == "__main__":
47
+ from config import CONFIG
 
 
 
 
 
 
 
 
48
 
49
+ train(DATASET="../data/omniglot-py/images_background/Futurama", SAVE_TO="./model/5w1s", config=CONFIG)
50
+ # if __name__ == "__main__":
51
+ ```
52
  ### Evaluation
53
+ eval.py is used to evaluate the trained model on the omniglot dataset. It loads the model and tokenizer, processes the dataset, and computes the accuracy of the model.
54
+ ```python
55
+ if __name__ == "__main__": evaluate("./model/5w1s.pth", "../data/omniglot-py/images_background/Futurama")
56
  # output example:
57
+ # seen classes: [1, 15, 6, 20, 12]
58
+ # unseen classes: [22, 3, 16, 20, 18]
59
+ # accuracy: 0.9000(9/10)
60
+ ```
61
+ ---
62
+ ## Technical Highlights
63
+ Although MAML is one of the most prominent few-shot learning algorithms, it's mathematically complex even compared to other modern deep learning approaches. Both the learning and evaluation processes consist of two stages.
64
+
65
+ ### Inner Loop
66
+ The inner loop is the first stage of MAML's algorithm where task-specific adaptations occur. It involves taking a small number of examples (support set) from a new task and creating parameters for each task. It then performs gradient updates to quickly adapt the model parameters for that specific task.
67
+
68
+ ```python
69
+ def inner_update(self, task):
70
+ local_params = {name: param.clone() for name, param in self.named_parameters()}
71
+ for _ in range(self.epochs):
72
+ for feature, label in DataLoader(task, batch_size=self.batch_size, shuffle=True, num_workers=4, pin_memory=True):
73
+ feature, label = feature.to(self.device, non_blocking=True), label.to(self.device, non_blocking=True)
74
+ pred = self.forward(feature, local_params)
75
+ loss = nn.MSELoss()(pred, label)
76
+ grads = torch.autograd.grad(loss, list(local_params.values()), create_graph=True)
77
+ local_params = {name: param - (self.alpha * grad) for (name, param), grad in zip(local_params.items(), grads)}
78
+ # for for
79
+ return local_params
80
+ # inner_update()
81
  ```
82
+ ### Outer Loop
83
+ The outer-loop is the second stage of MAML's algorithm where meta-learning occurs. It optimizes the initial model parameters to ensure they can be quickly adapted to new tasks with minimal data. This stage uses performance on the query set to update the model's starting point.
84
 
85
+ ```python
86
+ tasks, query_set = episoder.get_episode()
87
+ local_params = list()
88
+ for task in tasks: local_params.append(maml.inner_update(task))
89
+ for feature, label in DataLoader(query_set, batch_size=CONFIG["batch_size"], shuffle=True, pin_memory=True, num_workers=4):
90
+ feature, label = feature.to(device, non_blocking=True), label.to(device, non_blocking=True)
91
+ for local_param in local_params:
92
+ pred = maml.forward(feature, local_param)
93
+ print(f"pred shape: {pred.shape} feature shape: {feature.shape} label shape: {label.shape}")
94
+ # for
95
+ break
96
+ # for
97
  ```
 
98
 
99
+ ### Forward
100
+ The forward process in MAML differs significantly from other deep neural networks. First, it adapts to tasks from the query set. Then, it forwards each parameter per task and calculates probabilities.
 
101
 
102
+ ```python
103
+ def forward(self, x, params=None):
104
+ if not params: params = dict(self.named_parameters())
105
+ x = F.conv2d(x, params['conv1.weight'], bias=params['conv1.bias'], stride=1, padding=1)
106
+ x = self.swish(x)
107
+ x = F.conv2d(x, params['conv2.weight'], bias=params['conv2.bias'], stride=1, padding=1)
108
+ x = self.pool(x)
109
+ x = self.flatten(x)
110
+ x = F.linear(x, weight=params['l1.weight'], bias=params['l1.bias'])
111
+ return self.softmax(x)
112
+ # forward()
113
+ ```
config.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CONFIG = {
2
+ "version": "1.0.1",
3
+ # framework
4
+ "n_way": 5,
5
+ "k_shot": 1,
6
+ "n_query": 2,
7
+ # model
8
+ "inpt_dim": 3,
9
+ "hidn_dim": 6,
10
+ "oupt_dim": 5,
11
+ # hp
12
+ "iters": 5,
13
+ "epochs": 10,
14
+ "batch_size": 8,
15
+ "inner_batch_size": 5,
16
+ "alpha": 1e-2,
17
+ "beta": 1e-4,
18
+ } # CONFIG