# 创建tensor
import torch
# 创建5x3的未初始化的tensor
x = torch.empty(5,3)
print(x)
"""
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
"""
# 创建5x3的随机初始化的tensor
x = torch.rand(5,3)
print(x)
"""
tensor([[0.1924, 0.6229, 0.6194],
[0.7246, 0.8463, 0.2863],
[0.6315, 0.7640, 0.6690],
[0.1290, 0.5583, 0.6592],
[0.6149, 0.1370, 0.6620]])
"""
# 创建5x3的long型全0的tensor
x = torch.zeros(5,3,dtype=torch.long)
print(x)
"""
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
"""
# 直接创建数据tensor
x = torch.tensor([5.5,3])
print(x) # tensor([5.5000, 3.0000])
# 还可以通过现有的tensor来创建,此方法会默认重用输入tensor的一些属性,例如数据类型,除非自定义数据类型
x = x.new_ones(5,3,dtype = torch.float64) # 返回的tensor默认具有相同的torch.dtype和torch.device
print(x)
"""
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
"""
x = torch.randn_like(x,dtype = torch.float) # 指定新的数据类型
print(x)
"""
tensor([[ 0.2725, 0.9438, -2.3053],
[-0.0412, 0.7210, 1.1887],
[ 1.0555, 0.9503, 0.2940],
[-0.3706, -1.5824, 0.1490],
[ 1.5537, -0.0995, 0.0629]])
"""
# 可以通过shape或者size来获取tensor的形状-返回的是一个元组,支持所有的元组操作
print(x.size()) # torch.Size([5, 3])
print(x.shape) # torch.Size([5, 3])
# 常见的函数
"""
Tensor(*sizes)-基础构造函数
tensor(data)-类似np.array的构造函数
ones(*sizes)-全1tensor
zeros(*sizes)-全0tensor
eye(*sizes)-对角线为1,其余为0
arange(s,e,step)-从s到e,步长为step
linspace(s,e,steps)-从s到e,均匀分成steps份
"""
# 操作
# 1、算数操作
# 加法形式一
# y = torch.rand(5,3)
# print(x + y)
#
# # 加法形式二
# print(torch.add(x,y))
# # 还可以指定输出
# result = torch.empty(5,3)
# torch.add(x,y,out = result)
# print(result)
#
# # 加法形式三-inplace
# # add x to y
# y.add_(x)
# print(y)
# 索引
"""
我们还可以使用类似numpy的索引操作来访问tensor的一部分,需要注意的是:索引出来的结果与原数据共享内存,
也即修改一个,另一个会跟着修改
"""
y = x[0,:]
y += 1
print(y)
print(x[0,:]) # 源tensor也被改了
# 改变形状-使用view()来改变tensor的形状
y = x.view(15)
z = x.view(-1,5) # -1所指的维度可以根据其他维度的值推出来
print(x.size(),y.size(),z.size()) # torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
# 注意:view()返回的新tensor与源tensor共享内存(其实是同一个tensor),也即更改其中一个,另外一个也会跟着改变。
x += 1
print(x)
"""
tensor([[ 3.0034, 1.3416, 2.8765],
[ 0.3527, 2.2212, 1.4778],
[ 0.0205, 0.8304, 1.0855],
[-0.0095, 0.3674, 0.9666],
[ 1.0863, -1.9625, 1.9530]])
"""
print(y) # 也加1
"""
tensor([ 3.0034, 1.3416, 2.8765, 0.3527, 2.2212, 1.4778, 0.0205, 0.8304,
1.0855, -0.0095, 0.3674, 0.9666, 1.0863, -1.9625, 1.9530])
"""
"""
所以如果我们想返回一个真正的新副本(即不共享内存)该怎么办呢?pytorch还提供了一个reshape()可以改变形状,但是此函数并不能保证
返回的是其拷贝,所以不推荐使用,推荐先使用clone创造一个副本再使用view()
"""
x_cp = x.clone().view(15)
x -= 1
print(x)
"""
tensor([[ 0.6201, 0.2167, 0.6688],
[ 0.2767, 0.4309, 1.4564],
[-0.5027, 2.0011, -0.0314],
[-0.7101, 1.5521, 0.6628],
[ 1.4525, -1.1346, -0.7665]])
"""
print(x_cp)
"""
tensor([ 1.6201, 1.2167, 1.6688, 1.2767, 1.4309, 2.4564, 0.4973, 3.0011,
0.9686, 0.2899, 2.5521, 1.6628, 2.4525, -0.1346, 0.2335])
"""
# 使用clone还有一个好处就是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor
# 另外一个常用的函数就是item(),它可以将一个标量Tensor转换成一个python number
x = torch.randn(1)
print(x) # tensor([0.1865])
print(x.item()) # 0.18651612102985382
# 广播机制
# 当两个形状不相同的tensor按元素运算时,可能会触发广播机制,先适当复制元素使这两个tensor形状相同后再按元素运算
x = torch.arange(1,3).view(1,2)
print(x) # tensor([[1, 2]])
y = torch.arange(1,4).view(3,1)
print(y)
"""
tensor([[1],
[2],
[3]])
"""
print(x + y)
"""
tensor([[2, 3],
[3, 4],
[4, 5]])
"""
# 运算的内存开销
# 索引、view是不会开辟新的内存,而像y = x + y这样的运算会新开内存的,然后将y指向新内存,例如下面:
x = torch.tensor([1,2])
y = torch.tensor([3,4])
id_before = id(y)
y = y + x
print(id(y) == id_before) # False
# 如果想指定结果到原来的y内存,我们可以使用前面介绍的索引来进行替换操作,例如:
x = torch.tensor([1,2])
y = torch.tensor([3,4])
id_before = id(y)
y[:] = y + x
print(id(y) == id_before) # True
# 还可以使用运算符全名函数中的out参数或者自加运算符+=(也即add_())达到上述的效果,例如:
x = torch.tensor([1,2])
y = torch.tensor([3,4])
id_before = id(y)
torch.add(x,y,out = y) # y += x,y.add_(x)
print(id(y) == id_before) # True
# tesor和numpy相互转换
"""
我们可以使用numpy()和from_numpy()将tensor和numpy中的数组互换,但是需要注意:
这两个函数所产生的tensor和numpy中的数组共享相同的内存(所以它们之间的转换很快),改变其中一个另外一个也会改变
还有一个将numpy中的array转换为tensor的方法就是torch.tensor(),需要注意的是:此方法会进行数据拷贝(就会消更多的时间和空间)
,所以返回的tensor和原来的数据不再共享内存
"""
# tensor转numpy
a = torch.ones(5)
b = a.numpy() # tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
print(a,b)
a += 1
print(a,b) # # tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
b += 1
print(a + b) # tensor([6., 6., 6., 6., 6.])
# numpy数组转换tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
print(a,b) # [1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
a += 1
print(a,b) # [2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
b += 1
print(a,b) # [3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
# 不共享内存
c = torch.tensor(a)
a += 1
print(a,c) # [4. 4. 4. 4. 4.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
动手学习深度学习-数据操作
最新推荐文章于 2023-01-16 17:00:39 发布