Data and experiment versioning with trainer for end-to-end tasks
🚀 Feature

Add trainers for various tasks like classification/regression etc. that can be directly used for a new dataset without having to write any new line of code along with explicit support for versioning data and config-based creation of the entire pipeline.
Motivation

Hi everyone. Thanks for this awesome library. For some reason, I was not aware that PyTorch Lightning has so many great features. Since I was unaware, for my own experiments, I ended up writing my own premature version here. A few things that I really wanted to have was to avoid repeating code and be able to log every change in my experiments as well as in the data split being used. So, the repo linked above explicitly requires a config file (.yml) as input and generates all aspects of the pipeline like transforms, network, dataset, dataloader and various training details. It also imposes a standardization on the input format so that the same Dataset objects can be used for the same task (like classification) even with different datasets. Also, data versioning is something that is very important to me and so, there is also a requirement to specifically point to the version of data that is to be used. This allows reproducibility and documentation to great detail as well as minimizes the number of things one needs to do for moving to a new dataset of an existing task. So, if we have a package that extends PyTorch lightning with some of these features, it can further enable reproducibility, documentation and ease of experimentation.
Pitch

Create a new package (for example, pl-trainers) within the PyTorchLightning handle that extends pytorch-lightning for complete tasks and allows all aspects of the pipeline to be configurable by a single file.
For example, pl-trainers can contain a ClassificationTrainer class that handles everything related to classification and a Config class which accepts a .yml file as an argument and creates the corresponding trainer using the Factory design pattern:
from pl_trainers.config import Config
from pl_trainers import trainers

# create the config object
config = Config('classification.yml')

# create the trainer from the config object and this will
# also create the corresponding data loaders and networks
trainer = trainers(config)

# train the model
trainer.fit()
The .yml can look something like this where all aspects of the training pipeline, input processing, network architecture and data config is defined:
description: default config for CIFAR10 classification with resnet18
metrics_to_track:
- accuracy
train_mode: train-val
val_mode: test

device:
  name: cuda

# define the training parameters
model:
    name: classification
    batch_size: 512
    epochs: 35

    # define optimization parameters
    optimizer:
      name: AdamW
      args:
        lr: 0.00012
        weight_decay: 0.4
      scheduler:
        name: 1cycle
        update: batch
        params:
            max_lr: 0.003
            epochs: 35
            steps_per_epoch: 98
            pct_start: 0.3
            div_factor: 25
   
    # define the losses
    loss:
      train-val:
        name: cross-entropy
        params:
            reduction: none
      test:
        name: cross-entropy
        params:
            reduction: none
    
    # parameters for model checkpointing
    save:
      period: 2
      monitor: accuracy
      monitor_mode: max

    # parameters for resuming training
    load:
      version: null
      epoch: -1
      load_best: False
      resume_optimizer: False

# define the network architecture in the config itself
network:
    name: neural_net
    params:
        config:
        - name: resnet18
          params:
            in_channels: 3
            pretrained: true
        - name: AdaptiveAvgPool2d
          params:
            output_size:
            - 1
            - 1
        - name: Flatten
          params: {}
        - name: Linear
          params:
            in_features: 512
            out_features: 10

# define all data-related parameters
data:
  data_type: image

  # input processing defined in the config file itself
  signal_transform:
    train-val:
    - name: Permute
      params:
        order:
          - 2
          - 0
          - 1
    - name: Rescale
      params:
        value: 255.
    - name: RandomHorizontalFlip
      params:
        p: 0.5
    - name: RandomCrop
      params:
        padding: 4
        size:
          - 32
          - 32
        padding_mode: reflect
    - name: Normalize
      params:
        mean: cifar
        std: cifar

    test:
    - name: Permute
      params:
        order:
          - 2
          - 0
          - 1
    - name: Rescale
      params:
        value: 255.
    - name: RandomHorizontalFlip
      params:
        p: 0.5
    - name: RandomCrop
      params:
        padding: 4
        size:
          - 32
          - 32
        padding_mode: reflect
    - name: Normalize
      params:
        mean: cifar
        std: cifar

  # explicit support for data versioning
  dataset:
    name: classification_dataset
    config:
      - name: CIFAR10
        version: default
    params: {}
  collate_fn:
    name: classification_collate
    params: {}

Additional context

I can totally understand if this does not match with the philosophy of PyTorchLightning. I have found this kind of framework very useful for my own experiments and upon encountering PyTorchLightning today, I realized how much I have missed out (still shocked as to how I didn't come across this earlier). My only goal is to foster reproducibility and redundancy and I wanted to share my idea with the community here. Please share your thoughts on the same!