PytorchAPI - torch

文章目录

  • 1. Tensors
      • (1) torch.is_tensor(obj)
      • (2) torch.is_complex(obj)
      • (3) torch.is_nonzero(Tensor)
      • (4) torch.set_default_dtype(dtype)
      • (5) torch.get_default_dtype()
      • (6) torch.set_default_tensor_type(type)
      • (7) torch.numel(tensor)
      • (8) torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None, sci_mode=None)
  • 2. Random Sampling
      • (1) torch.manual_seed(s)
      • (2) torch.rand(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
      • (3) torch.randn(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
      • (4) torch.rand_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)
      • (5) torch.randn_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)
      • (6) torch.randint(low=0, high, size, \*, generator=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (7) torch.randint_like(input, low=0, high, \*, dtype=None, layout=torch.strided, device=None, requires_grad=False, memory_format=torch.preserve_format)
      • (8) torch.randperm(n, *, generator=None, out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
      • (9) torch.bernoulli(input, *, generator=None, out=None)
      • (10) torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None)
      • (11) torch.normal(mean, std, *, generator=None, out=None)
  • 3. Serialization
      • (1) torch.save(obj, f, pickle_module=pickle, pickle_protocol=DEFAULT_PROTOCOL, _use_new_zipfile_serialization=True)
      • (2) torch.load(f, map_location=None, pickle_module=pickle, *, weights_only=False, **pickle_load_args)
      • 训练模型的保存1 —— 模型整体的保存
      • 训练模型的保存2 —— 模型参数的保存
  • 4. Locally Disabling Gradient Computation
      • (1) torch.no_grad()
      • (2) torch.enable_grad()
      • (3) torch.set_grad_enabled(mode)
      • (4) torch.is_grad_enabled()
      • 关于model.train()和model.eval()及自动梯度的关系
  • 5. Tensor Creation
      • (1)torch.sparse_coo_tensor(indices, values, size=None, *, dtype=None, device=None, requires_grad=False)
      • (2)torch.asarray(obj, *, dtype=None, device=None, copy=None, requires_grad=False)
      • (3) torch.as_tensor(data, dtype=None, device=None)
      • (4) torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (5) torch.linspace(start, end, steps, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (6) torch.logspace(start, end, steps, base=10.0, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (7) torch.eye(n, m=None, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (8) torch.full(size, fill_value, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
      • (9) torch.polar(abs, angle, *, out=None)
      • (10) torch.heaviside(input, values, *, out=None)
  • 6. Tensor Operations
      • (1) torch.adjoint(Tensor)
      • (2) torch.argwhere(input)
      • (3) torch.cat(tensors, dim=0, *, out=None)
      • (4) torch.conj(input)
      • (5) torch.chunk(input, chunks, dim=0)
      • (6) torch.narrow(input, dim, start, length)
      • (7) torch.permute(input, dims)

1. Tensors

(1) torch.is_tensor(obj)

判断obj是不是tensor类型的,返回True/False.它本质上是通过isinstance(obj, torch.Tensor)实现的,所以真正要用的时候不妨用isinstance进行替代。

(2) torch.is_complex(obj)

判断obj是不是tensor.complex64torch.complex128类型的,返回True/False.
pytorch中生成复数张量使用如下方式:

variable= torch.complex(real=torch.tensor(1, dtype=torch.float64), imag=torch.tensor(2, dtype=torch.float64))

其中,real和imag类型得一致,要么都是torch.float32,要么都是torch.float64.如果都是torch.float32,那么生成的复数类型为torch.complex64,如果都是torch.float64,那么生成的复数类型为torch.complex128.
使用样例(注释表示输出结果):

    variable = torch.complex(real=torch.tensor(1, dtype=torch.float64), imag=torch.tensor(2, dtype=torch.float64))
    print(torch.is_complex(variable))
    print(variable.dtype)
# True
# True
# torch.complex128

(3) torch.is_nonzero(Tensor)

判断单元素张量是否为非0,如果是非0则返回True,如果是0则返回False。逻辑值False看作0.
示例

    variable = torch.tensor([1])
    print(torch.is_nonzero(variable))
    variable = torch.tensor([0.0])
    print(torch.is_nonzero(variable))
    variable = torch.tensor([False])
    print(torch.is_nonzero(variable))
# True
# False
# False

该方法不能对多元素的张量进行判断,如:
错误示例

    variable = torch.tensor([1, 5])
    print(torch.is_nonzero(variable))

会报如下错误:
Traceback (most recent call last):
File “C:\Users\86158\Desktop\Pytorch Learn\code_1\main.py”, line 6, in
print(torch.is_nonzero(variable))
RuntimeError: Boolean value of Tensor with more than one value is ambiguous

(4) torch.set_default_dtype(dtype)

设置默认的浮点类型dtype可以是torch.float32torch.float64.同时,默认复数张量的类型也会随之发生隐式的变化,如果设置为torch.float32,那么默认复数张量类型会变为torch.complex64;如果设置为torch.float64,那么默认复数张量类型会变为torch.complex128.
示例

    a = torch.tensor([1.0, 2.6])
    print(a.dtype)
    torch.set_default_dtype(torch.float64)
    b = torch.tensor([1.0, 2.6])
    print(b.dtype)
# torch.float32
# torch.float64

(5) torch.get_default_dtype()

获取默认的浮点类型

(6) torch.set_default_tensor_type(type)

设置默认的张量浮点类型,其实作用和(4)差不多。type如果为torch.FloatTensor,那么就是设置默认浮点类型为torch.float32type如果为torch.DoubleTensor,那么就是设置默认浮点类型为torch.float64.
示例

    a = torch.tensor([1.0, 2.6])
    print(a.dtype)
    torch.set_default_tensor_type(torch.DoubleTensor)
    b = torch.tensor([1.0, 2.6])
    print(b.dtype)
    print(torch.get_default_dtype())
    torch.set_default_tensor_type(torch.FloatTensor)
    c = torch.tensor([1.0, 2.6])
    print(c.dtype)
    print(torch.get_default_dtype())
# torch.float32
# torch.float64
# torch.float64
# torch.float32
# torch.float32

(7) torch.numel(tensor)

返回tensor中元素的数量。
示例

	variable = torch.randn(1, 2, 3, 4, 5)
	print(torch.numel(variable))
# 120

(8) torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None, sci_mode=None)

对tensor的print方式进行设置。
precision — 打印输出的浮点精度位数,默认是4位,同时会对末尾进行四舍五入效果。

    variable = torch.tensor([1.123456789])
    print(variable)
    torch.set_printoptions(precision=1)
    print(variable)
    torch.set_printoptions(precision=6)
    print(variable)
# tensor([1.1235])
# tensor([1.1])
# tensor([1.123457])

threshold — 打印输出的元素个数的阈值设置。这个地方要清楚的是,并不是说设置threshold为多少就会显示多少个元素,它只有两种显示方式:要么把tensor中所有的元素都给显示出来;要么只显示最前面的3个元素和最后面的3个元素,中间的全部用…省略。当tensor中的元素数量大于threshold时,则采用第二种省略的显示方式;当tensor中的元素数量小于等于threshold时,则采用全部显示的方式。默认threshold为1000.

    variable = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0])
    print(variable)
    torch.set_printoptions(threshold=10)
    print(variable)
    torch.set_printoptions(threshold=11)
    print(variable)
    torch.set_printoptions(threshold=12)
    print(variable)
    torch.set_printoptions(threshold=13)
    print(variable)
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  ..., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  ..., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])

