动手学习深度学习-数据操作

# 创建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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值