NNDL 实验二 pytorch入门

一. 概念:张量、算子
写出定义,并用通俗易懂的语言描述自己的理解。

张量(Tensor):深度学习中表示和存储数据的主要形式。张量概念是矢量概念的推广,矢量是一阶张量。张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数。它是一个定义在一些向量空间和一些对偶空间的笛卡尔积上的多重线性映射,其坐标是|n|维空间内,有|n|个分量的一种量, 其中每个分量都是坐标的函数, 而在坐标变换时,这些分量也依照某些规则作线性变换。
下图是3种纬度的张量可视化表示。
在这里插入图片描述

张量中元素的类型可以是布尔型数据、整数、浮点数或者复数,但同一张量中所有元素的数据类型均相同。因此我们可以给张量定义一个数据类型(dtype)来表示其元素的类型。

算子(Operator):深度学习算法由一个个计算单元组成,我们称这些计算单元为算子,也是构建神经网络模型的基础组件。每个算子有前向和反向计算过程,前向计算对应一个数学函数,而反向计算对应这个数学函数的梯度计算。有了算子,我们就可以很方便地通过算子来搭建复杂的神经网络模型,而不需要手工计算梯度。

二. 使用pytorch实现张量运算
1.2 张量

import torch  # 导入Torch

1.2.1 创建张量
1.2.1.1 指定数据创建张量

t=torch.tensor([1,2,3])
print(t)

tensor([1, 2, 3])

1.2.1.2 指定形状创建

 t = torch.full((2,2),1) 
 #指定形状为(矩阵尺寸2,2), 填充数值1
 print(t)

tensor([[1, 1],
[1, 1]])

1.2.1.3 指定区间创建


t = torch.arange(5, 10, 2)
# input:数值区间[5,10),间隔2
# 注意:是闭区间到开区间[5,10)
print(t)

tensor([5, 7, 9])

1.2.2 张量的属性
1.2.2.1 张量的形状

t= torch.ones([2, 3, 4, 5])
#创建一个四维张量
print("Number of dimensions:", t.ndim)
print("Shape of Tensor:", t.shape)
print("Elements number along axis 0 of Tensor:", t.shape[0])
print("Elements number along the last axis of Tensor:", t.shape[-1])
print('Number of elements in Tensor: ', t.size)

Number of dimensions: 4
Shape of Tensor: torch.Size([2, 3, 4, 5])
Elements number along axis 0 of Tensor: 2
Elements number along the last axis of Tensor: 5
Number of elements in Tensor: <built-in method size of Tensor object at 0x0000017B805D2040>

1.2.2.2 形状的改变

# 定义一个shape为[3,2,5]的三维Tensor
t= torch.tensor([[[1, 2, 3, 4, 5],
                                   [6, 7, 8, 9, 10]],
                                  [[11, 12, 13, 14, 15],
                                   [16, 17, 18, 19, 20]],
                                  [[21, 22, 23, 24, 25],
                                   [26, 27, 28, 29, 30]]])
print("the shape of t:", t.shape)
# paddle.reshape 可以保持在输入数据不变的情况下,改变数据形状。这里我们设置reshape为[2,5,3]
reshape_Tensor = torch.reshape(t, [2, 5, 3])
print("After reshape:", reshape_Tensor)

the shape of t: torch.Size([3, 2, 5])
After reshape: tensor([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]],
[[16, 17, 18],
[19, 20, 21],
[22, 23, 24],
[25, 26, 27],
[28, 29, 30]]])

总结:
1.从输出结果看,将张量从[3, 2, 5]的形状reshape为[2, 5, 3]的形状时,张量内的数据不会发生改变,元素顺序也没有发生改变,只有数据形状发生了改变。
2.从电子书上得知使用reshape函数的一个用法:-1表示这个维度的值是从张量的元素总数和剩余维度推断出来的。因此,有且只有一个维度可以被设置为-1。

1.2.2.3 张量的数据类型

#以上述定义shape为[3,2,5]的三维Tensor为例:

print("Tensor dtype from t:", t.dtype)

Tensor dtype from t: torch.int64

1.2.2.4 张量的设备位置

初始化张量时可以通过place来指定其分配的设备位置,可支持的设备位置有三种:CPU、GPU和固定内存。

print(t.device)

cpu

1.2.3 张量与Numpy数组转换

t = t.numpy()

1.2.4 张量的访问
1.2.4.1 索引和切片

t = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print("索引:", t[2])
print("切片:", t[0:3])

索引: tensor([4, 3, 2, 1])
切片: tensor([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])

1.2.4.2 访问张量

print(t[1:,2:3])

tensor([[3],
[2]])

1.2.4.3 修改张量

t[1] = 5
print (t)

