Code Monkey home page Code Monkey logo

changeling's Introduction

Changeling

Changeling is a neural network framework that allows for easy construction and manipulation of networks with multiple inputs and outputs. Parts of the network can be activated, deactivated, or frozen during training, allowing the user to train parts of the net individually. An example use case is training an RL agent that learns on progressively harder tasks. The agent can begin with a small neural net, as well as a reduced input and action space. As the agent learns tasks, its neural net can be expanded with more inputs, action outputs, and hidden neurons.

Usage

To use, first import the necessary classes and methods and define your neural net architecture using the Changeling class. Changeling inherits from torch.nn.Module, and has the same rules for parameter registration.

from torch import nn
from changeling.core.branch import Branch
from changeling.core.changeling import Changeling
from changeling.core.layers import MeanInputLayer


class MyModel(Changeling):
    def __init__(self):
        super().__init__()
        self.input_branches = {
            "gray_image": Branch(
                nn.Conv2d(1, 64, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.MaxPool2d(2)
            ),
            "color_image": Branch(
                nn.Conv2d(3, 64, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.MaxPool2d(2)
            ),
        }
        for name, branch in self.input_branches.items():
            self.add_module(name, branch)
        self.mean_input_layer = MeanInputLayer()
        self.hidden_layers = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
            nn.ReLU(),
            nn.Conv2d(128, 64, kernel_size=1),
            nn.ReLU(),
            nn.Conv2d(64, 32, kernel_size=1),
            nn.Flatten(),
            nn.Linear(2048, 512),
            nn.ReLU(),
            nn.Linear(512, 128),
            nn.ReLU(),
        )
        self.output_branches = {
            i: Branch(
                nn.Linear(128, 1),
                nn.Sigmoid(),
            )
            for i in range(10)
        }
        for name, branch in self.output_branches.items():
            self.add_module(name, branch)

    def forward(self, inputs: dict[str, Tensor]) -> Tensor:
        x = [
            self.input_branches[branch](inputs[branch])
            for branch in inputs.keys()
            if self.input_branches[branch].active
        ]
        x = self.mean_input_layer(x)
        x = self.hidden_layers(x)
        x = [
            self.output_branches[i](x)
            if self.output_branches[i].active
            else torch.zeros(hidden_out.shape[0], 1)
            for i in range(10)
        ]
        x = self.concat_layer(x)
        return x

This example neural net has two input branches, one processing grayscale images and the other color images, and 10 output branches for a classification task. The Branch class has activate, deactivate, freeze, and unfreeze functions, which can be used to control which parts of the net are active during training. Inactive branches are not used in the forward function.

Next, define the prep_lesson and loss methods for your neural net. The prep_lesson method specifies which parts of the net will be active or inactive during a given lesson, and the loss method defines the loss function for the net.

class MyModel(Changeling):
    # ... 
    
    def prep_lesson(self, name: str) -> None:
        if name == "Lesson 1":
            self.input_branches["gray_image"].activate()
            self.input_branches["color_image"].deactivate()
            for i in range(10):
                self.output_branches[i].deactivate()
            self.output_branches[0].activate()
        elif name == "Lesson 2":
            self.input_branches["gray_image"].activate()
            self.input_branches["color_image"].activate()
            for i in range(10):
                self.output_branches[i].deactivate()
            self.output_branches[0].activate()
            self.output_branches[1].activate()
        # ...

    def loss(self, outputs: Tensor, labels: Tensor) -> Tensor:
        return nn.CrossEntropyLoss(outputs, labels)

Once the neural net is defined, you can create a training curriculum and use the Teacher class to train and evaluate the net. The Teacher expects a list of Lesson objects, each specifying the training data, lesson name, and lesson completion criteria. The Teacher will use the lesson_complete criteria to determine when to move on to the next lesson in the curriculum.

from torch.utils.data import DataLoader
from changeling.core.learning_criteria import AccuracyThresholdAchieved, NEpochsComplete


class MyDataset(Dataset):
    # define your dataset here


train_loader = DataLoader(MyDataset(train=True), batch_size=32, shuffle=True)
test_loader = DataLoader(MyDataset(train=False), batch_size=32, shuffle=False)


def get_dataloader_subset(
    train_dataset: Dataset,
    test_dataset: Dataset,
    batch_size: int,
    output_labels_to_include: list[int],
) -> tuple[DataLoader, DataLoader]:
    ...


model = MyModel()
curriculum = [
    Lesson(
        name="Lesson 1",
        get_dataloaders=lambda: get_dataloader_subset(
            train_dataset,
            test_dataset,
            batch_size=32,
            output_labels_to_include=[0, 1],
        ),
        lesson_complete=NEpochsComplete(5),
    ),
    # ...    
    Lesson(
        name="Lesson N",
        get_dataloaders=lambda: get_dataloader_subset(
            train_dataset,
            test_dataset,
            batch_size=32,
            output_labels_to_include=list(range(10)),
        ),
        lesson_complete=AccuracyThresholdAchieved(0.95),
    ),
]


teacher = Teacher(model, curriculum)
teacher.teach()

Contributing

Contributions to Changeling are welcome!

License

TODO: fill this out

changeling's People

Contributors

mattunderscorezhang avatar

Watchers

 avatar

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.