edgeitems — 默认的打印方式要么全部显示,要么元素数量超过threshold时两边各显示三个。该参数可以设置元素数量超过threshold时两边显示的元素数目。
示例

    variable = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0])
    print(variable)
    torch.set_printoptions(threshold=4, edgeitems=1)
    print(variable)
    torch.set_printoptions(threshold=4, edgeitems=2)
    print(variable)
    torch.set_printoptions(threshold=4, edgeitems=3)
    print(variable)
    torch.set_printoptions(threshold=4, edgeitems=4)
    print(variable)
    torch.set_printoptions(threshold=4, edgeitems=20)
    print(variable)
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])
# tensor([ 1.,  ..., 12.])
# tensor([ 1.,  2.,  ..., 11., 12.])
# tensor([ 1.,  2.,  3.,  ..., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,  ...,  9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])

linewidth — 设置每行显示字符数量,默认为80.
示例

    variable = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0])
    print(variable)
    torch.set_printoptions(linewidth=30)
    print(variable)
    torch.set_printoptions(linewidth=40)
    print(variable)
    torch.set_printoptions(threshold=4, linewidth=40)
    print(variable)
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,
#          5.,  6.,  7.,  8.,
#          9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,
#          7.,  8.,  9., 10., 11., 12.])
# tensor([ 1.,  2.,  3.,  ..., 10., 11.,
#         12.])

profile — 以优雅的方式打印输出,会覆盖掉上面所有的选项。有三种模式,default, short, full.
示例

	torch.set_printoptions(profile='default')

