Giter VIP home page Giter VIP logo

learn2learn's Introduction


Test Status arXiv

learn2learn is a software library for meta-learning research.

learn2learn builds on top of PyTorch to accelerate two aspects of the meta-learning research cycle:

  • fast prototyping, essential in letting researchers quickly try new ideas, and
  • correct reproducibility, ensuring that these ideas are evaluated fairly.

learn2learn provides low-level utilities and unified interface to create new algorithms and domains, together with high-quality implementations of existing algorithms and standardized benchmarks. It retains compatibility with torchvision, torchaudio, torchtext, cherry, and any other PyTorch-based library you might be using.

To learn more, see our whitepaper: arXiv:2008.12284

Overview

  • learn2learn.data: Taskset and transforms to create few-shot tasks from any PyTorch dataset.
  • learn2learn.vision: Models, datasets, and benchmarks for computer vision and few-shot learning.
  • learn2learn.gym: Environment and utilities for meta-reinforcement learning.
  • learn2learn.algorithms: High-level wrappers for existing meta-learning algorithms.
  • learn2learn.optim: Utilities and algorithms for differentiable optimization and meta-descent.

Resources

Installation

pip install learn2learn

Snippets & Examples

The following snippets provide a sneak peek at the functionalities of learn2learn.

High-level Wrappers

Few-Shot Learning with MAML

For more algorithms (ProtoNets, ANIL, Meta-SGD, Reptile, Meta-Curvature, KFO) refer to the examples folder. Most of them can be implemented with with the GBML wrapper. (documentation).

maml = l2l.algorithms.MAML(model, lr=0.1)
opt = torch.optim.SGD(maml.parameters(), lr=0.001)
for iteration in range(10):
    opt.zero_grad()
    task_model = maml.clone()  # torch.clone() for nn.Modules
    adaptation_loss = compute_loss(task_model)
    task_model.adapt(adaptation_loss)  # computes gradient, update task_model in-place
    evaluation_loss = compute_loss(task_model)
    evaluation_loss.backward()  # gradients w.r.t. maml.parameters()
    opt.step()
Meta-Descent with Hypergradient

Learn any kind of optimization algorithm with the LearnableOptimizer. (example and documentation)

linear = nn.Linear(784, 10)
transform = l2l.optim.ModuleTransform(l2l.nn.Scale)
metaopt = l2l.optim.LearnableOptimizer(linear, transform, lr=0.01)  # metaopt has .step()
opt = torch.optim.SGD(metaopt.parameters(), lr=0.001)  # metaopt also has .parameters()

metaopt.zero_grad()
opt.zero_grad()
error = loss(linear(X), y)
error.backward()
opt.step()  # update metaopt
metaopt.step()  # update linear

Learning Domains

Custom Few-Shot Dataset

Many standardized datasets (Omniglot, mini-/tiered-ImageNet, FC100, CIFAR-FS) are readily available in learn2learn.vision.datasets. (documentation)

dataset = l2l.data.MetaDataset(MyDataset())  # any PyTorch dataset
transforms = [  # Easy to define your own transform
    l2l.data.transforms.NWays(dataset, n=5),
    l2l.data.transforms.KShots(dataset, k=1),
    l2l.data.transforms.LoadData(dataset),
]
taskset = Taskset(dataset, transforms, num_tasks=20000)
for task in taskset:
    X, y = task
    # Meta-train on the task
Environments and Utilities for Meta-RL

Parallelize your own meta-environments with AsyncVectorEnv, or use the standardized ones. (documentation)

def make_env():
    env = l2l.gym.HalfCheetahForwardBackwardEnv()
    env = cherry.envs.ActionSpaceScaler(env)
    return env

env = l2l.gym.AsyncVectorEnv([make_env for _ in range(16)])  # uses 16 threads
for task_config in env.sample_tasks(20):
    env.set_task(task)  # all threads receive the same task
    state = env.reset()  # use standard Gym API
    action = my_policy(env)
    env.step(action)

Low-Level Utilities

Differentiable Optimization

Learn and differentiate through updates of PyTorch Modules. (documentation)

model = MyModel()
transform = l2l.optim.KroneckerTransform(l2l.nn.KroneckerLinear)
learned_update = l2l.optim.ParameterUpdate(  # learnable update function
        model.parameters(), transform)
clone = l2l.clone_module(model)  # torch.clone() for nn.Modules
error = loss(clone(X), y)
updates = learned_update(  # similar API as torch.autograd.grad
    error,
    clone.parameters(),
    create_graph=True,
)
l2l.update_module(clone, updates=updates)
loss(clone(X), y).backward()  # Gradients w.r.t model.parameters() and learned_update.parameters()

