【动手学深度学习v2】学习笔记01:数据操作、数据预处理

文章目录

  • 声明
  • 一、数据操作实现
    • 1.1 基础操作
    • 1.2 张量创建和赋值
    • 1.3 张量操作
      • 1.3.1 常见数学操作
      • 1.3.2 张量连接
      • 1.3.3 逻辑运算
      • 1.3.4 广播机制
      • 1.3.5 元素选择
      • 1.3.6 类型转换
  • 二、数据预处理实现
    • 2.1 创建和加载数据集
    • 2.2 数据处理

声明

最近着手学习深度学习,学习之余整理此学习笔记,以便后续复习,也希望能帮助到以后学习深度学习的同好。我观看的网课是李沐老师的动手学深度学习v2,文章也是主要在李沐老师的课程学习中所记。读者可以通过前文超链接直接进入李沐老师的B站主页观看原视频。
本文章主要用于个人学习,非商用,如有侵权还请海涵,并联系博主删除。

一、数据操作实现

1.1 基础操作

首先,我们要导入torch

import torch

张量表示一个数值组成的数组,这个数组可能有多个维度。
我们通过如下代码创建了一个长度为12的一维数组。其中,我们可以通过arange(n)方法创建一个长度为n的一维数组,其各元素的值分别为0至n-1。

x = torch.arange(12)

有了数据,我们就可以对数据进行操作了。一些基础操作如下表所示:

操作 属性/方法
形状尺寸 shape
元素个数 numel()
改变形状 reshape()

对于我们的张量x,我们可以通过如下代码进行操作。其中,x.reshape(3, 4)将x改变为一个3行4列的二维张量,并且不改变各元素的值和顺序。

x.shape
x.numel()
x.reshape(3, 4)

1.2 张量创建和赋值

我们可以使用全0、全1、其他常量或者从特定分布中随机采样的数字。

类型 方法
全0 zeros()
全1 ones()
赋确定值 tensor()

举个例子:

torch.zeros(2, 3, 4)	# 创建一个三维全0张量,各维度分布为2、3和4
torch.ones(2, 3, 4)		# 创建一个三维全1张量

我们可以通过提供包含数值的Python列表(或嵌套列表)来为所需张量中的每个元素赋确定值。
下例中,我们创建了一个确定值的三维张量:
[ 1 2 3 4 2 3 4 1 4 3 2 1 ] \begin{bmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 1 \\ 4 & 3 & 2 & 1 \end{bmatrix} 124233342411

torch.tensor([[1, 2, 3, 4], [2, 3, 4, 1], [4, 3, 2, 1]])

1.3 张量操作

1.3.1 常见数学操作

创建了张量之后,我们就可以进行一些常见的操作了。

类型 运算符
+
-
*
/
求幂 **
指数运算 exp()
求和 sum()

如下例所示:

x = torch.tensor([1.0, 2, 3, 4])
y = torch.tensor([2, 2, 2, 2])

# 加减乘除和求幂
x + y, x - y, x * y, x / y, x ** y

# 指数运算
torch.exp(x)

# 求和
x.sum()

1.3.2 张量连接

此外,我们还可以通过cat()方法将多个张量连接在一起。当dim = 0时,按列连接;当dim = 1时,按行连接。

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)

1.3.3 逻辑运算

我们还可以通过逻辑运算符来构建二元张量。例如,我们可以通过X == Y来构建二元张量:
[ F a l s e T r u e F a l s e T r u e F a l s e F a l s e F a l s e F a l s e F a l s e F a l s e F a l s e F a l s e ] \begin{bmatrix} False & True & False & True \\ False & False & False & False \\ False & False & False & False \end{bmatrix} FalseFalseFalseTrueFalseFalseFalseFalseFalseTrueFalseFalse

1.3.4 广播机制

对于两个形状不同的张量,pytorch和numpy会将这个运算的参数自动扩张成相同的大小,来执行按元素操作。在不复制数据的情况下就能进行运算,以达到更高的效率。

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

上例可看成如下运算:
[ 0 1 2 ] + [ 0 1 ] = [ 0 0 1 1 2 2 ] + [ 0 1 0 1 0 1 ] = [ 0 1 1 2 2 3 ] \begin{bmatrix} 0 \\ 1 \\ 2 \end{bmatrix} + \begin{bmatrix} 0 & 1 \\ \end{bmatrix} = \begin{bmatrix} 0 & 0\\ 1 & 1\\ 2 & 2 \end{bmatrix} + \begin{bmatrix} 0 & 1 \\ 0 & 1 \\ 0 & 1 \end{bmatrix} = \begin{bmatrix} 0 & 1 \\ 1 & 2 \\ 2 & 3 \end{bmatrix} 012 +[01]= 012012 + 000111 = 012123

1.3.5 元素选择

我们可以用[-1]选择最后一个元素,可以用[n1:n2]选择第n1+1至第n2个元素。

X[-1]		# 选择X的最后一个元素
X[1:3]		# 选择X的第二个和第三个元素

此外,我们可以通过指定索引来将元素写入矩阵。