sci_mode — 启用(True)或禁用(False)科学计数法。如果指定了None(即为默认),则该值由torch._tensor_str._Formatter定义,这个值由框架自动选择。
示例

    variable = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0])
    print(variable)
    torch.set_printoptions(precision=2, sci_mode=True)
    print(variable)
    torch.set_printoptions(sci_mode=False)
    print(variable)
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])
# tensor([1.00e+00, 2.00e+00, 3.00e+00, 4.00e+00, 5.00e+00, 6.00e+00, 7.00e+00, 8.00e+00, 9.00e+00, 1.00e+01, 1.10e+01, 1.20e+01])
# tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])

2. Random Sampling

(1) torch.manual_seed(s)

设置一个随机数种子,这样子每次重新运行代码时,只要是同一个随机数种子,后面代码中生成的随机数都是一致的,这就保证了实验的可复现性。如果不设置随机数种子,那么每一次运行代码都会随机生成不同的随机数。

(2) torch.rand(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)

生成一个size大小的随机数tensor,服从均匀分布,区间为[0, 1)。
size是生成的随机数tensor的形状,dtype是数据类型,requires_grad默认为False,如果样本数据集是加载在CPU上的,并且希望把它放到GPU上训练,可以把pin_memory设置为True来加速(一般来说总是设置为True就可以了)。
示例

    torch.manual_seed(5)
    variable = torch.rand(size=(2, 3, 4))
    print(variable)
# tensor([[[0.8303, 0.1261, 0.9075, 0.8199],
#          [0.9201, 0.1166, 0.1644, 0.7379],
#          [0.0333, 0.9942, 0.6064, 0.5646]],
# 
#         [[0.0724, 0.6593, 0.7150, 0.5793],
#          [0.9809, 0.6502, 0.0566, 0.9201],
#          [0.6698, 0.2615, 0.0407, 0.7850]]])

(3) torch.randn(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)

生成一个size大小的随机数tensor,服从标准正态分布,均值为0,方差为1.
其他参数意义和上面差不多。

(4) torch.rand_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)

返回一个和input相同size的,服从均匀分布,区间为[0, 1)的随机数tensor.
torch.rand_like(input) 和 torch.rand(input.size(), dtype=input.dtype, layout=input.layout, device=input.device)的作用是等效的。

(5) torch.randn_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)

返回一个和input相同size的,服从标准正态分布,均值为0,方差为1的随机数tensor.
torch.randn_like(input) 和 torch.randn(input.size(), dtype=input.dtype, layout=input.layout, device=input.device)的作用是等效的。

(6) torch.randint(low=0, high, size, *, generator=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

返回一个区间为[low, high),均匀分布的形状为size的随机整数tensor。返回的tensor类型是torch.int64.
示例

    torch.manual_seed(5)
    a = torch.randint(0, 2, size=(10, ))
    b = torch.randint(1, 101, size=(2, 5))
    print(a)
    print(b)
# tensor([1, 0, 1, 1, 0, 0, 0, 1, 0, 0])
# tensor([[80, 51, 12, 13, 19],
#         [89, 24,  1, 28, 10]])

(7) torch.randint_like(input, low=0, high, *, dtype=None, layout=torch.strided, device=None, requires_grad=False, memory_format=torch.preserve_format)

返回一个区间为[low, high),均匀分布的形状和input一致的随机整数tensor。dtype,layout和device如果为None,则默认和input的保持一致。
示例

    torch.manual_seed(5)
    a = torch.randint(1, 101, size=(2, 5))
    b = torch.randint_like(a, 0, 2)
    print(a)
    print(b)
# tensor([[12, 15, 68, 86,  7],
#         [71, 93, 34, 89,  5]])
# tensor([[1, 0, 1, 0, 0],
#         [0, 1, 0, 1, 1]])

(8) torch.randperm(n, *, generator=None, out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)

返回一个从0到n-1的整数的随机排列。
示例

    torch.manual_seed(5)
    variable = torch.randperm(10)
    print(variable)
# tensor([1, 4, 9, 6, 3, 5, 0, 2, 8, 7])

(9) torch.bernoulli(input, *, generator=None, out=None)

input应为一个包含概率值的tensor,即它的每一个元素都应在区间[0, 1]内。函数返回生成一个元素为0或1二值的tensor,取0或取1的概率和input中的概率值保持一致。概率越高,越可能是1;概率越低,越可能是0.
示例

    torch.manual_seed(5)
    probability = torch.tensor([[0.9, 0.87, 0.95, 0.96, 0.99], [0.10, 0.11, 0.03, 0.13, 0.08]])
    variable = torch.bernoulli(probability)
    print(probability)
    print(variable)
# tensor([[0.9000, 0.8700, 0.9500, 0.9600, 0.9900],
#         [0.1000, 0.1100, 0.0300, 0.1300, 0.0800]])
# tensor([[1., 1., 1., 1., 1.],
#         [0., 0., 0., 1., 0.]])

(10) torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None)

