2021动手学深度学习笔记pytorch版本--2.1预备知识

  深度学习小白一枚,最近在看李沐的动手学深度学习(2021版本),一些代码感觉看不太懂,于是写个博客记录下代码的一些个人理解,也方便后续复习。

2.1数据操作

2.1.1入门


import torch
x = torch.arange(12)
x
#结果:tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

这里的张量我理解的就是一个’数组‘,一维是向量,二维是矩阵。torch.arange(12)创建一个大小为12的向量。

x.shape
#结果:torch.Size([12])
x.numel()
#结果:12

x.shape查看张量x每一个维度所包含元素的个数。x.numel()查看所有的元素个数。

X = x.reshape(3, 4)
X
#结果:tensor([[ 0,  1,  2,  3],
#              [ 4,  5,  6,  7],
#              [ 8,  9, 10, 11]])

改变张量x的形状,也可以用x.reshape(-1,4)或x.reshape(3,-1),给出一个维度之后会自动计算出另一个维度。注意此时x应该是一个维矩阵了。

torch.zeros((2, 3, 4))
#结果:
#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.]]])
torch.ones((2, 3, 4))
#结果:
#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.]]])

torch.zero&torch.ones分别生成全0和全1矩阵,第一个参数表示高度(样本个数),后两个参数表示高度和宽度。注意此时生成的应该是维的数组。

torch.randn(3, 4)
#结果:
# tensor([[-0.9464,  0.7712, -0.0070,  1.0236],
#        [-2.1246, -0.7854, -1.9674, -0.1727],
#        [ 0.0397, -0.0477, -0.0160, -0.0113]])

创建一个3行4列,每个元素都从均值为0、标准差为1的标准高斯(正态)分布中随机采样的张量。

torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
#结果:
# tensor([[2, 1, 4, 3],
#        [1, 2, 3, 4],
#        [4, 3, 2, 1]])

手动输入参数创建张量(3行4列)。

2.1.2运算


x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y  # **运算符是求幂运算
#结果: (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.]))

加减乘除比较简单,相对应的元素相加减乘除就可以。注意x**y是求幂运算。

torch.exp(x)
#结果:tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

对张量x进行幂指数运算。

X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)

#(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.]]))

张量连结(concatenate),这里分别将X和Y按行(轴0)和按列(轴1)连结在一起,这里为什么行是轴0,列是轴1呢?因为最开始创建的一维张量是一个行向量。按轴0,那就是两个张量按行连结列数不变共6行,按列就是行数不变共8列。

X==Y

# tensor([[False,  True, False,  True],
#        [False, False, False, False],
#        [False, False, False, False]])

逻辑运算符构建一个张量,里面应该都是布尔型元素。

X.sum()

#tensor(66.)

对张量中所有元素进行求和。

2.1.3.广播机制

a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b

#(tensor([[0],
#         [1],
#         [2]]),
# tensor([[0, 1]]))
a+b

# tensor([[0, 1],
#         [1, 2],
#         [2, 3]])

广播机制。比如两个形状不同的张量相加,先各自将张量复制成能互相相加的形状,然后再相加。

2.1.4.索引和切片

X[-1], X[1:3]

#(tensor([ 8.,  9., 10., 11.]),
# tensor([[ 4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11.]]))

很简单的python语法,注意python中下标是从0开始,一般最后一个下边不被包含在其中。

X[1, 2] = 9
X

#tensor([[ 0.,  1.,  2.,  3.],
#        [ 4.,  5.,  9.,  7.],
#        [ 8.,  9., 10., 11.]])
X[0:2, :] = 12
X

#tensor([[12., 12., 12., 12.],
#        [12., 12., 12., 12.],
#        [ 8.,  9., 10., 11.]])

通过指定索引将元素写入矩阵。

2.1.5.节省内存

before = id(Y)
Y = Y + X
id(Y) == before

#False

引用Y=Y+X会为Y开辟一个新地址,可能会造成资源浪费,而且更新时可能会引用旧的地址的值,造成错误。可以用id()来查询其确切地址。

Z = torch.zeros_like(Y)
print('id(Z):', id(Z))
Z[:] = X + Y
print('id(Z):', id(Z))

#id(Z): 140272150341696
#id(Z): 140272150341696
before = id(X)
X += Y
id(X) == before

#True

切片表示法分配给之前准备好的数组Z,也可以直接就用Y[:]。或者用+=。

2.1.6.转换为其他Python对象

A = X.numpy()
B = torch.tensor(A)
type(A), type(B)

#(numpy.ndarray, torch.Tensor)

张量和numpy库中的数组进行转换之后不共享地址。

a = torch.tensor([3.5])
a, a.item(), float(a), int(a)

#(tensor([3.5000]), 3.5, 3.5, 3)

要将大小为1的张量转换为Python标量,我们可以调用item函数或Python的内置函数。

你可能感兴趣的:(深度学习,神经网络,机器学习)