二、预备知识—pytorch数据基本操作

2.1 数据操作

为了能够完成各种数据操作,我们需要某种方法来存储和操作数据。 通常,我们需要做两件重要的事:(1)获取数据;(2)将数据读入计算机后对其进行处理。 如果没有某种方法来存储数据,那么获取数据是没有意义的。
首先,我们介绍维数组,也称为张量(tensor)。 使用过Python中NumPy计算包的读者会对本部分很熟悉。 无论使用哪个深度学习框架,它的张量类(在MXNet中为ndarray, 在PyTorch和TensorFlow中为Tensor)都与Numpy的ndarray类似。 但深度学习框架又比Numpy的ndarray多一些重要功能: 首先,GPU很好地支持加速计算,而NumPy仅支持CPU计算; 其次,张量类支持自动微分。 这些功能使得张量类更适合深度学习。 如果没有特殊说明,本书中所说的张量均指的是张量类的实例。–《动手学深度学习》

2.1.1 代码操作实例

一、

x = torch.arange(12)  # 创建一个含有12个元素的行向量
print(x)  # 输出创建的张量,张量表示由一个数值组成的数组,这个数组可能有多个维度
print(x.shape)  # 通过张量的shape属性来访问张量(沿每个轴的长度)的形状
print(x.numel())  # 张量中元素的总数

输出:

tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
torch.Size([12])
12

二、

X = x.reshape(3, 4)  # 将x从行向量转变为3行4列的矩阵,还可以通过x.reshape(3,-1)或者x.reshape(-1,4)让torch自动计算
print(X)

输出:

tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])

四、

y = torch.zeros((2, 3, 4))  # 创建一个形状为(2,3,4)的张量,其中所有元素都设置为0,第一个参数代表创建几个3行4列的矩阵
print(y)
z = torch.ones((2, 3, 4))  # 创建一个形状为(2,3,4)的张量,其中所有元素都设置为1,第一个参数代表创建几个3行4列的矩阵
print(z)

输出:

tensor([[[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]],

        [[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]]])
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])

五、

a = torch.randn(3, 4)  # 每个元素都从均值为0、标准差为1的标准高斯分布(正态分布(Normal distribution))中随机采样
print(a)

输出:

tensor([[-0.1024,  0.1142, -0.6478, -0.0730],
        [ 0.4957,  0.1379,  0.1367, -0.6389],
        [ 0.3903,  0.0232,  1.1764, -0.0586]])

六、

# 通过提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值。 在这里,最外层的列表对应于轴0,内层的列表对应于轴1
b = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(b)

输出:

tensor([[2, 1, 4, 3],
        [1, 2, 3, 4],
        [4, 3, 2, 1]])

七、

# 可以在同一形状的任意两个张量上调用按元素操作
c = torch.tensor([1.0, 2, 4, 8])
d = torch.tensor([2, 2, 2, 2])
print(c + d)  # 加法
print(c - d)  # 减法
print(c * d)  # 乘法
print(c / d)  # 除法
print(c ** d)  # 求幂运算
print(torch.exp(c))  # c的e次幂

输出:

tensor([ 3.,  4.,  6., 10.])
tensor([-1.,  0.,  2.,  6.])
tensor([ 2.,  4.,  8., 16.])
tensor([0.5000, 1.0000, 2.0000, 4.0000])
tensor([ 1.,  4., 16., 64.])
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

八、

# 可以把多个张量连结(concatenate)在一起, 把它们端对端地叠起来形成一个更大的张量
e = torch.arange(12, dtype=torch.float32).reshape(3, 4)
f = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(torch.cat((e, f), dim=0))  # 沿行(轴-0,形状的第一个元素)连结两个矩阵,输出张量的轴-0长度(6)是两个输入张量轴-0长度的总和(3+3)
print(torch.cat((e, f), dim=1))  # 按列(轴-1,形状的第二个元素)连结两个矩阵,输出张量的轴-1长度(8)是两个输入张量轴-1长度的总和(4+4)

输出:

tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [ 2.,  1.,  4.,  3.],
        [ 1.,  2.,  3.,  4.],
        [ 4.,  3.,  2.,  1.]])
tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],
        [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],
        [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]])

九、

print(e == f)  # 对于每个位置,如果X和Y在该位置相等,则新张量中相应项的值为1,这意味着逻辑语句e == f在该位置处为真,否则该位置为0,意味着假
print(e.sum())  # 对张量中的所有元素进行求和,会产生一个单元素张量

输出:

tensor([[False,  True, False,  True],
        [False, False, False, False],
        [False, False, False, False]])
tensor(66.)

十、

# 广播机制
# 工作方式如下:首先,通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状.其次,对生成的数组执行按元素操作
g = torch.arange(3).reshape((3, 1))
h = torch.arange(2).reshape((1, 2))
# 由于a和b分别是和矩阵,如果让它们相加,它们的形状不匹配.我们将两个矩阵广播为一个更大的矩阵,如下所示:矩阵a将复制列,矩阵b将复制行,然后再按元素相加
print(g)
print(h)
print(g + h)

输出:

tensor([[0],
        [1],
        [2]])
# 相当于复制成
# tensor([[0, 0],
#        [1, 1],
#        [2, 2]])
tensor([[0, 1]])
# 相当于复制成
# tensor([[0, 1], [0, 1], [0, 1]])
tensor([[0, 1],
        [1, 2],
        [2, 3]])

十一、

# 索引与切片
print(x[-1])  # 最后一个元素索引是-1
print(x[1:3])  # 用[1:3]选择第二个和第三个元素
b[1, 2] = 9  # 通过指定索引来将元素写入矩阵
print(b)
i = torch.arange(12).reshape(3, 4)
j = torch.arange(12).reshape(3, 4)
i[0:2, :] = 12  # 按列的方向修改,实际是修改1,2行
j[:, 0:2] = 12  # 按行的方向修改,实际是修改1,2列
print(i)
print(j)

输出:

tensor(11)
tensor([1, 2])
tensor([[2, 1, 4, 3],
        [1, 2, 9, 4],
        [4, 3, 2, 1]])
tensor([[12, 12, 12, 12],
        [12, 12, 12, 12],
        [ 8,  9, 10, 11]])
tensor([[12, 12,  2,  3],
        [12, 12,  6,  7],
        [12, 12, 10, 11]])

十二、

# 原地操作的方式:1.Y[:] =  2.X += Y
# 第一种
k = torch.zeros_like(i)
print(id(k))
k[:] = k + i
print(id(k))
# 第二种
before = id(k)
k += i
if before == id(k):
    print("true")
else:
    print("false")

输出:

1610199749248
1610199749248
true

十三、

# 将深度学习框架定义的张量转换为NumPy张量(ndarray)很容易,反之也同样容易.torch张量和numpy数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量
A = X.numpy()
B = torch.tensor(A)
print(type(A))
print(type(B))

输出:

<class 'numpy.ndarray'>
<class 'torch.Tensor'>

十四、

# 将大小为1的张量转换为Python标量,我们可以调用item函数或Python的内置函数
l = torch.tensor([3.5])
print(l)
print(l.item())
print(float(l))
print(int(l))

输出:

tensor([3.5000])
3.5
3.5
3

2.1.2 小结

  • 深度学习存储和操作数据的主要接口是张量(n维数组)。它提供了各种功能,包括基本数学运算、广播、索引、切片、内存节省和转换其他Python对象。

你可能感兴趣的:(李沐《动手学深度学习》学习笔记,pytorch,python,numpy)