input的每一行进行多次采样,采样结果为被采样元素在该行中的位置。元素被采样的概率与该元素的值大小相关,值越大被采样的概率越大。num_samples表示采样的次数,replacement表示是否放回。当replacement为False时,即不放回,此时num_samples不能大于每一行的元素个数,因为在不放回的情况下,最多采样每一行元素个数个次数。
示例

    torch.manual_seed(7)
    weight = torch.tensor([[1, 10, 100, 1000, 10000], [0, 50, 100, 200, 400]], dtype=torch.float32)
    variable = torch.multinomial(weight, 5, replacement=False)
    print(variable)
# tensor([[4, 3, 2, 1, 0],
#         [4, 1, 3, 2, 0]])
    torch.manual_seed(7)
    weight = torch.tensor([[1, 10, 100, 1000, 10000], [0, 50, 100, 200, 400]], dtype=torch.float32)
    variable = torch.multinomial(weight, 5, replacement=True)
    print(variable)
# tensor([[4, 4, 4, 4, 4],
#         [4, 3, 4, 4, 4]])

(11) torch.normal(mean, std, *, generator=None, out=None)

该函数从正态分布中随机提取张量每一个元素的值,并返回tensor.
①如果张量中的每一个元素都独立地从相同均值和标准差的正态分布中获取,可以如下:

    torch.manual_seed(7)
    variable = torch.normal(mean=1.0, std=2.0, size=(3, 4))
    print(variable)
# tensor([[ 0.7064,  2.5723,  2.8936, -1.2287],
#         [ 4.3816, -0.7897,  0.2887,  3.4648],
#         [ 1.2763, -2.3644,  1.6354,  1.2656]])

并不是这个张量中元素的整体服从该正态分布,而只是每个元素分别独立地来自相同均值和方差的各自的正态分布。
②如果张量中的每一个元素都独立地从各自不同均值和标准差的正态分布中获取,可以如下:

    torch.manual_seed(7)
    variable = torch.normal(mean=torch.arange(1.0, 11.0), std=0.05)
    print(variable)
# tensor([0.9927, 2.0393, 3.0473, 3.9443, 5.0845, 5.9553, 6.9822, 8.0616, 9.0069,
#         9.9159])

3. Serialization

(1) torch.save(obj, f, pickle_module=pickle, pickle_protocol=DEFAULT_PROTOCOL, _use_new_zipfile_serialization=True)

将一个对象序列化并保存,常用.pt作为保存后缀名,示例如下:

	torch.manual_seed(7)
    variable = torch.normal(mean=torch.arange(1.0, 11.0), std=0.05)
    torch.save(variable, 'variable.pt')

(2) torch.load(f, map_location=None, pickle_module=pickle, *, weights_only=False, **pickle_load_args)

将通过序列化保存为文件的对象读取出来,示例如下:

    q = torch.load('variable.pt')
    print(q)

训练模型的保存1 —— 模型整体的保存

这两个函数在保存和加载训练的模型中有很大的用处。首先,利用torch.save进行模型的保存,如

	torch.save(model, 'MNIST_model.pt')

这样训练好的整个模型就整个被保存下来了。在下一次使用的时候,只需要读入模型即可,如下

	model = torch.load('MNIST_model.pt')

要注意的是,因为在保存的时候保存的是整个模型而不是模型的参数,因此在读取训练好的模型时直接让model等于加载的模型即可,不需要先创建或初始化一个模型。

训练模型的保存2 —— 模型参数的保存

有时候我们只希望保存模型的参数,也是用这两个函数,差不多的方法就可以实现。
首先,在训练结束的时候利用torch.save进行模型参数的保存,如

torch.save(model.state_dict(), 'MNIST_model_state_dict.pt')

这样,训练好的模型的参数就被保存下来了,在下一次使用的时候,只需要读入模型即可,如下

    MNIST_model_state_dict = torch.load('MNIST_model_state_dict.pt')
    model.load_state_dict(MNIST_model_state_dict)

4. Locally Disabling Gradient Computation

(1) torch.no_grad()

在环境中禁用自动梯度,示例如下:

    x = torch.tensor([1.0], requires_grad=True)
    y = x * 2
    print(y.requires_grad)
