Code Monkey home page Code Monkey logo

torch-toolbox's Introduction

Torch Toolbox

Stable Version: v0.1.5 (recommended)

Automatic upload to PyPI is finished.

This project aims to provide the most frequently used tools to help you write more concise and readable PyTorch code.

Pull requests and issues are highly encouraged. Please reach out!

Installing

An easy way to install Torch Toolbox is via pip:

pip install torchtoolbox

If you want to install the nightly version:

pip install -U git+https://github.com/PistonY/torch-toolbox.git@master

Todo

  • cv2 transforms.
  • Integrate with albumentations
  • Prepare tensorboard support with metric collection.

Usage

Toolbox have two main parts:

  1. Auxiliary tools to make using Pytorch easier.
  2. Some fashion work which don't exist in Pytorch core.

More examples could be found at ModelZoo.pytorch

Tools

0. Now CV2 transforms have been released.

Support as list:(need test)

__all__ = ["Compose", "ToTensor", "ToCVImage", "Normalize", "Resize", "Scale", "CenterCrop", "Pad",
           "Lambda", "RandomApply", "RandomChoice", "RandomOrder", "RandomCrop", "RandomHorizontalFlip",
           "RandomVerticalFlip", "RandomResizedCrop", "RandomSizedCrop", "FiveCrop", "TenCrop", "LinearTransformation",
           "ColorJitter", "RandomRotation", "RandomAffine", "Grayscale", "RandomGrayscale",
           "RandomPerspective", "RandomErasing", "RandomGaussianNoise", "RandomPoissonNoise", "RandomSPNoise",
           "RandomTransforms", "Cutout"]

Part of this code refers to opencv_transforms_torchvision

1. Show your model parameters and FLOPs.

import torch
from torchtoolbox.tools import summary
from torchvision.models.mobilenet import mobilenet_v2
model = mobilenet_v2()
summary(model, torch.rand((1, 3, 224, 224)))

Here are some short outputs.

        Layer (type)               Output Shape          Params    FLOPs(M+A) #
================================================================================
            Conv2d-1          [1, 64, 112, 112]            9408       235225088
       BatchNorm2d-2          [1, 64, 112, 112]             256         1605632
              ReLU-3          [1, 64, 112, 112]               0               0
         MaxPool2d-4            [1, 64, 56, 56]               0               0
          ...                      ...                      ...              ...
          Linear-158                  [1, 1000]         1281000         2560000
     MobileNetV2-159                  [1, 1000]               0               0
================================================================================
        Total parameters: 3,538,984  3.5M
    Trainable parameters: 3,504,872
Non-trainable parameters: 34,112
Total flops(M)  : 305,252,872  305.3M
Total flops(M+A): 610,505,744  610.5M
--------------------------------------------------------------------------------
Parameters size (MB): 13.50

2. Metric collection

When we train a model we usually need to calculate some metrics like accuracy(top1-acc), loss etc. Now toolbox support the following:

  1. Accuracy: top-1 acc.
  2. TopKAccuracy: topK-acc.
  3. NumericalCost: This is a number metric collection which support mean, max, min calculate type.
  4. FeatureVerification.
    • This is widely used in margin based algorithm.
from torchtoolbox import metric

# define first
top1_acc = metric.Accuracy(name='Top1 Accuracy')
top5_acc = metric.TopKAccuracy(top=5, name='Top5 Accuracy')
loss_record = metric.NumericalCost(name='Loss')

# reset before using
top1_acc.reset()
top5_acc.reset()
loss_record.reset()

...
model.eval()
for data, labels in val_data:
    data = data.to(device, non_blocking=True)
    labels = labels.to(device, non_blocking=True)

    outputs = model(data)
    losses = Loss(outputs, labels)
    # update/record
    top1_acc.update(outputs, labels)
    top5_acc.update(outputs, labels)
    loss_record.update(losses)
    test_msg = 'Test Epoch {}: {}:{:.5}, {}:{:.5}, {}:{:.5}\n'.format(
    epoch, top1_acc.name, top1_acc.get(), top5_acc.name, top5_acc.get(),
    loss_record.name, loss_record.get())

print(test_msg)

Then you may get outputs like this

Test Epoch 101: Top1 Accuracy:0.7332, Top5 Accuracy:0.91514, Loss:1.0605

