E02 预备知识


E02 预备知识

数据操作

入门

张量表示一个由数值组成的数组,这个数组可能有多个维度。

设想一根钢筋内一点受的力所组成的3$\times$3矩阵,每个矩阵元素包含了力的作用方向和力的作用面

具有一个轴的张量对应数学上的向量(vector); 具有两个轴的张量对应数学上的矩阵(matrix); 具有两个轴以上的张量没有特殊的数学名称。

import torch
x = torch.arange(12) #使用 arange 创建一个行向量 x。这个行向量包含以0开始的前12个整数,它们默认创建为整数
x.shape	#shape属性来访问张量(沿每个轴的长度)的形状
x.numel()	# 张量里的元素总数
X = x.reshape(3, 4) #张量的形状有一行12列改为3行4列,大小不变
X = x.reshape(3,-1) #自动计算,不需要给出所有维度
#使用全0、全1、其他常量,或者从特定分布中随机采样的数字来初始化矩阵
torch.zeros((2, 3, 4))
torch.ones((2, 3, 4))
torch.randn(3, 4)
torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]]) #通过提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值,此行意为3行4列的矩阵

运算符

同一形状的张量,常见的标准算术运算符(+-*/**)都可以被升级为按元素运算。

我们也可以把多个张量连结(concatenate)在一起, 把它们端对端地叠起来形成一个更大的张量。 我们只需要提供张量列表,并给出沿哪个轴连结。

第一个输出张量的轴-0长度(6)是两个输入张量轴-0长度的总和(3+3); 第二个输出张量的轴-1长度(8)是两个输入张量轴-1长度的总和(4+4)。

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为例: 对于每个位置,如果XY在该位置相等,则新张量中相应项的值为1。 这意味着逻辑语句X == Y在该位置处为真,否则该位置为0。

X == Y
tensor([[False,  True, False,  True],
        [False, False, False, False],
        [False, False, False, False]])

对张量中的所有元素进行求和,会产生一个单元素张量。

X.sum()
tensor(66.)

广播机制

在上面的部分中,我们看到了如何在相同形状的两个张量上执行按元素操作。 在某些情况下,即使形状不同,我们仍然可以通过调用 广播机制(broadcasting mechanism)来执行按元素操作。 这种机制的工作方式如下:

  1. 通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状;
  2. 对生成的数组执行按元素操作。

在大多数情况下,我们将沿着数组中长度为1的轴进行广播,如下例子:

a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b
(tensor([[0],
         [1],
         [2]]),
 tensor([[0, 1]]))

由于ab分别是3×1和1×2矩阵,如果让它们相加,它们的形状不匹配。 我们将两个矩阵广播为一个更大的3×2矩阵,如下所示:矩阵a将复制列, 矩阵b将复制行,然后再按元素相加。

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

索引和切片

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

转化为其他python对象

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

数据预处理

读取数据集

import os

os.makedirs(os.path.join('..', 'data'), exist_ok=True)#创建目录。os.path.join() 可以将一些路径片段合并成为一个路径字符串。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')
    
import pandas as pd
data = pd.read_csv(data_file)#要从创建的CSV文件中加载原始数据集,我们导入pandas包并调用read_csv函数。
print(data)

运行结果如下:

   NumRooms Alley   Price
0       NaN  Pave  127500
1       2.0   NaN  106000
2       4.0   NaN  178100
3       NaN   NaN  140000

处理缺失值

为了处理缺失的数据,典型的方法包括插值法删除法, 其中插值法用一个替代值弥补缺失值,而删除法则直接忽略缺失值。

inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]#iloc[:, 0:2]指行索引全部,列索引0-1的数据(索引从0开始标记)
inputs = inputs.fillna(inputs.mean())#用inputs.mean(),即平均值来填充空值
print(inputs)

运行结果如下:

   NumRooms Alley
0       3.0  Pave
1       2.0   NaN
2       4.0   NaN
3       3.0   NaN

对于inputs中的类别值或离散值,我们将“NaN”视为一个类别。 由于“巷子类型”(“Alley”)列只接受两种类型的类别值“Pave”和“NaN”, pandas可以自动将此列转换为两列“Alley_Pave”和“Alley_nan”。 巷子类型为“Pave”的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。 缺少巷子类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。

inputs = pd.get_dummies(inputs, dummy_na=True)
#get_dummies:Convert categorical variable into dummy/indicator variables.
#dummy variables: 0 or 1
#dummy_na:Add a column to indicate NaNs, if False NaNs are ignored.
print(inputs)
   NumRooms  Alley_Pave  Alley_nan
0       3.0           1          0
1       2.0           0          1
2       4.0           0          1
3       3.0           0          1

现在inputsoutputs中的所有条目都是数值类型,它们可以转换为张量格式。 当数据采用张量格式后,可以通过张量函数来进一步操作。

import torch
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
X, y
(tensor([[3., 1., 0.],
         [2., 0., 1.],
         [4., 0., 1.],
         [3., 0., 1.]], dtype=torch.float64),
 tensor([127500, 106000, 178100, 140000]))

线性代数

张量算法的基本性质

两个矩阵的按元素乘法称为Hadamard积(Hadamard product)(数学符号⊙)

范数

向量长度是一个L2范数

u = torch.tensor([3.0, -4.0])
torch.norm(u)

微积分

绘制函数u = f(x) 及其在x=1处的切线y=2x−3, 其中系数2是切线的斜率。

x = np.arange(0, 3, 0.1)#起点0,终点3,步长0.1
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])
#legend图例

文章作者: JingdeTDW
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 JingdeTDW !
  目录