reshape,view 拆分某一维度用
permute 置换维度顺序用
einops 万能
a = torch.rand(2,3,4,5)
# a.chunk(5, dim=-1) -> list(torch[2,3,4,1])
import torch
tensor = torch.rand(2,3,224,224)
tensor.is_contiguous() # must make sure is contiguous
tensor.unsqueeze(0).shape # torch.Size([1, 2, 3, 224, 224])
tensor.squeeze(0).shape # Only cut the dimention if it is 1
tensor.view(-1,244,244).shape # torch.Size([6, 224, 224])
tensor.reshape(-1,244,244).shape # torch.Size([6, 224, 224])
tensor.transpose(0, 1).contiguous().shape # torch.Size([3, 2, 224, 224])
tensor.permute(3, 2, 0, 1).contiguous().shape # torch.Size([224, 224, 2, 3])
import torch
import torch.nn as nn
import torch.nn.functional as F
tensor = torch.rand(2,3,224,224)
m = nn.MaxPool2d((2, 2), stride=(2, 2))
m(tensor).shape # max value of each patch, torch.Size([2, 3, 112, 112])
m = nn.AvgPool2d((2, 2), stride=(2, 2))
m(tensor).shape # avergae each patch, torch.Size([2, 3, 112, 112])
m=nn.AdaptiveAvgPool2d(2)
m(tensor).shape # avergae each patch, torch.Size([2, 3, 2, 2])
m=nn.AdaptiveAvgPool2d(2)
m(tensor).shape # avergae each patch, torch.Size([2, 3, 2, 2])
m = nn.MaxPool2d((2, 2), stride=(2, 2), return_indices=True)
max_unpool = nn.MaxUnpool2d((2, 2), stride=(2, 2))
img_pool, indices = m(tensor)
img_unpool = max_unpool(img_pool, indices) # map to initial size, oher position will be zero, torch.Size([2, 3, 224, 224])
m = nn.UpsamplingNearest2d(scale_factor=2)
m(tensor).shape # repeat value upsample, 1,2 -> 1,1,2,2, torch.Size([2, 3, 448, 448])
m = nn.UpsamplingBilinear2d(scale_factor=2)
m(tensor).shape # bilinear upsample, 1,2 -> 1,1.33,1.66,2, torch.Size([2, 3, 448, 448])
interpolate
inp = torch.rand(1, 1, 2, 2)
'''
tensor([[[[0.3167, 0.4675],
[0.9175, 0.9710]]]])
'''
outp = F.interpolate(inp, (4, 4), mode='bilinear')
'''
tensor([[[[0.3167, 0.3544, 0.4298, 0.4675],
[0.4669, 0.4985, 0.5618, 0.5934],
[0.7673, 0.7868, 0.8257, 0.8451],
[0.9175, 0.9309, 0.9576, 0.9710]]]])
'''
grid_sample
inp = torch.rand(1, 1, 2, 2)
'''
tensor([[[[0.3167, 0.4675],
[0.9175, 0.9710]]]])
'''
out_h = 4
out_w = 4
new_h = torch.linspace(-1, 1, out_h).view(-1, 1).repeat(1, out_w)
new_w = torch.linspace(-1, 1, out_w).repeat(out_h, 1)
grid = torch.cat((new_h.unsqueeze(2), new_w.unsqueeze(2)), dim=2)
grid = grid.unsqueeze(0) # build grid values from -1~1
'''
tensor([[[[-1.0000, -1.0000],
[-1.0000, -0.3333],
[-1.0000, 0.3333],
[-1.0000, 1.0000]],
[[-0.3333, -1.0000],
[-0.3333, -0.3333],
[-0.3333, 0.3333],
[-0.3333, 1.0000]],
[[ 0.3333, -1.0000],
[ 0.3333, -0.3333],
[ 0.3333, 0.3333],
[ 0.3333, 1.0000]],
[[ 1.0000, -1.0000],
[ 1.0000, -0.3333],
[ 1.0000, 0.3333],
[ 1.0000, 1.0000]]]])
'''
outp = F.grid_sample(inp, grid=grid, mode='bilinear', align_corners=True).transpose(2,3)
'''
tensor([[[[0.3167, 0.3669, 0.4172, 0.4675],
[0.5169, 0.5564, 0.5959, 0.6353],
[0.7172, 0.7459, 0.7745, 0.8032],
[0.9175, 0.9353, 0.9532, 0.9710]]]])
'''
topk and select the indices on other features
corr = torch.range(0,47).reshape(2,4,6)
features = torch.range(1,48).reshape(2,4,6)
fea, idx = torch.topk(corr, 2, dim=1)
out = torch.gather(features, dim=1, index=idx)
截断取值范围
torch.clamp(m, min_value, max_value)
repeat and repeat_interleave
a = torch.randn(3, 5)
tensor([[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276]])
a.repeat_interleave(3, dim=0)
tensor([[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276]])
a.repeat(3, 1)
tensor([[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276],
[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276],
[ 0.5905, -0.1420, -0.7692, -0.0174, -0.7759],
[-1.0320, -0.7636, -0.2155, 0.0854, -0.0052],
[ 0.7473, -0.2531, -0.9139, 0.8557, -1.1276]])
- 指定索引填充指定值
attn = attn.masked_fill(mask == 0, -1e9)
- 沿某一维度拆分多块
qkv = self.to_qkv(x).chunk(3, dim = -1)
- 无穷大和无穷小填充
supermax = float('inf')
supermin = -float('inf')
- Mask to onehot 一行代码
obj_idx = torch.arange(0, 10).view(10, 1, 1)
mask = (mask == obj_idx).float() # 1xhxw & ox1x1 --> oxhxw
- 不一样的上采样 nn.PixelShuffle
BxRRCxHW --> BxCxRHxRW
ps = nn.PixelShuffle(3) # 缩放到三倍,r == 3
input = torch.tensor(1, 9, 4, 4) # r^2 C == 9C == 9,所以C == 1
output = ps(input)
print(output.size())
# 输出为 torch.Size([1, 1, 12, 12])