教材:李沐《动手学深度学习》
一、数据操作
张量:n维数组,PyTorch中的张量类为Tensor。相比较于Numpy中的ndarray,深度学习框架具有的优势:
- GPU很好地支持加速计算,而NumPy仅支持CPU计算;
- 张量类支持自动微分。 这些功能使得张量类更适合深度学习。
(一)张量的创建
- arange创建一个行向量:
x=torch.arange(12)
- 张量的形状与大小
print(f"张量:{x}") print(f"张量形状:{x.shape}") print(f"张量大小:{x.numel()}")
- reshape改变张量形状
X=x.reshape(3,4) X
- 创建新张量
torch.ones((2,3,4))#创建全1张量 torch.zeros((2,3,4))#创建全0张量 torch.randn(3,4)#创建元素为正态分布的张量 torch.tensor([[1,2,3,4],[2,1,4,3],[4,3,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 #求幂运算 torch.exp(x)
- 线性代数运算
除了按元素计算外,我们还可以执行线性代数运算,包括向量点积和矩阵乘法。 - 张量的连结(concatenate)
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)
- 元素求和
X.sum()
- 通过逻辑运算符构建二元张量
X==Y
(三)张量的广播机制
一般情况下,张量按照元素操作要求两个张量的形状相同。当张量形状不同时,执行按元素操作需要调用广播机制(broadcasting mechanism)。广播的原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
- 两个数组的维数不相等,但是它们的后缘维度(从末尾开始算起的维度)的轴长相符;
x=torch.tensor([[0,0,0],[1,1,1],[2,2,2],[3,3,3]]) y=torch.tensor([1,2,3]) x+y
x的shape为(4,3),y的shape为(3,)。它们的后缘维度相等,x的第二维长度为3,和y的维度相同。x和y的shape并不一样,但是它们可以执行相加操作,这就是通过广播完成的,在这个例子当中是将y沿着0轴进行扩展:
从下面的图可以看到,(3,4,2)和(4,2)的维度是不相同的,前者为3维,后者为2维。但是它们后缘维度的轴长相同,都为(4,2),所以可以沿着0轴进行广播。
同样,还有一些例子:(4,2,3)和(2,3)是兼容的,(4,2,3)还和(3)是兼容的,后者需要在两个轴上面进行扩展。
- 两个数组中有一方的长度为1。
x=torch.tensor([[0,0,0],[1,1,1],[2,2,2],[3,3,3]]) y=torch.tensor([[1],[2],[3],[4]]) x+y
x的shape为(4,3),y的shape为(4,1),它们都是二维的,但是第二个数组在1轴上的长度为1,所以,可以在1轴上面进行广播,如下图所示:
在这种情况下,两个数组的维度要保证相等,其中有一个轴的长度为1,这样就会沿着长度为1的轴进行扩展。这样的例子还有:(4,6)和(1,6)。(3,5,6)和(1,5,6)、(3,1,6)、(3,5,1),后面三个分别会沿着0轴,1轴,2轴进行广播。
(四)索引和切片
- 元素读取
张量与任何其他Python数组一样,可以通过索引访问其中的元素:第一个元素的索引是0,最后一个元素索引是-1; 可以指定范围以包含第一个元素和最后一个之前的元素。#用[-1]选择最后一个元素,用[1:3]选择第二个和第三个元素 X[-1],X[1:3]
- 元素写入
除读取外,我们还可以通过指定索引来将元素写入矩阵。X[1,2]=9 X
- 为多个元素赋值相同的值
如果想为多个元素赋值相同的值,我们只需要索引所有元素,然后为它们赋值。 例如,[0:2, :]访问第1行和第2行,其中“:”代表沿轴1(列)的所有元素。 虽然我们讨论的是矩阵的索引,但这也适用于向量和超过2个维度的张量。X[0:2, :] = 12 X
(五)转换为其他Python对象
- 深度学习框架定义的张量与NumPy张量(ndarray)之间的转换
A=X.numpy() B=torch.tensor(A) type(A),type(B)
- 调用item函数或Python的内置函数将大小为1的张量转换为Python标量
a=torch.tensor([3.5]) a,a.item(),float(a),int(a)
二、数据预处理
用深度学习来解决现实世界的问题,经常从预处理原始数据开始, 而不是从那些准备好的张量格式数据开始。
(一)数据集读取
首先创建一个人工数据集,并存储在CSV(逗号分隔值)文件 …/data/house_tiny.csv中。 将数据集按行写入CSV文件中。
import os
os.makedirs(os.path.join('..', 'data'), exist_ok=True)
data_file = os.path.join('..', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n') # 每行表示一个数据样本
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
从创建的CSV文件中加载原始数据集
import pandas as pd
data = pd.read_csv(data_file)
print(data)
(二)缺失值处理
“NaN”项代表缺失值。
- 对于inputs中缺少的数值,用同一列的均值替换“NaN”项。
#通过位置索iloc,将data分成inputs和outputs, 其中前者为data的前两列,而后者为data的最后一列。
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)
- 对于inputs中的类别值或离散值,将“NaN”视为一个类别,处理为哑变量
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
(三)转换为张量格式
现在inputs和outputs中的所有条目都是数值类型,它们可以转换为张量格式。
import torch
X = torch.tensor(inputs.to_numpy(dtype=float))
y = torch.tensor(outputs.to_numpy(dtype=float))
X, y
参考:
https://www.cnblogs.com/jiaxin359/p/9021726.html