Tensor.contiguous(memory_format=torch.contiguous_format) → Tensor
:主要是为了辅助pytorch中其他函数,返回原始tensor改变纬度后的深拷贝数据。x = torch.Tensor(2,3)
y = x.permute(1,0) # permute:二维tensor的维度变换,此处功能相当于转置transpose
y.view(-1) # 报错,view使用前需调用contiguous()函数
y = x.permute(1,0).contiguous()
y.view(-1) # OK
narrow(),view(),expand(),transpose(),permute()
这些函数是对原始数据纬度的变化,是对原始数据的浅拷贝。在执行这些操作时,pytorch并不会创建新的张量,而是修改了张量中的一些属性,但是二者在内存上是共享的。因此对执行transpose()操作后的张量的改变也会改变原始张量,如下:
x = torch.randn(3, 2)
y = x.transpose(x, 0, 1)
x[0, 0] = 233
print(y[0, 0]) # 233
在这个例子中,x是连续的,y不是连续的。y的布局方式与重新创建一个tensor的布局方式是不一样的,当对y调用了contiguous()函数之后,pytorch会强制拷贝一份tensor,使得它的布局是连续的,这也是执行view操作的条件。
x = torch.arange(12).reshape(3,4)
y = x[:,:,None]
print(x.shape,'\n',y.shape)
# torch.Size([3, 4])
# torch.Size([3, 4, 1])
x = torch.arange(4).reshape(1,4)
y = torch.arange(4).reshape(4,1)
print(x+y)
a = x.repeat(4,1)
b = y.repeat(1,4)
print(a+b)
在pytorch中模型的参数一种nn.Parameter()定义的,包括各种模块中的参数,这种会随着optimazer.step()更新;另一种是buffer,这种不会更新,相当于“常数”,不会在训练中改变
relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww
self.register_buffer("relative_position_index", relative_position_index)
from timm.models.layers import DropPath
from timm.models.layers import DropPath
self.drop_path = DropPath(drop_prob) if drop_prob > 0. else nn.Identity()
x = x + self.drop_path(self.mlp(self.norm2(x)))
表明有一些分支(batch中的样本)不经过norm和mlp,直接进行恒等变换。也就是加入了残差。
torch.roll(input, shifts, dims=None) → Tensor
说明:对张量沿指定纬度平移指定的places。>>> x = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]).view(4, 2)
>>> x
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
# 向0纬度正方向平移1个位置
>>> torch.roll(x, 1, 0)
tensor([[7, 8],
[1, 2],
[3, 4],
[5, 6]])
# 向0纬度负方向平移1个位置
>>> torch.roll(x, -1, 0)
tensor([[3, 4],
[5, 6],
[7, 8],
[1, 2]])
# 向0纬度正方向平移2个位置,1纬度正方向平移1个位置
>>> torch.roll(x, shifts=(2, 1), dims=(0, 1))
tensor([[6, 5],
[8, 7],
[2, 1],
[4, 3]])
Tensor.masked_fill(mask, value) → Tensor
:将tensor中mask为true的位置替换为value。此函数不改变原始tensor,返回改变后的tensor。mask为一个张量,与tensor形状一致。x = torch.arange(24).reshape(2,3,4)
y = x.masked_fill(x>10,10)
print(x,'\n\n',y)
# tensor([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]],
# [[12, 13, 14, 15],
# [16, 17, 18, 19],
# [20, 21, 22, 23]]])
# tensor([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 10]],
# [[10, 10, 10, 10],
# [10, 10, 10, 10],
# [10, 10, 10, 10]]])
torch.nn.parameter.Parameter(data=None, requires_grad=True)
或者torch.nn.Parameter(data=None, requires_grad=True)
:参数是一个tensor,类型为浮点数y = torch.arange(24).float() # 可以看做初始化
x = nn.Parameter(y) # 如果在Module中则会被自动优化
torch.meshgrid(*tensors, indexing=None)
#二维举例
x = torch.arange(2) # 行坐标,长度为2
y = torch.arange(2,5) # 列坐标,长度为3
a1, a2 = torch.meshgrid(x,y) # 返回一个tuple,2个tensor(2,3)
print(a1)
# tensor([[0, 0, 0],
# [1, 1, 1]])
print(a2)
# tensor([[2, 3, 4],
# [2, 3, 4]])
# 三维举例
z = torch.arange(3,7) # 第三维坐标,长度为4
b1, b2, b3 = torch.meshgrid(x,y,z) # 返回一个tuple,3个tensor(2,3,4)
print(b1) # 只有第一维的元素不同,相当于b1 = torch.arange(2).reshape(2,1,1).repeat(1,3,4)
# tensor([[[0, 0, 0, 0],
# [0, 0, 0, 0],
# [0, 0, 0, 0]],
# [[1, 1, 1, 1],
# [1, 1, 1, 1],
# [1, 1, 1, 1]]])
# y=A(x), z=B(y) 求B中参数的梯度,不求A中参数的梯度
y = A(x)
z = B(y.detach())
z.backward()
a = torch.tensor([0.0], requires_grad=True)
c = a.item()
print(type(c)) #
参考:
pytorch中的detach()、detach_()
pytorch-detach,detach_
Pytorch中x.data()与x.detach()的区别
inputs = torch.randn(m, n)
# 创建空的tensor
new_inputs = inputs.new()
new_inputs = torch.Tensor.new(inputs)
# 创建shape为(3,4)的tensor(与inputs的type和device相同)
new_inputs = inputs.new(3,4)
Tensor.type_as(tensor) → Tensor
,将tensor的dtype转换为指定张量的类型。相当于self.type(tensor.type())