3. Model Initializer

Now ToolBox support XavierInitializer and KaimingInitializer.

from torchtoolbox.nn.init import KaimingInitializer

model = XXX
initializer = KaimingInitializer()
model.apply(initializer)

4. AdaptiveSequential

Make Pytorch nn.Sequential could handle multi input/output layer.

from torch import nn
from torchtoolbox.nn import AdaptiveSequential
import torch


class n_to_n(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 3, 1, 1, bias=False)
        self.conv2 = nn.Conv2d(3, 3, 1, 1, bias=False)

    def forward(self, x1, x2):
        y1 = self.conv1(x1)
        y2 = self.conv2(x2)
        return y1, y2


class n_to_one(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 3, 1, 1, bias=False)
        self.conv2 = nn.Conv2d(3, 3, 1, 1, bias=False)

    def forward(self, x1, x2):
        y1 = self.conv1(x1)
        y2 = self.conv2(x2)
        return y1 + y2


class one_to_n(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 3, 1, 1, bias=False)
        self.conv2 = nn.Conv2d(3, 3, 1, 1, bias=False)

    def forward(self, x):
        y1 = self.conv1(x)
        y2 = self.conv2(x)
        return y1, y2

seq = AdaptiveSequential(one_to_n(), n_to_n(), n_to_one()).cuda()
td = torch.rand(1, 3, 32, 32).cuda()

out = seq(td)
print(out.size())

# output
# torch.Size([1, 3, 32, 32])

5. Make and Use LMDB dataset.

If you meet IO speed limit, you may think about LMDB format dataset. LMDB is a tiny database with some excellent properties.

Easy to generate a LMDB format dataset.

from torchtoolbox.tools.convert_lmdb import generate_lmdb_dataset, raw_reader
from torchvision.datasets import ImageFolder

dt = ImageFolder(..., loader=raw_reader)
save_dir = XXX 
dataset_name = YYY
generate_lmdb_dataset(dt, save_dir=save_dir, name=dataset_name)

Then if you use ImageFolder like dataset you can easily use ImageLMDB to load you dataset.

from torchtoolbox.data import ImageLMDB

dt = ImageLMDB(db_path=save_dir, db_name=dataset_name, ...)

6. Non-Lable dataset

This dataset only return images.

More details please refers to codes

7. Activation Layer

A Activation Layer is provided to select a activation by string.

from torchtoolbox.nn import Activation

relu = Activation('relu', auto_optimize=True)

8. FeatureVerification Metric

A FeatureVerification Metric used to test feature based accuracy. More details refers to code.

Fashion work

1. LabelSmoothingLoss

from torchtoolbox.nn import LabelSmoothingLoss
# The num classes of your task should be defined.
classes = 10
# Loss
Loss = LabelSmoothingLoss(classes, smoothing=0.1)

...
for i, (data, labels) in enumerate(train_data):
    data = data.to(device, non_blocking=True)
    labels = labels.to(device, non_blocking=True)

    optimizer.zero_grad()
    outputs = model(data)
    # just use as usual.
    loss = Loss(outputs, labels)
    loss.backward()
    optimizer.step()

2. CosineWarmupLr

Cosine lr scheduler with warm-up epochs.It's helpful to improve acc for classification models.

from torchtoolbox.optimizer import CosineWarmupLr

optimizer = optim.SGD(...)
# define scheduler
# `batches_pre_epoch` means how many batches(times update/step the model) within one epoch.
# `warmup_epochs` means increase lr how many epochs to `base_lr`.
# you can find more details in file.
lr_scheduler = CosineWarmupLr(optimizer, batches_pre_epoch, epochs,
                              base_lr=lr, warmup_epochs=warmup_epochs)
...
for i, (data, labels) in enumerate(train_data):
    ...
    optimizer.step()
    # remember to step/update status here.
    lr_scheduler.step()
    ...

3. SwitchNorm2d/3d

from torchtoolbox.nn import SwitchNorm2d, SwitchNorm3d

Just use it like Batchnorm2d/3d. More details please refer to origin paper Differentiable Learning-to-Normalize via Switchable Normalization OpenSourse

4. Swish activation

from torchtoolbox.nn import Swish

