Module invertransforms.tensors
This module contains transformations on torch tensors.
Expand source code
"""
This module contains transformations on torch tensors.
"""
import torch
from torchvision import transforms
import invertransforms as T
from invertransforms import functional as F
from invertransforms.lib import InvertibleError, Invertible, flip_coin
class LinearTransformation(transforms.LinearTransformation, Invertible):
def inverse(self):
try:
return LinearTransformation(
transformation_matrix=self.transformation_matrix.inverse(),
mean_vector=(-1.0) * self.mean_vector @ self.transformation_matrix
)
except RuntimeError:
raise InvertibleError(
f'{self.__repr__()} is not invertible because the transformation matrix singular.')
class Normalize(transforms.Normalize, Invertible):
def inverse(self):
mean = torch.as_tensor(self.mean)
std = torch.as_tensor(self.std)
std_inv = torch.tensor(1.0) / std
mean_inv = (-1.0) * mean * std_inv
return Normalize(mean=mean_inv, std=std_inv, inplace=self.inplace)
class RandomErasing(transforms.RandomErasing, Invertible):
_transform = None
def __call__(self, img):
"""
Args:
img (Tensor): Tensor image of size (C, H, W) to be erased.
Returns:
img (Tensor): Erased Tensor image.
"""
self._transform = T.Identity()
if flip_coin(self.p):
x, y, h, w, v = self.get_params(img, scale=self.scale, ratio=self.ratio, value=self.value)
self._transform = T.Lambda(
lambd=lambda img: F.erase(img, x, y, h, w, v, self.inplace),
tf_inv=lambda img: img,
repr_str='RandomErasing()'
)
return img
def inverse(self):
if not self._can_invert():
raise InvertibleError('Cannot invert a random transformation before it is applied.')
return self._transform.inverse()
def _can_invert(self):
return self._transform is not None
Classes
class LinearTransformation (transformation_matrix, mean_vector)
-
Transform a tensor image with a square transformation matrix and a mean_vector computed offline. Given transformation_matrix and mean_vector, will flatten the torch.*Tensor and subtract mean_vector from it which is then followed by computing the dot product with the transformation matrix and then reshaping the tensor to its original shape.
Applications
whitening transformation: Suppose X is a column vector zero-centered data. Then compute the data covariance matrix [D x D] with torch.mm(X.t(), X), perform SVD on this matrix and pass it as transformation_matrix.
Args
transformation_matrix
:Tensor
- tensor [D x D], D = C x H x W
mean_vector
:Tensor
- tensor [D], D = C x H x W
Expand source code
class LinearTransformation(transforms.LinearTransformation, Invertible): def inverse(self): try: return LinearTransformation( transformation_matrix=self.transformation_matrix.inverse(), mean_vector=(-1.0) * self.mean_vector @ self.transformation_matrix ) except RuntimeError: raise InvertibleError( f'{self.__repr__()} is not invertible because the transformation matrix singular.')
Ancestors
- torchvision.transforms.transforms.LinearTransformation
- Invertible
Inherited members
class Normalize (mean, std, inplace=False)
-
Normalize a tensor image with mean and standard deviation. Given mean:
(M1,...,Mn)
and std:(S1,..,Sn)
forn
channels, this transform will normalize each channel of the inputtorch.*Tensor
i.e.input[channel] = (input[channel] - mean[channel]) / std[channel]
Note
This transform acts out of place, i.e., it does not mutates the input tensor.
Args
mean
:sequence
- Sequence of means for each channel.
std
:sequence
- Sequence of standard deviations for each channel.
inplace(bool,optional): Bool to make this operation in-place.
Expand source code
class Normalize(transforms.Normalize, Invertible): def inverse(self): mean = torch.as_tensor(self.mean) std = torch.as_tensor(self.std) std_inv = torch.tensor(1.0) / std mean_inv = (-1.0) * mean * std_inv return Normalize(mean=mean_inv, std=std_inv, inplace=self.inplace)
Ancestors
- torchvision.transforms.transforms.Normalize
- Invertible
Inherited members
class RandomErasing (p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)
-
Randomly selects a rectangle region in an image and erases its pixels. 'Random Erasing Data Augmentation' by Zhong et al. See https://arxiv.org/pdf/1708.04896.pdf
Args
p
- probability that the random erasing operation will be performed.
scale
- range of proportion of erased area against input image.
ratio
- range of aspect ratio of erased area.
value
- erasing value. Default is 0. If a single int, it is used to erase all pixels. If a tuple of length 3, it is used to erase R, G, B channels respectively. If a str of 'random', erasing each pixel with random values.
inplace
- boolean to make this transform inplace. Default set to False.
Returns
Erased Image.
Examples:
>>> transform = transforms.Compose([ >>> transforms.RandomHorizontalFlip(), >>> transforms.ToTensor(), >>> transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), >>> transforms.RandomErasing(), >>> ])
Expand source code
class RandomErasing(transforms.RandomErasing, Invertible): _transform = None def __call__(self, img): """ Args: img (Tensor): Tensor image of size (C, H, W) to be erased. Returns: img (Tensor): Erased Tensor image. """ self._transform = T.Identity() if flip_coin(self.p): x, y, h, w, v = self.get_params(img, scale=self.scale, ratio=self.ratio, value=self.value) self._transform = T.Lambda( lambd=lambda img: F.erase(img, x, y, h, w, v, self.inplace), tf_inv=lambda img: img, repr_str='RandomErasing()' ) return img def inverse(self): if not self._can_invert(): raise InvertibleError('Cannot invert a random transformation before it is applied.') return self._transform.inverse() def _can_invert(self): return self._transform is not None
Ancestors
- torchvision.transforms.transforms.RandomErasing
- Invertible
Inherited members