# True
    x = torch.tensor([1.0], requires_grad=True)
    with torch.no_grad():
        y = x * 2
    print(y.requires_grad)
# False
	def times2(x):
	    return x*2
	
	
	if __name__ == '__main__':
	    x = torch.tensor([1.0], requires_grad=True)
	    y = times2(x)
	    print(y.requires_grad)
# True
	@torch.no_grad()
	def times2(x):
	    return x*2
	
	
	if __name__ == '__main__':
	    x = torch.tensor([1.0], requires_grad=True)
	    y = times2(x)
	    print(y.requires_grad)
# False

(2) torch.enable_grad()

在环境中启用自动梯度,示例如下

    x = torch.tensor([1.0], requires_grad=True)
    with torch.enable_grad():
        y = x * 2
    print(x.requires_grad)

但是要注意,如果原来输入的x的requires_grad=False,那么即便使用的torch.enable_grad(),输出的y的requires_grad依然等于False,示例如下:

    x = torch.tensor([1.0], requires_grad=False)
    with torch.enable_grad():
        y = x * 2
    print(y.requires_grad)
# False

(3) torch.set_grad_enabled(mode)

当mode为True时,表示启用自动梯度,那么就和torch.enable_grad()效果是一样的;当mode为False时,表示禁用自动梯度,那么就和torch.no_grad()效果是一样的。
示例

    x = torch.tensor([1.0], requires_grad=True)
    with torch.set_grad_enabled(False):
        y = x * 2
    print(y.requires_grad)
# False
    x = torch.tensor([1.0], requires_grad=True)
    with torch.set_grad_enabled(True):
        y = x * 2
    print(y.requires_grad)
# True

(4) torch.is_grad_enabled()

判断当前环境是否启用自动梯度。返回True则表示已启用,返回False则表示未启用。
示例

    x = torch.tensor([1.0], requires_grad=True)
    with torch.set_grad_enabled(False):
        y = x * 2
        print(torch.is_grad_enabled())
    print(torch.is_grad_enabled())
# False
# True

关于model.train()和model.eval()及自动梯度的关系

①model.train()和model.eval()负责的是BatchNorm和Dropout。当使用model.train()时,则开启训练模式,此时BatchNorm和Dropout是在变化的;当使用model.eval()时,则开启推理模式,此时就固定了BatchNorm和Dropout,如果不固定,就会导致网络有问题及推理结果出现错误。
②自动梯度负责的是是否进行梯度计算的问题,和上面两个负责的是两个不同的部分。
可再参考【PyTorch】搞定网络训练中的model.train()和model.eval()模式进行进一步了解。

5. Tensor Creation

(1)torch.sparse_coo_tensor(indices, values, size=None, *, dtype=None, device=None, requires_grad=False)

创建一个稀疏张量,indices是稀疏张量中非零元素的坐标,values是稀疏张量中非零元素的值。size表示稀疏张量的形状,如果size为None,则默认为满足需求稀疏张量的最小size。
示例

	i = torch.tensor([[0, 1, 1], [2, 0, 2]])
    v = torch.tensor([3, 4, 5], dtype=torch.float32)
    variable = torch.sparse_coo_tensor(i, v, [2, 4], requires_grad=True)
    print(variable)

在该示例中,稀疏张量的非零元素分别是(0, 2)的3,(1, 0)的4,(1, 2)的5. 稀疏张量的形状为 2 × 4 2\times4 2×4.

(2)torch.asarray(obj, *, dtype=None, device=None, copy=None, requires_grad=False)

用于将一个obj转换为tensor,obj可以是以下之一
1.a tensor
2.a NumPy array
3.a DLPack capsule
4.an object that implements Python’s buffer protocol
5.a scalar
6.a sequence of scalars
值得关注的是这个copy的参数,copy为None时,则创建的tensor和obj尽可能共享内存;copy为False时,则返回的tensor和obj共享内存,如果不能共享内存则抛出异常;copy为True时,则不共享内存。默认为None
示例

    a = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
    b = torch.asarray(a, copy=False)
    print(f'{a},{a.requires_grad}')
    print(f'{b},{b.requires_grad}')
    print(a.data_ptr() == b.data_ptr())
# tensor([1., 2., 3.]),False
# tensor([1., 2., 3.]),False
# True

需要注意的是,在上面这个示例中原来a的requires_grad是True的,但是在设置copy=False的情况下,a和b共享内存,结果a的requires_grad变成了False。

    a = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
    b = torch.asarray(a, copy=True)
    print(f'{a},{a.requires_grad}')
    print(f'{b},{b.requires_grad}')
    print(a.data_ptr() == b.data_ptr())