Just use it like Relu. More details please refer to origin paper SEARCHING FOR ACTIVATION FUNCTIONS

5. Lookahead optimizer

A wrapper optimizer seems better than Adam. Lookahead Optimizer: k steps forward, 1 step back

from torchtoolbox.optimizer import Lookahead
from torch import optim

optimizer = optim.Adam(...)
optimizer = Lookahead(optimizer)

5. Mixup training

Mixup method to train a classification model. mixup: BEYOND EMPIRICAL RISK MINIMIZATION

from torchtoolbox.tools import mixup_data, mixup_criterion

# set beta distributed parm, 0.2 is recommend.
alpha = 0.2
for i, (data, labels) in enumerate(train_data):
    data = data.to(device, non_blocking=True)
    labels = labels.to(device, non_blocking=True)

    data, labels_a, labels_b, lam = mixup_data(data, labels, alpha)
    optimizer.zero_grad()
    outputs = model(data)
    loss = mixup_criterion(Loss, outputs, labels_a, labels_b, lam)

    loss.backward()
    optimizer.update()

6. Cutout

A image transform method. Improved Regularization of Convolutional Neural Networks with Cutout

from torchvision import transforms
from torchtoolbox.transform import Cutout

_train_transform = transforms.Compose([
    transforms.RandomResizedCrop(224),
    Cutout(),
    transforms.RandomHorizontalFlip(),
    transforms.ColorJitter(0.4, 0.4, 0.4),
    transforms.ToTensor(),
    normalize,
])

7. No decay bias

If you train a model with big batch size, eg. 64k, you may need this, Highly Scalable Deep Learning Training System with Mixed-Precision: Training ImageNet in Four Minutes

from torchtoolbox.tools import no_decay_bias
from torch import optim

model = XXX
parameters = no_decay_bias(model)
optimizer = optim.SGD(parameters, ...)

8. Margin based classification loss

Now support:

  1. ArcLoss
  2. CosLoss
  3. L2Softmax
from torchtoolbox.nn.loss import ArcLoss, CosLoss, L2Softmax

You could use this like nn.CrossEntropyLoss

9. DCNv2

10. FocalLoss

11. SigmoidCrossEntropy

12. CircleLoss

13. EvoNrom

14. Activation Layer

  1. Swish
  2. HardSwish
  3. HardSigmoid Usage:
from torchtoolbox.nn import Swish, HardSwish, HardSigmoid

swish = Swish()
hswish = HardSwish()
hsigmoid = HardSigmoid()

15. Zero LastGamma Init

from torchtoolbox.nn.init import ZeroLastGamma

model == XXX
init = ZeroLastGamma(block_name='Bottleneck', bn_name='bn3')
model.apply(init)

16. SGC_GC

Gradient Centralization: A New Optimization Technique for Deep Neural Networks

from torchtoolbox.optimizer import SGD_GC

optimizer = SGD_GC(model.parameters())
optimizer.zero_grad()
loss.backward()
optimizer.step()

17. Autoaugment

# for ImageNet
from torchtoolbox.transform import ImageNetPolicy, Compose, \
            RandomResizedCrop, RandomHorizontalFlip, ToTensor

transforms = Compose([RandomResizedCrop(224), 
                      RandomHorizontalFlip(),
                      ImageNetPolicy,
                      ToTensor()])

Contribution

Welcome pull requests and issues!!!

torch-toolbox's People

Contributors

arthdh avatar digantamisra98 avatar garyhlai avatar pistony 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

torch-toolbox's Issues

ImageLMDB subdir error

set subdir=False, otherwise,
subdir=os.path.isdir(db_path)

master...sailfish009:master


.local/lib/python3.7/site-packages/torchtoolbox/data/lmdb_dataset.py", line 23, in __init__
    readahead=False, meminit=False)
lmdb.Error: /tmp/train_lmdb/train_image.lmdb: Not a directory

ImportError: dlopen: cannot load any more object with static TLS

