02.1、数据操作
文章目录
- 2.1 数据操作
- 2.1.1 入门
- 2.1.2 运算符
- 2.1.3. 广播机制
- 2.1.4. 索引和切片
- 2.1.5. 节省内存
- 2.1.6. 转换为其他Python对象
- 2.1.7. 小结
2.1 数据操作
- 获取数据
- 将数据读入计算机后对其进行处理
2.1.1 入门
0、下载torch
pip3 install torch # 默认最新版
pip3 install torch==0.8 # 下载指定版本的torch
1、导入torch
虽然它被称为PyTorch,但是代码中使用torch而不是pytorch。
import torch
- 张量表示由一个数值组成的数组,这个数组可能有多个维度
- 具有一个轴的张量对应数学上的向量(vector)
- 具有两个轴的张量对应数学上的矩阵(matrix)
- 具有两个轴以上的张量没有特殊的数学名称。
2、arange创建一个行向量x
x = torch.arange(12)
x
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
张量的shape属性来访问张量(沿每个轴的长度)的形状
x.shape
torch.Size([12])
只想知道张量中元素的总数,即形状的所有元素乘积,可以检查它的大小(size)。 因为这里在处理的是一个向量,所以它的shape与它的size相同。
x.numel()
12
3、reshape
改变一个张量的形状而不改变元素数量和元素值
X = x.reshape(3, 4)
X
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
可以通过-1来调用此自动计算出维度的功能,用x.reshape(-1,4)或x.reshape(3,-1)来取代x.reshape(3,4)。
4、初始化矩阵
希望使用全0、全1、其他常量,或者从特定分布中随机采样的数字来初始化矩阵。
- 创建一个形状为(2,3,4)的张量,其中所有元素都设置为0
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.]]])
- 创建一个形状为(2,3,4)的张量,其中所有元素都设置为1
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.]]])
- 创建一个形状为(3,4)的张量。 其中的每个元素都从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样
torch.randn(3, 4)
tensor([[-0.5979, 0.6042, -1.1094, -0.9001],
[ 1.3877, 0.1119, 0.2164, 0.7615],
[-0.6081, -0.2789, -0.7933, 0.7229]])
- Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值
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]])
2.1.2 运算符
- 按元素运算
- 标准算术运算符(+、-、*、/和**)
1、标准运算
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.]))
2、求幂一元运算符
torch.exp(x)
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])
3、矩阵连接方式
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.]]))
沿行(轴-0,形状的第一个元素) 和按列(轴-1,形状的第二个元素)连结两个矩阵
4、逻辑运算符构建二元张量
- 逻辑语句X == Y在该位置处为真,否则该位置为0。
X == Y
tensor([[False, True, False, True],
[False, False, False, False],
[False, False, False, False]])
- 张量中的所有元素进行求和,会产生一个单元素张量
X.sum()
tensor(66.)
2.1.3. 广播机制
广播机制(broadcasting mechanism):
- 首先,通过适当复制元素来扩展一个或两个数组, 以便在转换之后,两个张量具有相同的形状。
- 其次,对生成的数组执行按元素操作。
在大多数情况下,我们将沿着数组中长度为1的轴进行广播
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. 索引和切片
- 第一个元素的索引是0,最后一个元素索引是-1
- 指定范围以包含第一个元素和最后一个之前的元素
1、 [-1]选择最后一个元素,可以用[1:3]选择第二个和第三个元素:
X[-1], X[1:3]
(tensor([ 8., 9., 10., 11.]),
tensor([[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]]))
2、指定索引来将元素写入矩阵
X[1, 2] = 9
X
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]])
3、为多个元素赋值相同的值
X[0:2, :] = 12
X
tensor([[12., 12., 12., 12.],
[12., 12., 12., 12.],
[ 8., 9., 10., 11.]])
2.1.5. 节省内存
- Python的id() 查看内存地址
before = id(Y)
Y = Y + X
id(Y) == before
False
- 执行原地操作,使用切片表示法将操作的结果分配给先前分配的数组
Z = torch.zeros_like(Y)
print('id(Z):', id(Z))
Z[:] = X + Y
print('id(Z):', id(Z))
id(Z): 140622147537312
id(Z): 140622147537312
- 如果在后续计算中没有重复使用X, 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销。
before = id(X)
X += Y
id(X) == before
True
2.1.6. 转换为其他Python对象
1、 张量转换NumPy张量(ndarray)
A = X.numpy()
B = torch.tensor(A)
type(A), type(B)
(numpy.ndarray, torch.Tensor)
2、张量转换为Python标量
调用item函数或Python的内置函数。
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
(tensor([3.5000]), 3.5, 3.5, 3)
2.1.7. 小结
深度学习存储和操作数据的主要接口是张量(维数组)。
它提供了各种功能,包括基本数学运算、广播、索引、切片、内存节省和转换其他Python对象