Changelog

A human-readable changelog is available in the CHANGELOG.md file.

Citation

To cite the learn2learn repository in your academic publications, please use the following reference.

Arnold, Sebastien M. R., Praateek Mahajan, Debajyoti Datta, Ian Bunner, and Konstantinos Saitas Zarkias. 2020. “learn2learn: A Library for Meta-Learning Research.” arXiv [cs.LG]. http://arxiv.org/abs/2008.12284.

You can also use the following Bibtex entry.

@article{Arnold2020-ss,
  title         = "learn2learn: A Library for {Meta-Learning} Research",
  author        = "Arnold, S{\'e}bastien M R and Mahajan, Praateek and Datta,
                   Debajyoti and Bunner, Ian and Zarkias, Konstantinos Saitas",
  month         =  aug,
  year          =  2020,
  url           = "http://arxiv.org/abs/2008.12284",
  archivePrefix = "arXiv",
  primaryClass  = "cs.LG",
  eprint        = "2008.12284"
}

Acknowledgements & Friends

  1. TorchMeta is similar library, with a focus on datasets for supervised meta-learning.
  2. higher is a PyTorch library that enables differentiating through optimization inner-loops. While they monkey-patch nn.Module to be stateless, learn2learn retains the stateful PyTorch look-and-feel. For more information, refer to their ArXiv paper.
  3. We are thankful to the following open-source implementations which helped guide the design of learn2learn:

learn2learn's People

Contributors

8bitmp3 avatar debajyotidatta avatar dependabot[bot] avatar dubiouscactus avatar ethanwharris avatar ewinapun avatar farzam-khodajoo avatar ian-bunner avatar isakfalk avatar janbolle avatar joeljosephjin avatar joemzhao avatar jorgectf avatar kostis-s-z avatar krikunovev avatar kristian-georgiev avatar kzhang2 avatar mayug avatar mi92 avatar nightlessbaron avatar nsanghi avatar praateekmahajan avatar seba-1511 avatar shielian avatar sliverysky avatar steremma avatar timweiland avatar trellixvulnteam avatar vfdev-5 avatar zhaofengwu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

learn2learn's Issues

Runs out of memory if num_tasks not mentioned.

Since this generates all possible tasks and making this into a list and not through an iterator means it will run out of memory.


MemoryError                               Traceback (most recent call last)
<ipython-input-2-497a9350dcca> in <module>
    292     loss_fn = torch.nn.NLLLoss().cuda()
    293 
--> 294     eval_generator = l2l.data.TaskGenerator(dataset=omniglot, ways=args.k_test)
    295     support_t = eval_generator.sample(shots=args.q_test)
    296     query_t = eval_generator.sample(shots=args.q_test)

/data/home/debo/l2l/learn2learn/learn2learn/data/task_generator.py in __init__(self, dataset, ways, shots, classes, tasks)
    147 
    148         if tasks is None:
--> 149             self.tasks = list(permutations(self.classes, self.ways))
    150         elif isinstance(tasks, int):
    151             self.tasks = self.generate_n_tasks(tasks)

MemoryError: 

Add a way to create new classes from image rotations

Currently, l2l.vision.transforms.RandomRotation generates additional image rotations within the same dataset. The actual functionality (following the MAML repo) is that each rotation corresponds to its own class. This means that an Omniglot task could in theory consist of labels: [A, rot(A, 90), rot(A, 180), rot(A, 270), B], where rot(A, x) is the character A rotated by x degrees.

Add Omniglot to README

Omniglot is an important and widely used benchmark, so we should highlight l2l's superb performance on it in the README. We have both video and graphic evidence that would look good in the README.

MAML with RL

Hi,
In your given rl+maml example, we always update the maml loss by using a2c.policyloss, even in the maml+ppo? I'm confused about it. Could you explain the reasons?
Meanwhile, in the meta rl examples, we only update the policy loss rather than value loss. I wonder do we also need to update the value loss(i.e. state loss) as well?

Thanks for your time.

Is testing necessary in every epoch (MAML vision examples)?

I might be misunderstanding something completely but, in the MAML vision examples (maml_miniimagenet & maml_omniglot) the normal train/val/test split takes place but testing also happens in every epoch during training. Why is that? Isn't this the purpose of the validation set? Shouldn't testing be left just for after the training? Also, testing at every epoch slows down the training time.

Add MNIST or Omniglot to README

