Deep Learning学习day1-数据操作
2.1 数据操作
这一部分是直接从 jupyter 里面导出来的,可能观感不太好,可以直接在这里下文件
入门
使用 arange 创建一个行向量 x,这个行向量包含以0开始的前12个整数,它们默认创建为整数,也可指定创建类型为浮点数,张量中的每个值都称为张量的元素(element)。基础操作如下所示:
1 | import torch |
1 | tensor([[2, 1, 4, 3], |
运算符
对于任意具有相同形状的张量, 常见的标准算术运算符(+、-、*、/和**)都可以被升级为按元素运算
1 | import torch |
1 | (tensor([[ 0., 1., 2., 3.], |
广播机制
1 | a = torch.arange(3).reshape((3, 1)) |
1 | tensor([[0, 1], |
索引&切片
1 | import torch |
1 | tensor([[12., 12., 12., 12.], |
转换其它对象
1 | import torch |
1 | (tensor([3.5000]), 3.5, 3.5, 3) |
数据集预处理
读取数据集
创建一个人工数据集,并存储在CSV(逗号分隔值)文件 ../data/house_tiny.csv中。 以其他格式存储的数据也可以通过类似的方式进行处理
1 | import os |
1 | import pandas as pd |
1 | NumRooms Alley Price |
处理缺失值
“NaN”项代表缺失值。 为了处理缺失的数据,典型的方法包括插值法和删除法, 其中插值法用一个替代值弥补缺失值,而删除法则直接忽略缺失值
1 | inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] |
1 | NumRooms Alley |
1 | # dummy_na=True: 指定是否将缺失值(NaN)作为一个单独的类别进行编码。如果设置为 True,那么缺失值会被转换为一个额外的哑变量列,哑变量是指用 0 和 1 表示的二进制变量 |
1 | NumRooms Alley_Pave Alley_nan |
转换为张量格式
1 | import torch |
1 | (tensor([[3., 1., 0.], |
练习
删除缺失值最多的列
1 | import numpy as np |
1 | before delete |
线性代数
两个矩阵的按元素乘法称为Hadamard积(Hadamard product)。
1 | import torch |
1 | (tensor([[ 0., 1., 2., 3.], |
将张量乘以或加上一个标量不会改变张量的形状,其中张量的每个元素都将与标量相加或相乘
1 | a = 2 |
1 | tensor([[ 2., 3., 4., 5.], |
张量降维
1 | x = torch.arange(4, dtype = torch.float32) |
1 | (tensor([0., 1., 2., 3.]), tensor(6.)) |
1 | A_sum_axis0 = A.sum(axis=0) #按列相加 |
1 | (tensor([40., 45., 50., 55.]), torch.Size([4])) |
1 | A_sum_axis1 = A.sum(axis=1) #按行相加 |
1 | (tensor([ 6., 22., 38., 54., 70.]), torch.Size([5])) |
通过将总和除以元素总数来计算平均值。 在代码中,我们可以调用函数来计算任意形状张量的平均值。
1 | A.sum() / A.numel() |
1 | tensor(9.5000) |
1 | A.mean(axis=0), A.sum(axis=0)/A.shape[0] |
1 | (tensor([ 8., 9., 10., 11.]), tensor([ 8., 9., 10., 11.])) |
非降维求和
1 | sum_A = A.sum(axis=1, keepdims=True) |
1 | tensor([[ 6.], |
通过广播让 A 除以 sum_A
1 | A/sum_A |
1 | tensor([[0.0000, 0.1667, 0.3333, 0.5000], |
求累加总和
1 | A.cumsum(axis=0) |
1 | tensor([[ 0., 1., 2., 3.], |
点积
两个向量相同位置元素乘积之和
1 | y = torch.ones(4, dtype = torch.float32) |
1 | (tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.)) |
1 | # 矩阵向量积 |
1 | (torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.])) |
1 | # 矩阵乘法积 |
1 | tensor([[ 6., 6., 6.], |
范数
L2 范数
对于一个向量来说,它的 L2 范数就是它的各元素平方和的平方根
1 | u = torch.tensor([3.0, -4.0]) |
1 | tensor(5.) |
L1 范数对于一个向量来说是各向量元素的绝对值之和
1 | torch.abs(u).sum() |
1 | tensor(7.) |
Frobenius范数(Frobenius norm)是矩阵元素平方和的平方根:
1 | torch.norm(torch.ones((4, 9))) |
1 | tensor(6.) |
1 | A,A.sum(axis=0),A/A.sum(axis=0) |
1 | (tensor([[ 0., 1., 2., 3.], |
自动微分
1 | import torch |
1 | tensor([0., 1., 2., 3.]) |
1 | # 下面代码需要一个地方来存储梯度,不会在每次对一个参数求导时都分配新的内存 |
1 | None |
1 | y = 2 * torch.dot(x,x) |
1 | tensor(28., grad_fn=<MulBackward0>) |
注意事项:前面这里 y 实际上是一个标量,标量关于向量的梯度是向量,并且与x拥有相同形状
1 | y.backward() |
1 | tensor([ 0., 4., 8., 12.]) |
1 | x.grad == 4*x |
1 | tensor([True, True, True, True]) |
1 | # 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值 |
1 | tensor([1., 1., 1., 1.]) |
非标量变量的反向传播
当y不是标量时,向量y关于向量x的导数的最自然解释是一个矩阵。 对于高阶和高维的y和x,求导的结果可以是一个高阶张量。
1 | # 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。 |
1 | tensor([0., 2., 4., 6.]) |
然而,这种情况会出现在高级机器学习中(包括深度学习中), 但当调用向量的反向计算时,通常会试图计算一批训练样本中每个组成部分的损失函数的导数
分离计算
假设y是作为x的函数计算的,而z则是作为y和x的函数计算的。 如果想计算z关于x的梯度,但由于某种原因,希望将y视为一个常数,并且只考虑到x在y被计算后发挥的作用,这里就需要用分离计算。
1 | x.grad.zero_() |
1 | tensor([True, True, True, True]) |
python 控制流梯度计算
1 | def f(a): |
然后计算梯度
1 | a = torch.randn(size=(), requires_grad=True) |
1 | tensor(-1794.2429, grad_fn=<MulBackward0>) |
- Title: Deep Learning学习day1-数据操作
- Author: henry
- Created at : 2024-06-16 21:11:19
- Updated at : 2024-06-16 21:32:58
- Link: https://henrymartin262.github.io/2024/06/16/data_process/
- License: This work is licensed under CC BY-NC-SA 4.0.