深度学习之数据操作
1.N维数组是机器学习和神经网络的主要数据结构
样本
特征
2.创建数组
数组要素:形状例如3*4矩阵
每个元素的数据类型
每个元素的值
访问元素
数据操作
打开Anaconda-进入 jupyter-notebook
找到chapter2_preliminaries/ndarray.ipynb就可以看到准备好的代码
首先
import torch(torch不是pytorch)
张量表示一个数值组成的数组,这个数组可能有多个维度
具有一个轴的张量对应数学上的向量(vector); 具有两个轴的张量对应数学上的矩阵(matrix); 具有两个轴以上的张量没有特殊的数学名称。
1.首先,我们可以使用 arange
创建一个行向量 x
。这个行向量包含以0开始的前12个整数,它们默认创建为整数。也可指定创建类型为浮点数。张量中的每个值都称为张量的 元素(element)。例如,张量 x
中有 12 个元素。除非额外指定,新的张量将存储在内存中,并采用基于CPU的计算。
x = torch.arange(12)
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
2. 张量的shape
属性来访问张量(沿每个轴的长度)的形状
如果只想知道张量中元素的总数,即形状的所有元素乘积,可以检查它的大小(size)。 因为这里在处理的是一个向量,所以它的shape
与它的size
相同。
3.reshape 函数可以改变一个张量的形状而不改变元素数量和元素值
我们不需要手动指定每个维度来改变形状,只需要指定一个另一个用-1代替。例如x.reshape(3,4)就等同于x.reshape(3,-1)
4.torch.zeros((2,3,4)) 意味着创建一个形状为(2,3,4)的张量,其中所有元素都设置为0。来进行初始化矩阵
torch.one((2,3,4)) 意味着创建一个形状为(2,3,4)的张量,其中所有元素都设置为1。来进行初始化矩阵
torch.random(3,4)随机初始化参数的值从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样。
torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]]) [通过提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值
运算符
对数据元素进行算术操作 常见的标准算术运算符(+、-、*、/和**)都可以被升级为按元素运算] exp(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.]]))''' X == Y # 逻辑运算符 '''tensor([[False, True, False, True], [False, False, False, False], [False, False, False, False]])''' X.sum() # 求和
广播机制
通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状; 对生成的数组执行按元素操作。
a = torch.arange(3).reshape((3, 1)) b = torch.arange(2).reshape((1, 2)) a, b a + b '''(tensor([[0], [1], [2]]), tensor([[0, 1]]))
tensor([[0, 1], [1, 2], [2, 3]])'''
索引和切片
就像在任何其他Python数组中一样,张量中的元素可以通过索引访问
除读取外,我们还可以通过指定索引来将元素写入矩阵
为多个元素赋值相同的值,我们只需要索引所有元素,然后为它们赋值。
节省内存(运行一些操作可能会导致为新结果分配内存)
首先,我们不想总是不必要地分配内存。在机器学习中,我们可能有数百兆的参数,并且在一秒内多次更新所有参数。通常情况下,我们希望原地执行这些更新; 如果我们不原地更新,其他引用仍然会指向旧的内存位置,这样我们的某些代码可能会无意中引用旧的参数。 幸运的是,(执行原地操作)非常简单。 我们可以使用切片表示法将操作的结果分配给先前分配的数组,例如Y[:] = <expression>
。 如果想避免这个临时开销,可以使用运算符全名函数中的out 参数 如果X的值在之后的程序中不会复用,我们也可以用下X[:]=X+Y或者X+=Y来减少内存开销!