X[1, 2] = 9	# 将X的第二行第三列元素赋值为9

为多个元素赋相同的值,我们只需要索引所有元素,然后为他们赋值。

X[0:2, :] = 12	# 将X的第一二行元素赋值为12

如果矩阵过大,运行一些操作可能会导致为新结果分配内存。我们可通过一些办法执行原地操作。

# 运算前后Z的地址不变
Z = torch.zeros_like(Y)
Z[:] = X + Y

# 若后续运算中没有重复使用X,可以使用如下两种操作
X[:] = X + Y
X += Y

1.3.6 类型转换

tensor类型的数据可以与numpy类型的数据相互转换。并且,大小为1的张量可以转换为Python标量。

A = X.numpy()			# tensor -> numpy
B = torch.tensor(A)		# numpy -> tensor

a = torch.tensor([1.2])
b = a.item()			# tensor -> float
c = float(a)			# tensor -> float
d = int(a)				# tensor -> int

二、数据预处理实现

2.1 创建和加载数据集

首先,创建一个人工数据集,并存储在csv文件中。

import os

os.makedirs(os.path.join('..', 'data'), exist_ok=True)	# 创建目录
data_file = os.path.join('..', 'data', 'house_tiny.csv')# 文件路径

def write():
    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文件中加载原始数据集,我们会得到如下所示的数据:
N u m R o o m s A l l e y P r i c e 0 N a N P a v e 127500 1 2.0 N a N 106000 2 4.0 N a N 178100 3 N a N N a N 140000 \begin{matrix} & NumRooms & Alley & Price \\ 0 & NaN & Pave & 127500 \\ 1 & 2.0 & NaN & 106000 \\ 2 & 4.0 & NaN & 178100 \\ 3 & NaN & NaN & 140000 \end{matrix} 0123NumRoomsNaN2.04.0NaNAlleyPaveNaNNaNNaNPrice127500106000178100140000

import pandas as pd

def read():
    data = pd.read_csv(data_file)

2.2 数据处理

其次,我们进行缺失数据处理:插值和删除。
我们先将加载的数据分为输入数据和输出数据。通过mean()方法获得输入数据的平均值,再通过fillna()方法将缺失的数据修改为之前获得的平均值。

# 前两列为输入数据 后一列为输出数据
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())

如上操作可视为对输入数据进行了如下处理:
N u m R o o m s A l l e y 0 N a N P a v e 1 2.0 N a N 2 4.0 N a N 3 N a N N a N ⟶ N u m R o o m s A l l e y 0 3.0 P a v e 1 2.0 N a N 2 4.0 N a N 3 3.0 N a N \begin{matrix} & NumRooms & Alley\\ 0 & NaN & Pave \\ 1 & 2.0 & NaN \\ 2 & 4.0 & NaN \\ 3 & NaN & NaN \end{matrix} \longrightarrow \begin{matrix} & NumRooms & Alley\\ 0 & 3.0 & Pave \\ 1 & 2.0 & NaN \\ 2 & 4.0 & NaN \\ 3 & 3.0 & NaN \end{matrix} 0123NumRoomsNaN2.04.0NaNAlleyPaveNaNNaNNaN0123NumRooms3.02.04.03.0AlleyPaveNaNNaNNaN
可以看到,第一列的缺失值已经被赋予了平均值。但第二列为字符类型,无法通过此方法为缺失值赋值。因此,对于输入数据中的类别值或离散值,我们将“NaN”视为一个类别

inputs = pd.get_dummies(inputs, dummy_na=True)

如上操作可视为对输入数据进行了如下处理:
N u m R o o m s A l l e y 0 3.0 P a v e 1 2.0 N a N 2 4.0 N a N 3 3.0 N a N ⟶ N u m R o o m s A l l e y _ P a v e A l l e y _ n a n 0 3.0 1 0 1 2.0 0 1 2 4.0 0 1 3 3.0 0 1 \begin{matrix} & NumRooms & Alley\\ 0 & 3.0 & Pave \\ 1 & 2.0 & NaN \\ 2 & 4.0 & NaN \\ 3 & 3.0 & NaN \end{matrix} \longrightarrow \begin{matrix} & 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 \end{matrix} 0123NumRooms3.02.04.03.0AlleyPaveNaNNaNNaN0123NumRooms3.02.04.03.0Alley_Pave1000Alley_nan0111
此时,inputsoutputs中的所有数据元素都是数值类型,它们可以转换为张量格式。

import torch

x, y = torch.tensor(inputs.values), torch.tensor(outputs.values)

其中,输入数据最终为:
[ 3. 1. 0. 2. 0. 1. 4. 0. 1. 3. 0. 1. ] \begin{bmatrix} 3. & 1. & 0. \\ 2. & 0. & 1. \\ 4. & 0. & 1. \\ 3. & 0. & 1. \end{bmatrix} 3.2.4.3.1.0.0.0.0.1.1.1.
下一篇:【动手学深度学习v2】学习笔记02:线性代数、矩阵计算、自动求导

你可能感兴趣的:(深度学习笔记整理,深度学习,学习,python,数据分析)