tensor([[2, 1, 4, 3],
[5, 5, 5, 5],
[4, 3, 2, 1]])

1.2.5 张量的运算
1.2.5.1 数学运算

a=torch.tensor([1, 2, 3, 4])
b=torch.tensor([2, 4, 6, 8])
print("加法:", a+b)
print("减法:", a-b)
print("乘法:", a*b)
print("除法:", a/b)
print("幂:", a**b)

加法: tensor([ 3, 6, 9, 12])
减法: tensor([-1, -2, -3, -4])
乘法: tensor([ 2, 8, 18, 32])
除法: tensor([0.5000, 0.5000, 0.5000, 0.5000])
幂: tensor([ 1, 16, 729, 65536])

1.2.5.2 逻辑运算

a=torch.tensor([0, 1, 1, 0]).bool()
b=torch.tensor([0, 1, 0, 0]).bool()
print(a & b) # 与
print(a | b) # 或
print(~a)    # 取反
print(a ^ b) # 异或

tensor([False, True, False, False])
tensor([False, True, True, False])
tensor([ True, False, False, True])
tensor([False, False, True, False])

1.2.5.3 矩阵运算
要注意满足矩阵相乘的条件!!

# 矩阵相乘
x = torch.arange(12, dtype=torch.float32).reshape((4, 3))
y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print("矩阵相乘:", x.matmul(y)  )

矩阵相乘: tensor([[ 9., 8., 7., 6.],
[30., 26., 34., 30.],
[51., 44., 61., 54.],
[72., 62., 88., 78.]])

# 矩阵转置
a = torch.ones(2, 1)
print("原始:",a)
print("转置后:",a.t())

原始: tensor([[1.],
[1.]])
转置后:tensor([[1., 1.]])

1.2.5.4 广播机制
广播机制:
允许在一些运算时使用不同形状的张量。通常来讲,如果有一个形状较小和一个形状较大的张量,会希望多次使用较小的张量来对较大的张量执行某些操作,看起来像是形状较小的张量首先被扩展到和较大的张量形状一致,然后再做运算。

广播机制的条件:
飞桨的广播机制主要遵循如下规则(参考Numpy广播机制):
1)每个张量至少为一维张量。
2)从后往前比较张量的形状,当前维度的大小要么相等,要么其中一个等于1,要么其中一个不存在。

广播机制的计算规则:
现在我们知道在什么情况下两个张量是可以广播的。两个张量进行广播后的结果张量的形状计算规则如下:
1)如果两个张量shape的长度不一致,那么需要在较小长度的shape前添加1,直到两个张量的形状长度相等。
2) 保证两个张量形状相等之后,每个维度上的结果维度就是当前维度上较大的那个。

三. 使用pytorch实现数据预处理

  1. 读取数据集 house_tiny.csv、boston_house_prices.csv、Iris.csv
import pandas as pd
file1=r"C:\Users\teacher\Documents\Tencent Files\1377916621\FileRecv\boston_house_prices.csv"
file2=r"C:\Users\teacher\Documents\Tencent Files\1377916621\FileRecv\house_tiny.csv"
file3=r"C:\Users\teacher\Documents\Tencent Files\1377916621\FileRecv\Iris.csv"
data1=pd.read_csv(file1)
data2=pd.read_csv(file2)
data3=pd.read_csv(file3)
print(data1)
print(data2)
print(data3)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 处理缺失值
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
# inputs中的缺失值用同一列的均值替换
inputs = inputs.fillna(inputs.mean()) 
print(inputs)
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)

在这里插入图片描述

  1. 转换为张量格式
a,b=torch.Tensor(inputs.values), torch.Tensor(outputs.values)
print(a.dtype)
print(b.dtype)

总结:本次作业首先明确了张量和算子的概念。对于张量,我通过联系它与标量、矢量、矩阵之间的关系,来更好地理解张量这个概念;对于算子,主要从它在神经网络模型中的应用来理解它,比如在机器学习中bp算法反向计算就对应这个数学函数的梯度计算,能把算子看成一个个计算单元。
然后通过参考飞桨AI Studio - 人工智能学习与实训社区中的代码,它们是基于PaddlePaddle框架的,本次作业老师言简意赅的说为把基于PaddlePaddle框架的代码改为基于Pytorch的,通过复习并学习一些函数的算法得以解决。
最后就是对数据的预处理,比较麻烦的点在于对缺失值的处理,这部分在西瓜书中是有介绍的,但可能因为当时这不是重点就没仔细看。通过本次实验我了解到对于缺失值的处理有两种方法,一个是插值法一个是直接删除法。前者是用均值或者中位数进行插值,而后者则是直接删去。在实验操作中,我用了用均值进行插值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值