Hello, when I use cutout, the following error occurs๏ผš
from torchtoolbox.transform import Cutout
File "/anaconda3/envs/recognition/lib/python3.8/site-packages/torchtoolbox/transform/init.py", line 4, in
from .transforms import *
File "/anaconda3/envs/recognition/lib/python3.8/site-packages/torchtoolbox/transform/transforms.py", line 11, in
from . import functional as F
File "/anaconda3/envs/recognition/lib/python3.8/site-packages/torchtoolbox/transform/functional.py", line 6, in
import cv2
File "/anaconda3/envs/recognition/lib/python3.8/site-packages/cv2/init.py", line 181, in
bootstrap()
File "/anaconda3/envs/recognition/lib/python3.8/site-packages/cv2/init.py", line 153, in bootstrap
native_module = importlib.import_module("cv2")
File "/anaconda3/envs/recognition/lib/python3.8/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
ImportError: dlopen: cannot load any more object with static TLS

DCNv2

How exactly is DCNv2 supported in this repo?

1d version of evo_norms

I've looked at the code for evonorm layers, it seems that you expect a 4d (n,c,h,w) shape. I need evonorm with 1d convolutions, for this it seems the only way is to rewrite the evo_norm function to handle the different shape. Do you plan to provide evonorm1d version for tensors of 3d shape?
Thanks

Cutout throws 'Image' object has no attribute 'shape'

pytorch-lightning==0.7.6
torchtoolbox==0.1.4.1
torchvision==0.6.0a0+82fd1c8

Loading Images using:
img = Image.open(str(IMAGE_DIR ))) # import PIL.Image as Image

Composing Transforms using:

self.transform_train = transforms.Compose([transforms.Resize((224, 224)), 
                                    transforms.RandomHorizontalFlip(0.5),
                                    transforms.RandomVerticalFlip(0.5),      
                                    transforms.ColorJitter(0.4, 0.4, 0.4),
                                    Cutout(),
                                    transforms.ToTensor(),
                                    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                                                   std=[0.229, 0.224, 0.225])])

Trace:
AttributeError: Caught AttributeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/worker.py", line 178, in _worker_loop
data = fetcher.fetch(index)
File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File "", line 30, in getitem
img = self.transform(img)
File "/opt/conda/lib/python3.7/site-packages/torchvision/transforms/transforms.py", line 61, in call
img = t(img)
File "/opt/conda/lib/python3.7/site-packages/torchtoolbox/transform/transforms.py", line 1450, in call
left, top, h, w, ch = self.get_params(img, self.scale, self.ratio)
File "/opt/conda/lib/python3.7/site-packages/torchtoolbox/transform/transforms.py", line 1433, in get_params
img_h, img_w, img_c = img.shape
AttributeError: 'Image' object has no attribute 'shape'

`np.int` now deprecated

https://github.com/PistonY/torch-toolbox/blame/993a0dfe56de9eda8d12aa08ebdae6ee932545cf/torchtoolbox/transform/autoaugment.py#L104

For the above line, following error is encountered

/usr/local/lib/python3.10/dist-packages/torchtoolbox/transform/autoaugment.py in __init__(self, p, magnitude)
    102 class Posterize(SubPolicy):
    103     def __init__(self, p, magnitude=None):
--> 104         ranges = np.round(np.linspace(8, 4, 10), 0).astype(np.int)
    105         super(Posterize, self).__init__(p, magnitude, ranges)
    106 

/usr/local/lib/python3.10/dist-packages/numpy/__init__.py in __getattr__(attr)
    317 
    318         if attr in __former_attrs__:
--> 319             raise AttributeError(__former_attrs__[attr])
    320 
    321         if attr == 'testing':

AttributeError: module 'numpy' has no attribute 'int'.
`np.int` was a deprecated alias for the builtin `int`. To avoid this error in existing code, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
    https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
    ```
    

from torchtoolbox.tools import split_weights error

In [4]: from torchtoolbox.tools import split_weights                                                                                                                                                                                                                                                 
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-4-6431db6b00b1> in <module>
----> 1 from torchtoolbox.tools import split_weights

ImportError: cannot import name 'split_weights' from 'torchtoolbox.tools' (/home/vladimir/anaconda3/lib/python3.7/site-packages/torchtoolbox/tools/__init__.py)

Cannot import 'ImageNetPolicy'

Hi, I am new to the package. I want to use the ImageNetPolicy as one of the data transformation by

from torchtoolbox.transform import ImageNetPolicy

But shows:

ImportError: cannot import name 'ImageNetPolicy'

How can I solve this? Thanks.

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.