# tensor([1., 2., 3.], requires_grad=True),True
# tensor([1., 2., 3.]),False
# False

当设置copy=True时,则a和b不共享内存,此时发现a的requires_grad也有被影响。

(3) torch.as_tensor(data, dtype=None, device=None)

把一个数据转换为tensor,并且尽可能的共享数据和保留自动梯度历史。data可以是list, tuple, Numpy ndarray, scalar和其他类型。
比如,如果原来是numpy的array类型,如果转换后的dtype和device和转换之前一样的话,那么就共享数据;但是如果转换后的dtype和device的需求和转换之前不一样,那么就不共享数据,重新开辟内存。
示例

    a = numpy.array([1, 2, 3])
    b = torch.as_tensor(a)
    print(a)
    print(b)
    b[0] = 0
    print(a)
    print(b)
# [1 2 3]
# tensor([1, 2, 3], dtype=torch.int32)
# [0 2 3]
# tensor([0, 2, 3], dtype=torch.int32)
    a = numpy.array([1, 2, 3])
    b = torch.as_tensor(a, dtype=torch.float32)
    print(a)
    print(b)
    b[0] = 0
    print(a)
    print(b)
# [1 2 3]
# tensor([1., 2., 3.])
# [1 2 3]
# tensor([0., 2., 3.])
    a = numpy.array([1, 2, 3])
    b = torch.as_tensor(a, device=torch.device('cuda:0'))
    print(a)
    print(b)
    b[0] = 0
    print(a)
    print(b)
# [1 2 3]
# tensor([1, 2, 3], device='cuda:0', dtype=torch.int32)
# [1 2 3]
# tensor([0, 2, 3], device='cuda:0', dtype=torch.int32)

同样,如果原始数据是tensor类型的,如果使用torch.as_tensor要求得到的新tensor和原来的tensor的dtype以及device都一致,则返回原来的tensor;如果不一致,则开辟新内存,复制成新的tensor。
示例

    a = torch.tensor([1, 2, 3])
    b = torch.as_tensor(a)
    print(a)
    print(b)
    b[0] = 0
    print(a)
    print(b)
    print(a.data_ptr() == b.data_ptr())
# tensor([1, 2, 3])
# tensor([1, 2, 3])
# tensor([0, 2, 3])
# tensor([0, 2, 3])
# True
    a = torch.tensor([1, 2, 3], dtype=torch.float32)
    b = torch.as_tensor(a, dtype=torch.float64)
    print(a)
    print(b)
    b[0] = 0
    print(a)
    print(b)
    print(a.data_ptr() == b.data_ptr())
# tensor([1., 2., 3.])
# tensor([1., 2., 3.], dtype=torch.float64)
# tensor([1., 2., 3.])
# tensor([0., 2., 3.], dtype=torch.float64)
# False

(4) torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

start是开始的值,默认为0(能取到);end是结束的值(取不到),step是步幅。返回一个从区间[start, end)中,按照步幅step取的数。
示例

    variable = torch.arange(10)
    print(variable)
# tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    variable = torch.arange(1, 10)
    print(variable)
# tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])
    variable = torch.arange(1, 10, 0.5)
    print(variable)
# tensor([1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000, 4.0000, 4.5000, 5.0000,
#         5.5000, 6.0000, 6.5000, 7.0000, 7.5000, 8.0000, 8.5000, 9.0000, 9.5000])