The current demonstration of how to use l2l in the README is for a RL example. This creates the false impression that l2l is a RL library. We should also include a supervised/deep-learning example (possibly side by side?) to make l2l more welcoming for those w/o an RL focus.

Add Test Cases for All Files

Since l2l is undergoing rapid growth, things are constantly changing and breaking. As we attempt to grow l2l into a mature, flagship library for meta-learning we need to create tests that guarantee that all code still works properly and that l2l continues to achieve state-of-the-art performance. This will greatly improve l2l's reliability, allowing other users to confidently incorporate l2l in their projects.

We need both granular and high-level test cases. All functions should be tested, as well as examples. Ideally, the tests for examples should ensure that l2l continues to perform incredibly well on all examples.

l2l.transforms.RandomRotation(degrees)

A vision transform that uniformly samples from iterable degrees the degress of rotation that will be applied to the image.

Example:

rotate = l2l.transforms.RandomRotation([0.0, 90.0, 180.0, 270.0])

Question: should it be in l2l.transforms or l2l.data.transforms or l2l.data.vision.transforms ?

l2l.detach_module(module)

We can inspire ourselves from l2l.clone_module, and replace the clone() calls with detach() calls.

Use booleans to avoid warnings

adaptation_indices = torch.zeros(data.size(0)).byte()
adaptation_indices[torch.arange(shots*ways) * 2] = 1
adaptation_data, adaptation_labels = data[adaptation_indices], labels[adaptation_indices]
evaluation_data, evaluation_labels = data[1 - adaptation_indices], labels[1 - adaptation_indices]

Change to:

adaptation_indices = torch.zeros(data.size(0)).bool()
adaptation_indices[torch.arange(shots*ways) * 2] = True
adaptation_data, adaptation_labels = data[adaptation_indices], labels[adaptation_indices]
evaluation_data, evaluation_labels = data[~adaptation_indices], `labels[~adaptation_indices]

Definition of common models

We would like to have definitions for models commonly used for Omniglot and MiniImageNet. Here's a preliminary list:

  • l2l.models.OmniglotFC -- the FC model from the MAML paper.
  • l2l.models.OmniglotCNN -- the CNN model from the Matching Nets (with MAML modifications)
  • l2l.models.MiniImageNetCNN -- the CNN model from Meta-LSTM.

Add reference to pytorch-meta

pytorch-meta is a similar project, whose creators have been gracious consultants. While we would love for everyone to use l2l, if for some reason l2l is not the perfect fit for a user, pytorch-meta is an excellent alternative that we hope suits their needs.

Add FullOmniglot Dataset

Add FullOmniglot dataset in l2l.data.vision.full_omniglot.py. Instanciating the class should be equivalent to (and support the usual options, such as transforms, download=True, etc...)

    omni_background = Omniglot(root='./data', background=True)
    max_y = 964
    omni_evaluation = Omniglot(root='./data', background=False,
                               target_transform=transforms.Compose([
                                   lambda x: max_y + x,
                               ]))
    full_omniglot = ConcatDataset((omni_background, omni_evaluation))

Non deterministic behaviour

I tried setting random seed initially, but get different accs within same number of steps.

To ensure reproducibility we should be sure that given the same seeds our models/modules perform the same way.

Here is a good link describing pytorch and seeds in detail.

FYI : I was on CPU so I believe the only seeds that I needed to set were

torch.manual_seed(0)
random.seed(0)

Add l2l.ConcatDataset for MetaDataset

MetaDataset seems to be rather important for now.

We can create a function that can concat all our datasets.

ConcatDataset(MNIST, MiniImagenet, FullOmniglot .....)

Add Accuracy Achieved for Examples

  • add the accuracy achieved for all examples in the README (maybe create a section called Performance)
  • next to each accuracy post the reported accuracy achieved on the task in the paper the example was pulled from
  • the purpose is to show that l2l is a state-of-the-art library, so if l2l performs worse than the literature make an issue for that example and we will look at it

Why is recursion required in maml_update and clone_module

I am a bit confused in the implementation of maml_update and clone_module function. In maml_update first the gradient update is done for all parameters of model. Doesn't this mean that all submodules are also updated because model.parameters will return all parameters? What is need of recursively again applying gradient update on submodules? I might be thinking in wrong direction hence would be very helpful if you can make this a bit more clear to me.

Best regards,
Shivam Saboo

Better TaskGenerator splitting options

Splitting a dataset into multiple task generators is weird currently. (The interaction between split, test_size, and test_classes is not very clear.) I think a nicer API would be the following.

dataset = datasets.MNIST(download=True)
train_classes = [1, 2, 3, 9]
valid_classes = [0, 4, 5]
test_classes = [6, 7, 8]
train_generator = l2l.data.TaskGenerator(dataset, ways=2, classes=train_classes)
valid_generator = l2l.data.TaskGenerator(dataset, ways=2, classes=valid_classes)
test_generator = l2l.data.TaskGenerator(dataset, ways=2, classes=test_classes)

Swap MKDocs for Sphinx

It's been suggested we move the docs to Sphinx. Though not an immediate priority, the documentation will be our users introduction to the repository so we should either clean up the styling we currently have or consider migration. If you have any thoughts, please post as a comment to this issue.

Allow MetaDataset to take in label_to_indices as argument

Some datasets (like MiniImagenet) have a dict already specified that maps their labels to the respective indices. If that's the case then wrapping using MetaDataset is a waste of computeee.

h2. Acceptance Criteria

MetaDataset(dataset, labels_to_indices : Optional[dict]=None)

setup of new cython modules does not work properly?

Great to see the addition of Cython modules in the building of datasets!

However, I seem to have a bit of a problem. When I try to execute maml_miniimagenet.py (or cifarfs.py or fc100.py or probably any other script that makes use of the data modules) without already having a copy of the datasets locally I get the following error.

Traceback (most recent call last):
  File ".../learn2learn/learn2learn/vision/datasets/cifarfs.py", line 11, in <module>
    from learn2learn.data.utils import download_file_from_google_drive
  File ".../learn2learn/learn2learn/__init__.py", line 4, in <module>
    from . import data
  File ".../learn2learn/learn2learn/data/__init__.py", line 3, in <module>
    from . import transforms
ImportError: cannot import name 'transforms'

I did run the setup.py again in order to build the modules, but it still didn't work (In fact, I made a new virtual env to try from scratch, but I still get that error). Any ideas?

TypeError probably due to some bug in RandomClassRotation

l2l.vision.transforms.RandomClassRotation(dataset, [0.0, 90.0, 180.0, 270.0])

After having instantiated the train_tasks TaskDataset try to do:

for t in train_tasks:
    pass

At a random t I get the following error:

  File "/Software/Python3/miniconda3/envs/torch-1.4/lib/python3.7/site-packages/PIL/Image.py", line 2544, in new
    return im._new(core.fill(mode, size, color))
TypeError: function takes exactly 1 argument (3 given)

Add final accuracies to examples

For protonets/maml on Omniglot/miniImageNet, we should include the final train/valid/test accuracies obtained after training and compare them to the numbers from the paper. (e.g. in examples/vision/README.md)

[Feature Request] Add metaworld support

Hi!
Thank you for learn2learn!

It would be great to have the support of Metaworld environments (it is pretty tricky right now and requires to change some source code). I'd be happy to help.

Make Mujoco Imports Optional

Several RL examples rely on MuJoCo; however, the successful importation of MuJoCo is dependent on the user having a MuJoCo license. Since this is not free (as in lunch) and not necessary for any other examples or core tools, we should make it so that the imports of MuJoCo are optional, allowing users to use the rest of l2l without issue.

Add l2l.splitDataset

That splits a l2l.metadataset. It'll be helpful to split a task generator to train and val, so that we can sample tasks using class generator from a set of data points that we haven't trained on.

Add Contribution and Ownership Information to README

l2l is a young library with great potential. To accelerate it's growth we need a strong community of users who are willing to positively contribute. With that in mind, we should create a section detailing how l2l users can contribute. Ideally this section would cover both the mechanics of contributing and what contributions we are most looking for.

Additionally, we should add a section listing the code owners.

cross domain example

hello,
how to train on mnist test on another dataset, that is cross domain, not testing on mnist dataset.

Add more tutorials

As suggested on Reddit, it would be nice to have more tutorials.

A simple idea is to base them on our existing examples. The tutorial could explain how each implemented method works and contrast it with other meta-learning methods. In doing so, it could also cover functionalities that learn2learn provides.

MAML Omniglot Example

Replicate the MAML results with the FC and CNN models in examples/vision/maml_omniglot.py.

Also, check that when swapping MAML for MetaSGD, we replicate results from the Meta-SGD paper.

issue with downloading data

Hey guys,

I keep getting the following errors when I run the maml_miniimagenet.py example. I did not change anything on the code do you have any idea why that might be the case.

Downloading: ./data/mini-imagenet-cache-train.pkl
Download finished
Traceback (most recent call last):
File "/home/michalislazarou/PhD/learn2learn/examples/vision/maml_miniimagenet.py", line 179, in
main()
File "/home/michalislazarou/PhD/learn2learn/examples/vision/maml_miniimagenet.py", line 66, in main
train_dataset = l2l.vision.datasets.MiniImagenet(root='./data', mode='train')
File "/home/michalislazarou/PhD/learn2learn/learn2learn/vision/datasets/mini_imagenet.py", line 94, in init
self.data = pickle.load(f)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa6 in position 35778727: invalid start byte

RuntimeError: One of the differentiated Tensors does not require grad

Hi there! I am building a neural network with MAML. Everything works fine until adapting the learner to the loss. Here is the code (slightly modified from the examples):

import random
import time

import numpy as np
import torch as th

from torch import nn
from torch import optim
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

from freezenet import FreezeNet
import learn2learn as l2l

writer = SummaryWriter('/info')

def accuracy(predictions, targets):
    predictions = predictions.argmax(dim=1).view(targets.shape)
    return (predictions == targets).sum().float() / targets.size(0)

def nll(z, log_det):
    return (th.mean(z**2) / 2 - th.mean(log_det) / 28*28) * 0.0005

def fast_adapt(adaptation_data, evaluation_data, learner, loss, adaptation_steps):
    for step in range(adaptation_steps):
        data = [d for d in adaptation_data]
        X = th.cat([d[0] for d in data], dim=0)
        X = X.view(X.shape[0], 1, X.shape[1], X.shape[2])
        y = th.cat([th.tensor(d[1]).view(-1) for d in data], dim=0).to(dtype=th.int64)
        y_pred, z, log_det = learner(X)
        train_error = loss(y_pred, y) + nll(z, log_det)
        train_error /= len(adaptation_data)
        learner.adapt(train_error)
    data = [d for d in evaluation_data]
    X = th.cat([d[0] for d in data], dim=0)
    X = X.view(X.shape[0], 1, X.shape[1], X.shape[2])
    y = th.cat([th.tensor(d[1]).view(-1) for d in data], dim=0).to(dtype=th.int64)
    y_pred, z, log_det = learner(X)
    valid_error = loss(y_pred, y) + nll(z, log_det)
    valid_error /= len(evaluation_data)
    valid_accuracy = accuracy(y_pred, y)
    return valid_error, valid_accuracy

def main(
        ways=5,
        shots=1,
        meta_lr=0.003,
        fast_lr=0.5,
        meta_batch_size=32,
        adaptation_steps=1,
        num_iterations=6000,
        cuda=True,
        seed=42,
):
    random.seed(seed)
    np.random.seed(seed)
    th.manual_seed(seed)

    omniglot = l2l.vision.datasets.FullOmniglot(root='./data',
                                                transform=transforms.Compose([
                                                    l2l.vision.transforms.RandomDiscreteRotation(
                                                        [0.0, 90.0, 180.0, 270.0]),
                                                    transforms.Resize(28),
                                                    transforms.ToTensor(),
                                                    lambda x: 1.0 - x,
                                                ]),
                                                download=True)
    omniglot = l2l.data.MetaDataset(omniglot)
    classes = list(range(1623))
    random.shuffle(classes)
    train_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                             ways=ways,
                                             classes=classes[:1100],
                                             tasks=20000)
    valid_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                             ways=ways,
                                             classes=classes[1100:1200],
                                             tasks=1024)
    test_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                            ways=ways,
                                            classes=classes[1200:],
                                            tasks=1024)

    # Create model
    model = FreezeNet((1, 28, 28), ways, num_steps=3)
    maml = l2l.algorithms.MAML(model, lr=fast_lr, first_order=True)
    opt = optim.Adam(maml.parameters(), meta_lr)
    loss = nn.CrossEntropyLoss(reduction='mean')

    start = time.time()
    for iteration in range(num_iterations):
        opt.zero_grad()
        meta_train_error = 0.0
        meta_train_accuracy = 0.0
        meta_valid_error = 0.0
        meta_valid_accuracy = 0.0
        meta_test_error = 0.0
        meta_test_accuracy = 0.0
        for task in range(meta_batch_size):
            # Compute meta-training loss
            learner = maml.clone()
            adaptation_data = train_generator.sample(shots=shots)
            evaluation_data = train_generator.sample(shots=shots,
                                                     task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps)
            evaluation_error.backward()
            meta_train_error += evaluation_error.item()
            meta_train_accuracy += evaluation_accuracy.item()

            # Compute meta-validation loss
            learner = maml.clone()
            adaptation_data = valid_generator.sample(shots=shots)
            evaluation_data = valid_generator.sample(shots=shots,
                                                     task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps)
            meta_valid_error += evaluation_error.item()
            meta_valid_accuracy += evaluation_accuracy.item()

            # Compute meta-testing loss
            learner = maml.clone()
            adaptation_data = test_generator.sample(shots=shots)
            evaluation_data = test_generator.sample(shots=shots,
                                                    task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps)
            meta_test_error += evaluation_error.item()
            meta_test_accuracy += evaluation_accuracy.item()

        # Print some metrics
        print('\n')
        print('Iteration', iteration)
        print('Meta Train Error', meta_train_error / meta_batch_size)
        print('Meta Train Accuracy', meta_train_accuracy / meta_batch_size)
        print('Meta Valid Error', meta_valid_error / meta_batch_size)
        print('Meta Valid Accuracy', meta_valid_accuracy / meta_batch_size)
        print('Meta Test Error', meta_test_error / meta_batch_size)
        print('Meta Test Accuracy', meta_test_accuracy / meta_batch_size)

        # Add information for evidence in project
        writer.add_scalar('Train Error', meta_train_error, iteration)
        writer.add_scalar('Validation Error', meta_valid_error, iteration)
        writer.add_scalar('Test Error', meta_test_error, iteration)

        writer.add_scalar('Train Accuracy', meta_train_accuracy, iteration)
        writer.add_scalar('Valid Accuracy', meta_valid_accuracy, iteration)
        writer.add_scalar('Test Accuracy', meta_test_accuracy, iteration)

        # Average the accumulated gradients and optimize
        for p in maml.parameters():
            p.grad.data.mul_(1.0 / meta_batch_size)
        opt.step()
    
    print('Total Training Time is {} seconds'.format(time.time() - start))
    writer.close()    
    th.save(learner.state_dict(), '/saved_model')

if __name__ == '__main__':
    main()

Here is the network:

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision.models.squeezenet import Fire
import FrEIA.framework as Ff
import FrEIA.modules as Fm

def subnet(in_channels, out_channels):
    return nn.Sequential(
        Fire(in_channels, 8, 16, 16),
        nn.BatchNorm2d(32),
        nn.ReLU(),
        Fire(32, 16, out_channels//2, out_channels//2),
    )


class FreezeNet(nn.Module):
    def __init__(self, shape, num_outputs, num_steps=3):
        super(FreezeNet, self).__init__()
        self.C, self.H, self.W = shape
        self.num_steps = num_steps
        self.model = self.build_model()
        self.final_conv = nn.Conv2d(2 * 2 * self.C, num_outputs, kernel_size=1)
        self.pool = nn.AvgPool2d(self.H // 2)

    def build_model(self):
        nodes = [Ff.InputNode(self.C, self.H, self.W, name='input')]
        nodes.append(Ff.Node(nodes[-1], Fm.HaarDownsampling, {}, name='Downsampling'))

        for i in range(self.num_steps):
            nodes.append(Ff.Node(nodes[-1], Fm.ActNorm, {}, name='actnorm_{}'.format(i)))
            nodes.append(Ff.Node(nodes[-1], Fm.PermuteRandom, {'seed':i}, name='permute_{}'.format(i)))
            nodes.append(Ff.Node(nodes[-1], Fm.GLOWCouplingBlock,
            {'subnet_constructor': subnet, 'clamp':1.2}, name='coupling_{}'.format(i)))

        nodes.append(Ff.OutputNode(nodes[-1], name='output_node'))
        return Ff.ReversibleGraphNet(nodes, verbose=False)

    def forward(self, x):
        z = self.model(x)
        y = F.relu(self.final_conv(z))
        y = F.sigmoid(self.pool(y))
        y = y.view(y.shape[0], -1)
        log_det = self.model.log_jacobian(run_forward=False)
        return y, z, log_det

AttributeError: 'NoneType' object has no attribute '_parameters'

Hi there!
I am training a classifier with meta learning, Everything works fine, except when instantiating a clone of the model. Here is the code (slightly modified from the examples):

import random

import numpy as np
import torch as th

from torch import nn
from torch import optim
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

from freezenet import FreezeNet
import learn2learn as l2l

writer = SummaryWriter('/info')

def accuracy(predictions, targets):
    predictions = predictions.argmax(dim=1).view(targets.shape)
    return (predictions == targets).sum().float() / targets.size(0)

def nll(z, log_det):
    return (torch.mean(z**2) / 2 - torch.mean(log_det) / 28*28) * 0.0005

def fast_adapt(adaptation_data, evaluation_data, learner, loss, adaptation_steps, device):
    for step in range(adaptation_steps):
        data = [d for d in adaptation_data]
        X = th.cat([d[0] for d in data], dim=0).to(device)
        y = th.cat([th.tensor(d[1]).view(-1) for d in data], dim=0).to(device)
        y_pred, z, log_det = learner(X)
        log_ll = nll(z, log_det)
        train_error = loss(y_pred, y) + log_ll
        train_error /= len(adaptation_data)
        learner.adapt(train_error)
    data = [d for d in evaluation_data]
    X = th.cat([d[0] for d in data], dim=0).to(device)
    y = th.cat([th.tensor(d[1]).view(-1) for d in data], dim=0).to(device)
    y_pred, z, log_det = learner(X)
    log_ll = nll(z, log_det)
    valid_error = loss(y_pred, y) + log_ll
    valid_error /= len(evaluation_data)
    valid_accuracy = accuracy(y_pred, y)
    return valid_error, valid_accuracy

def main(
        ways=5,
        shots=1,
        meta_lr=0.003,
        fast_lr=0.5,
        meta_batch_size=32,
        adaptation_steps=1,
        num_iterations=6000,
        cuda=True,
        seed=42,
):
    random.seed(seed)
    np.random.seed(seed)
    th.manual_seed(seed)

    omniglot = l2l.vision.datasets.FullOmniglot(root='./data',
                                                transform=transforms.Compose([
                                                    l2l.vision.transforms.RandomDiscreteRotation(
                                                        [0.0, 90.0, 180.0, 270.0]),
                                                    transforms.Resize(28),
                                                    transforms.ToTensor(),
                                                    lambda x: 1.0 - x,
                                                ]),
                                                download=True)
    omniglot = l2l.data.MetaDataset(omniglot)
    classes = list(range(1623))
    random.shuffle(classes)
    train_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                             ways=ways,
                                             classes=classes[:1100],
                                             tasks=20000)
    valid_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                             ways=ways,
                                             classes=classes[1100:1200],
                                             tasks=1024)
    test_generator = l2l.data.TaskGenerator(dataset=omniglot,
                                            ways=ways,
                                            classes=classes[1200:],
                                            tasks=1024)

    # Create model
    model = FreezeNet((1, 28, 28), ways, num_steps=3)
    maml = l2l.algorithms.MAML(model, lr=fast_lr, first_order=False)
    opt = optim.Adam(maml.parameters(), meta_lr)
    loss = nn.CrossEntropyLoss(size_average=True, reduction='mean')

    for iteration in range(num_iterations):
        opt.zero_grad()
        meta_train_error = 0.0
        meta_train_accuracy = 0.0
        meta_valid_error = 0.0
        meta_valid_accuracy = 0.0
        meta_test_error = 0.0
        meta_test_accuracy = 0.0
        for task in range(meta_batch_size):
            # Compute meta-training loss
            learner = maml.clone()
            adaptation_data = train_generator.sample(shots=shots)
            evaluation_data = train_generator.sample(shots=shots,
                                                     task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps,
                                                               device)
            evaluation_error.backward()
            meta_train_error += evaluation_error.item()
            meta_train_accuracy += evaluation_accuracy.item()

            # Compute meta-validation loss
            learner = maml.clone()
            adaptation_data = valid_generator.sample(shots=shots)
            evaluation_data = valid_generator.sample(shots=shots,
                                                     task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps,
                                                               device)
            meta_valid_error += evaluation_error.item()
            meta_valid_accuracy += evaluation_accuracy.item()

            # Compute meta-testing loss
            learner = maml.clone()
            adaptation_data = test_generator.sample(shots=shots)
            evaluation_data = test_generator.sample(shots=shots,
                                                    task=adaptation_data.sampled_task)
            evaluation_error, evaluation_accuracy = fast_adapt(adaptation_data,
                                                               evaluation_data,
                                                               learner,
                                                               loss,
                                                               adaptation_steps,
                                                               device)
            meta_test_error += evaluation_error.item()
            meta_test_accuracy += evaluation_accuracy.item()

        # Print some metrics
        print('\n')
        print('Iteration', iteration)
        print('Meta Train Error', meta_train_error / meta_batch_size)
        print('Meta Train Accuracy', meta_train_accuracy / meta_batch_size)
        print('Meta Valid Error', meta_valid_error / meta_batch_size)
        print('Meta Valid Accuracy', meta_valid_accuracy / meta_batch_size)
        print('Meta Test Error', meta_test_error / meta_batch_size)
        print('Meta Test Accuracy', meta_test_accuracy / meta_batch_size)

        # Add information for evidence in project
        writer.add_scalar('Train Error', meta_train_error, iteration)
        writer.add_scalar('Validation Error', meta_valid_error, iteration)
        writer.add_scalar('Test Error', meta_test_error, iteration)

        writer.add_scalar('Train Accuracy', meta_train_accuracy, iteration)
        writer.add_scalar('Valid Accuracy', meta_valid_accuracy, iteration)
        writer.add_scalar('Test Accuracy', meta_test_accuracy, iteration)

        # Average the accumulated gradients and optimize
        for p in maml.parameters():
            p.grad.data.mul_(1.0 / meta_batch_size)
        opt.step()

    writer.close()    
    th.save(learner.state_dict(), '/saved_model')

if __name__ == '__main__':
    main()

and here is the model that I built:

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision.models.squeezenet import Fire
import FrEIA.framework as Ff
import FrEIA.modules as Fm

def subnet(in_channels, out_channels):
    return nn.Sequential(
        Fire(in_channels, 8, 16, 16),
        nn.BatchNorm2d(32),
        nn.ReLU(),
        Fire(32, 16, out_channels//2, out_channels//2),
    )


class FreezeNet(nn.Module):
    def __init__(self, shape, num_outputs, num_steps=3):
        super(FreezeNet, self).__init__()
        self.C, self.H, self.W = shape
        self.num_steps = num_steps
        self.model = self.build_model()
        self.final_conv = nn.Conv2d(2 * 2 * self.C, num_outputs, kernel_size=1)
        self.pool = nn.AvgPool2d(self.H // 2)

    def build_model(self):
        nodes = [Ff.InputNode(self.C, self.H, self.W, name='input')]
        nodes.append(Ff.Node(nodes[-1], Fm.HaarDownsampling, {}, name='Downsampling'))

        for i in range(self.num_steps):
            nodes.append(Ff.Node(nodes[-1], Fm.ActNorm, {}, name='actnorm_{}'.format(i)))
            nodes.append(Ff.Node(nodes[-1], Fm.PermuteRandom, {'seed':i}, name='permute_{}'.format(i)))
            nodes.append(Ff.Node(nodes[-1], Fm.GLOWCouplingBlock,
            {'subnet_constructor': subnet, 'clamp':1.2}, name='coupling_{}'.format(i)))

        nodes.append(Ff.OutputNode(nodes[-1], name='output_node'))
        return Ff.ReversibleGraphNet(nodes, verbose=False)

    def forward(self, x):
        z = self.model(x)
        y = F.relu(self.final_conv(z))
        y = F.sigmoid(self.pool(y))
        y = y.view(y.shape[0], -1)
        log_det = self.model.log_jacobian(run_forward=False)
        return y, z, log_det

The code should work, but it doesn't. I appreciate any help.

AttributeError: module 'learn2learn.text.datasets' has no attribute 'TaskGenerator'

Hi,

I am trying to run the news_topic_classification.py in the text examples folder, but I keep running into the error mentioned here:

Traceback (most recent call last): File "news_topic_classification.py", line 166, in <module> download_location=args.download_location) File "news_topic_classification.py", line 84, in main train_gen = l2l.text.datasets.TaskGenerator(text_train, ways=ways) AttributeError: module 'learn2learn.text.datasets' has no attribute 'TaskGenerator'

I am using a conda venv with the following pip list:

image

Error during installation (UnicodeDecodeError)

Collecting learn2learn
Using cached https://files.pythonhosted.org/packages/9e/31/da004bafc94300b7d1d2c6da297c9064ae5bab8181e5d2eb02f669279d4b/learn2learn-0.0.5.tar.gz
ERROR: Command errored out with exit status 1:
command: /usr/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-5xlmbvh1/learn2learn/setup.py'"'"'; file='"'"'/tmp/pip-install-5xlmbvh1/learn2learn/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-5xlmbvh1/learn2learn/pip-egg-info
cwd: /tmp/pip-install-5xlmbvh1/learn2learn/
Complete output (7 lines):
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-5xlmbvh1/learn2learn/setup.py", line 26, in
long_description=open('README.md').read(),
File "/usr/lib/python3.6/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3190: ordinal not in range(128)
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Hi, I wanted to install learn2learn by 'pip install learn2learn', but it's failed by this error.
I've searched how to solve this problem, and applied it, but it's also failed.
would you tell me how to solve this problem?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.