(5) torch.linspace(start, end, steps, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

创建一个一维的线性等分的tensor,start为起始值,end为终值,steps为tensor的元素总数。
示例

	variable = torch.linspace(0, 10, steps=4)
    print(variable)
# tensor([ 0.0000,  3.3333,  6.6667, 10.0000])
	variable = torch.linspace(0, 10, steps=1)
    print(variable)
# tensor([0.])

(6) torch.logspace(start, end, steps, base=10.0, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

创建一个一维的对数等分的tensor,start为起始值的指数,end为终值的指数,steps为元素的个数。其中指数是线性等分的。
示例

    variable = torch.logspace(0, 2, steps=5)
    print(variable)
# tensor([  1.0000,   3.1623,  10.0000,  31.6228, 100.0000])
    variable = torch.logspace(0, 2, steps=1)
    print(variable)
# tensor([1.])

(7) torch.eye(n, m=None, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

返回一个对角为1,其余为0的二维张量。 n为行数,m默认和n一致。
示例

    variable = torch.eye(4)
    print(variable)
# tensor([[1., 0., 0., 0.],
#         [0., 1., 0., 0.],
#         [0., 0., 1., 0.],
#         [0., 0., 0., 1.]])
    variable = torch.eye(4, 3)
    print(variable)
# tensor([[1., 0., 0.],
#         [0., 1., 0.],
#         [0., 0., 1.],
#         [0., 0., 0.]])

(8) torch.full(size, fill_value, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

创建一个size形状的张量,所有的元素值均为fill_value.
示例

    variable = torch.full(size=(2, 2, 2), fill_value=3.14)
    print(variable)
# tensor([[[3.1400, 3.1400],
#          [3.1400, 3.1400]],
# 
#         [[3.1400, 3.1400],
#          [3.1400, 3.1400]]])

(9) torch.polar(abs, angle, *, out=None)

根据极坐标中的幅值abs和角度angle,构建笛卡尔坐标系中对应的复数。其中,abs和angle对应的类型应该一致,要么都是torch.float32,要么都是torch.float64. 如果都是torch.float32,那么产生的复数类型是torch.complex64;如果都是torch.float64,那么产生的复数类型是torch.complex128.
示例

    abs = torch.tensor([1, 2], dtype=torch.float64)
    angle = torch.tensor([numpy.pi / 2, 5 / 4 * numpy.pi], dtype=torch.float64)
    z = torch.polar(abs, angle)
    print(z)
# tensor([ 6.1232e-17+1.0000j, -1.4142e+00-1.4142j], dtype=torch.complex128)

(10) torch.heaviside(input, values, *, out=None)

对input中的每一个元素计算海维赛德阶跃函数。海维赛德阶跃函数的定义是,如果输入值小于0,则输出0;如果输入值等于0,则输出values;如果输入值大于0,则输出1. input 和 values都要求是浮点类型。
示例

	input = torch.tensor([-0.6, 5, 0.3, 0, 2.1, -2.2, 0])
    values = torch.tensor([0.5])
    variable = torch.heaviside(input=input, values=values)
    print(variable)
# tensor([0.0000, 1.0000, 1.0000, 0.5000, 1.0000, 0.0000, 0.5000])

6. Tensor Operations

(1) torch.adjoint(Tensor)

首先将tensor中的每一个元素取共轭,然后将tensor最后两个维度转置。对于二维的复数tensor来说,这个操作就相当于共轭转置;对于二维的实数tensor来说,这个操作就相当于转置。
示例

    real = torch.arange(1, 7, dtype=torch.float32)
    imag = torch.linspace(1, 10, 6, dtype=torch.float32)
    variable = torch.complex(real, imag).reshape(3, 2)
    print(variable)
    new_variable = torch.adjoint(variable)
    print(new_variable)
# tensor([[1.+1.0000j, 2.+2.8000j],
#         [3.+4.6000j, 4.+6.4000j],
#         [5.+8.2000j, 6.+10.0000j]])
# tensor([[1.-1.0000j, 3.-4.6000j, 5.-8.2000j],
#         [2.-2.8000j, 4.-6.4000j, 6.-10.0000j]])

(2) torch.argwhere(input)

将输入张量中的非零元素的索引坐标全部输出出来,形成一个新的tensor。新tensor的形状为 z × n z\times n z×n z z z为非零元素的个数, n n n为每个每个非零元素对应的坐标的维数。
示例

    data = torch.tensor([[1.0, 0.0, 3.0], [0.0, 0.0, 5.0]])
    variable = torch.argwhere(data)
    print(variable)
# tensor([[0, 0],
#         [0, 2],
#         [1, 2]])

(3) torch.cat(tensors, dim=0, *, out=None)

将所给的tensor序列在指定的维度上连接起来。所有的tensor必须形状相同(除了所指定的连接维度上可以不同)或为空。
torch.cat, torch.concat 和 torch.concatenate这三个是一样的。
示例

    data1 = torch.tensor([[0, 1, 2], [3, 4, 5]])
    data2 = torch.tensor([[6, 7, 8], [9, 10, 11]])
    data3 = torch.tensor([[12, 13, 14], [15, 16, 17]])
    variable1 = torch.cat((data1, data2, data3), 0)
    print(variable1)
    variable2 = torch.cat((data1, data2, data3), 1)
    print(variable2)
# tensor([[ 0,  1,  2],
#         [ 3,  4,  5],
#         [ 6,  7,  8],
#         [ 9, 10, 11],
#         [12, 13, 14],
#         [15, 16, 17]])
# tensor([[ 0,  1,  2,  6,  7,  8, 12, 13, 14],
#         [ 3,  4,  5,  9, 10, 11, 15, 16, 17]])

(4) torch.conj(input)

返回输入tensor的共轭。
示例

    real = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32)
    imag = torch.tensor([0.5, 1.5, 2.5], dtype=torch.float32)
    data = torch.complex(real, imag)
    conj = torch.conj(data)
    print(data)
    print(conj)
# tensor([1.+0.5000j, 2.+1.5000j, 3.+2.5000j])
# tensor([1.-0.5000j, 2.-1.5000j, 3.-2.5000j])

(5) torch.chunk(input, chunks, dim=0)

将输入的tensor划分为特定数量chunks的块。但是不一定最后划分的块数就是chunks,也不一定每一个chunk的元素个数都是一样的。
示例

    data1 = torch.arange(1, 12)
    data2 = torch.arange(1, 13)
    data3 = torch.arange(1, 14)
    data = torch.tensor([[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]])
    c1 = torch.chunk(data1, 6)
    c2 = torch.chunk(data2, 6)
    c3 = torch.chunk(data3, 6)
    c = torch.chunk(data, 2)
    print(c1)
    print(c2)
    print(c3)
    print(c)
# (tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11]))
# (tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11, 12]))
# (tensor([1, 2, 3]), tensor([4, 5, 6]), tensor([7, 8, 9]), tensor([10, 11, 12]), tensor([13]))
# (tensor([[1, 2, 3, 4, 5, 6]]), tensor([[ 7,  8,  9, 10, 11, 12]]))

在划分之后,得到的新的tensor中的数据与原tensor是共享内存的。

    data = torch.arange(1, 12)
    c = torch.chunk(data, 6)
    q = c[0]
    print(data)
    print(c)
    print(q)
    q[0] = 5
    print(data)
    print(c)
    print(q)
# tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
# (tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11]))
# tensor([1, 2])
# tensor([ 5,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
# (tensor([5, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11]))
# tensor([5, 2])

可以用前面提到的torch.asarray阻值这种内存共享,示例如下

    data = torch.arange(1, 12)
    c = torch.chunk(data, 6)
    q = torch.asarray(c[0], copy=True)
    print(data)
    print(c)
    print(q)
    q[0] = 5
    print(data)
    print(c)
    print(q)
# tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
# (tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11]))
# tensor([1, 2])
# tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
# (tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]), tensor([ 9, 10]), tensor([11]))
# tensor([5, 2])

(6) torch.narrow(input, dim, start, length)

返回一个对input沿着dim维,从start位置划分length长度的新tensor。新tensor与旧tensor共享内存。
示例

    data = torch.arange(32.0).reshape(2, 1, 4, 4)
    variable = torch.narrow(data, 3, 1, 2)
    print(data)
    print(variable)
    variable[0][0][0][0] = 100
    print(data)
    print(variable)
'''
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.],
          [24., 25., 26., 27.],
          [28., 29., 30., 31.]]]])
tensor([[[[ 1.,  2.],
          [ 5.,  6.],
          [ 9., 10.],
          [13., 14.]]],


        [[[17., 18.],
          [21., 22.],
          [25., 26.],
          [29., 30.]]]])
tensor([[[[  0., 100.,   2.,   3.],
          [  4.,   5.,   6.,   7.],
          [  8.,   9.,  10.,  11.],
          [ 12.,  13.,  14.,  15.]]],


        [[[ 16.,  17.,  18.,  19.],
          [ 20.,  21.,  22.,  23.],
          [ 24.,  25.,  26.,  27.],
          [ 28.,  29.,  30.,  31.]]]])
tensor([[[[100.,   2.],
          [  5.,   6.],
          [  9.,  10.],
          [ 13.,  14.]]],


        [[[ 17.,  18.],
          [ 21.,  22.],
          [ 25.,  26.],
          [ 29.,  30.]]]])
'''

同样,如果不想共享内存的话可以利用torch.asarray

variable = torch.asarray(torch.narrow(data, 3, 1, 2), copy=True)

(7) torch.permute(input, dims)

这个函数用于交换不同维度上的形状。比如说input的形状是(5, 2, 3),执行permute设置dims=(2, 0, 1),就表示原来第2个维度上的形状3现在要放到第0个维度上,原来维度0上的形状5现在要放到第1个维度上,原来第1个维度上的形状2现在要放到第2个维度上。这样,变换之后的新形状就是(3, 5, 2). 同样,新生成的tensor和原tensor是共享内存的。
示例

    data = torch.arange(30.0).reshape(5, 2, 3)
    print(data.shape)
    data = data.permute(2, 0, 1)
    print(data.shape)
# torch.Size([5, 2, 3])
# torch.Size([3, 5, 2])

你可能感兴趣的:(Pytorch,pytorch,深度学习,人工智能)