| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> Python知识库 -> HBU-NNDL 实验二 pytorch入门 -> 正文阅读 |
|
|
[Python知识库]HBU-NNDL 实验二 pytorch入门 |
|
|
| Data type | dtype | Tensor types |
|---|---|---|
| 32-bit floating point | torch.float32 or torch.float | torch.*.FloatTensor |
| 64-bit floating point | torch.float64 or torch.double | torch.*.DoubleTensor |
| 16-bit floating point | torch.float16 or torch.half | torch.*.HalfTensor |
| 8-bit integer (unsigned) | torch.uint8 | torch.*.ByteTensor |
| 8-bit integer (signed) | torch.int8 | torch.*.CharTensor |
| 16-bit integer (signed) | torch.int16 or torch.short | torch.*.ShortTensor |
| 32-bit integer (signed) | torch.int32 or torch.int | torch.*.IntTensor |
| 64-bit integer (signed) | torch.int64 or torch.long | torch.*.LongTensor |
1.2.2.4 张量的设备位置
Tensor=torch.tensor(1)
# 创建CPU上的Tensor
cpu_Tensor = Tensor.to("cpu")
# 通过Tensor.place查看张量所在设备位置
print('cpu Tensor: ', cpu_Tensor)
# 创建GPU上的Tensor
gpu_Tensor = Tensor.to("cuda")
print('gpu Tensor: ', gpu_Tensor)
# 创建固定内存上的Tensor
pin_memory_Tensor = torch.tensor(1, pin_memory=True)
print('pin memory Tensor: ', pin_memory_Tensor)
????????pin_memory就是锁页内存,创建Tensor时,设置pin_memory=True, 则意味着生成的Tensor数据最开始是属于内存中的锁页内存, 这样将内存的Tensor转义到GPU的显存就会更快一些。
????????主机中的内存,有两种存在方式,一是锁页,二是不锁页, 锁页内存存放的内容在任何情况下都不会与主机的虚拟内存进行交换(注:虚拟内存就是硬盘),而不锁页内存在主机内存不足时, 数据会存放在虚拟内存中。
ndim_1_Tensor = torch.tensor([1., 2.])
# 将当前 Tensor 转化为 numpy.ndarray
ndim_1_numpy=ndim_1_Tensor.numpy()
print('Tensor to convert: ', ndim_1_numpy)
print('type:',type(ndim_1_numpy))
Tensor to convert: ?[1. 2.]
type: <class 'numpy.ndarray'>
Tensor和numpy.ndarray之间可以互相转换
1.2.4.1 索引和切片
一般索引值表达形式是[index, index,...]
假设我们定义这样一个tensor,torch.rand(4, 3, 28, 28) 这个tensor表示包含了4张图片,每张图片3个通道(RGB),每张图片的大小是28(行)*28(列)
a = torch.rand(4, 3, 28, 28)
print(a[0].shape) #取第一张图片的Shape
print(a[0, 0].shape) #取第一张图片的第一个通道(R通道)的Shape
print(a[0, 0, 2, 4]) #取第一张图片,R通道,第三行,第五列的像素值,是一个标量
torch.Size([3, 28, 28])
torch.Size([28, 28])
tensor(0.6839)
切片表达式:[start:end:step]
表达式的意义是,从start开始到end结束,每隔step个进行采样。根据start,end,step以及:选项可以分为:
·通过[start:end] 形式索引,注意这种方式是左闭右开的方式[start:end),左边默认是从0开始索引.
·注意负值的索引即表示倒数第几个元素,例如-2就是倒数第二个元素。
·[start:end:step] 从start开始到end结束,每隔step个进行采样,普通的切片索引对应的step是1
a = torch.rand(4, 3, 28, 28)
print(a[:2].shape) # 在第一个维度上取后0和1
print(a[:2, :1, :, :].shape) # 在第一个维度上取0和1,在第二个维度上取0
print(a[:2, 1:, :, :].shape) # 在第一个维度上取0和1,在第二个维度上取1,2
print(a[:2, -2:, :, :].shape) # 在第一个维度上取0和1,在第二个维度上取1,2
print(a[:, :, 0:28:2, 0:28:2].shape) # step=2隔行采样
print(a[:, :, ::2, ::2].shape) # 等同于这个
torch.Size([2, 3, 28, 28])
torch.Size([2, 1, 28, 28])
torch.Size([2, 2, 28, 28])
torch.Size([2, 2, 28, 28])
torch.Size([4, 3, 14, 14])
torch.Size([4, 3, 14, 14])
1.2.4.2 访问张量
一维张量:
# 定义1个一维Tensor
ndim_1_Tensor = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
print("Origin Tensor:", ndim_1_Tensor)
print("First element:", ndim_1_Tensor[0])
print("Last element:", ndim_1_Tensor[-1])
print("All element:", ndim_1_Tensor[:])
print("Before 3:", ndim_1_Tensor[:3])
print("Interval of 3:", ndim_1_Tensor[::3])
print("Reverse:", torch.tensor(list(ndim_1_Tensor.numpy()[::-1])))
?Origin Tensor: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
First element: tensor(0)
Last element: tensor(8)
All element: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8])
Before 3: tensor([0, 1, 2])
Interval of 3: tensor([0, 3, 6])
Reverse: tensor([8, 7, 6, 5, 4, 3, 2, 1, 0])
tensor无法直接[::-1]进行反转,会出现如下报错:
ValueError: step must be greater than zero
如果将tensor转换为numpy反转后再转换为tensor
torch.from_numpy(ndim_1_Tensor.numpy()[::-1])
会出现如下报错:
ValueError: At least one stride in the given numpy array is negative, and tensors with negative strides are not currently supported. (You can probably work around this by making a copy of your array ?with array.copy().)?
所以我将tensor转换为numpy反转后改为list类型,再通过torch.tensor()创建张量
torch.tensor(list(ndim_1_Tensor.numpy()[::-1]))
二位张量:
# 定义1个二维Tensor
ndim_2_Tensor = torch.tensor([[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]])
print("Origin Tensor:", ndim_2_Tensor)
print("First row:", ndim_2_Tensor[0])
print("First row:", ndim_2_Tensor[0, :])
print("First column:", ndim_2_Tensor[:, 0])
print("Last column:", ndim_2_Tensor[:, -1])
print("All element:", ndim_2_Tensor[:])
print("First row and second column:", ndim_2_Tensor[0, 1])
Origin Tensor: tensor([[ 0, ?1, ?2, ?3],
? ? ? ? [ 4, ?5, ?6, ?7],
? ? ? ? [ 8, ?9, 10, 11]])
First row: tensor([0, 1, 2, 3])
First row: tensor([0, 1, 2, 3])
First column: tensor([0, 4, 8])
Last column: tensor([ 3, ?7, 11])
All element: tensor([[ 0, ?1, ?2, ?3],
? ? ? ? [ 4, ?5, ?6, ?7],
? ? ? ? [ 8, ?9, 10, 11]])
First row and second column: tensor(1)
1.2.4.3 修改张量?
# 定义1个二维Tensor
ndim_2_Tensor = torch.ones([2, 3], dtype=torch.float32)
print('Origin Tensor: ', ndim_2_Tensor)
# 修改第1维为0
ndim_2_Tensor[0] = 0
print('change Tensor: ', ndim_2_Tensor)
# 修改第1维为2.1
ndim_2_Tensor[0:1] = 2.1
print('change Tensor: ', ndim_2_Tensor)
# 修改全部Tensor
ndim_2_Tensor[...] = 3
print('change Tensor: ', ndim_2_Tensor)
Origin Tensor: ?tensor([[1., 1., 1.],
? ? ? ? [1., 1., 1.]])
change Tensor: ?tensor([[0., 0., 0.],
? ? ? ? [1., 1., 1.]])
change Tensor: ?tensor([[2.1000, 2.1000, 2.1000],
? ? ? ? [1.0000, 1.0000, 1.0000]])
change Tensor: ?tensor([[3., 3., 3.],
? ? ? ? [3., 3., 3.]])?
创建tensor时,dtype不能='float32',正确的是dtype='torch.float32'
修改全部tensor需要使用[...]
# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]], dtype=torch.float64)
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]], dtype=torch.float64)
# 第一种调用方法,torch.add逐元素相加算子,并将各个位置的输出元素保存到返回结果中
print('Method 1: ', torch.add(x, y))
# 第二种调用方法
print('Method 2: ', x.add(y))
Method 1: ?tensor([[ 6.6000, ?8.8000],
? ? ? ? [11.0000, 13.2000]], dtype=torch.float64)
Method 2: ?tensor([[ 6.6000, ?8.8000],
? ? ? ? [11.0000, 13.2000]], dtype=torch.float64)
1.2.5.1 数学运算
1.加减乘除
torch.add(input, alpha=1, other, out=None)????????????????????????????????
torch.sub(input, other, out=None)
torch.mul(input, other, out=None)
torch.div(input, other, out=None)
2.对数,指数,幂函数
torch.log(input, out=None) ——以e为底
torch.log10(input, out=None)
torch.log2(input, out=None)
torch.exp(input, out=None)
torch.pow(input, exponent, out=None)
?
3.三角函数
torch.acos(input, out=None)
torch.cosh(input, out=None)
torch.cos(input, out=None)
torch.asin(input, out=None)
torch.sinh(input, out=None)
torch.sin(input, out=None)
torch.atan(input, out=None)
torch.tanh(input, out=None)
torch.tan(input, out=None)
torch.atan2(input, other, out=None)
4.绝对值
torch.abs(input, out=None)
1.2.5.2 逻辑运算
x.isfinite() # 判断Tensor中元素是否是有限的数字,即不包括inf与nan
x.eq(y) # 判断两个Tensor的全部元素是否相等,并返回形状为[1]的布尔类Tensor
x.equal(y) # 判断两个Tensor的每个元素是否相等,并返回形状相同的布尔类Tensor
x.ne(y) # 判断两个Tensor的每个元素是否不相等
x.lt(y) # 判断Tensor x的元素是否小于Tensor y的对应元素
x.le(y) # 判断Tensor x的元素是否小于或等于Tensor y的对应元素
x.gt(y) # 判断Tensor x的元素是否大于Tensor y的对应元素
x.ge(y) # 判断Tensor x的元素是否大于或等于Tensor y的对应元素
x.allclose(y) # 判断两个Tensor的全部元素是否接近
1.2.5.3 矩阵运算
x.t() # 矩阵转置
x.transpose(1,0) # 交换第 0 维与第 1 维的顺序
x.norm('fro') # 矩阵的弗罗贝尼乌斯范数
x.dist(y, p=2) # 矩阵(x-y)的2范数
x.matmul(y) # 矩阵乘法
transpose()参数是两个整数,而不是一个列表
dist()需要x和y相同
matmul()需要x的列数与y的行数相同
1.2.5.4 广播机制
如果Pytorch运算支持广播的话,那么就意味着传给这个运算的参数会被自动扩张成相同的size,在不复制数据的情况下就能进行运算,整个过程可以做到避免无用的复制,达到更高效的运算。
广播机制实际上是在运算过程中,去处理两个形状不同向量的一种手段。
pytorch中的广播机制和numpy中的广播机制一样, 因为都是数组的广播机制。
# 当两个Tensor的形状一致时,可以广播
x = torch.ones((2, 3, 4))
y = torch.ones((2, 3, 4))
z = x + y
print('broadcasting with two same shape tensor: ', z.shape)
x = torch.ones((2, 3, 1, 5))
y = torch.ones((3, 4, 1))
# 从后往前依次比较:
# 第一次:y的维度大小是1
# 第二次:x的维度大小是1
# 第三次:x和y的维度大小相等,都为3
# 第四次:y的维度不存在
# 所以x和y是可以广播的
z = x + y
print('broadcasting with two different shape tensor:', z.shape)
broadcasting with two same shape tensor: ?torch.Size([2, 3, 4])
broadcasting with two different shape tensor: torch.Size([2, 3, 4, 5])
以张量x和张量y的相加为例, 其余数学运算同理
核心:如果相加的两个数组的shape不同, 就会触发广播机制:
? ? ? 1)程序会自动执行操作使得x.shape==y.shape;
? ? ? 2)对应位置进行相加运算,结果的shape是:x.shape和y.shape对应位置的最大值,比如:x.shape=(2,3,1,5),y.shape=(3,4,1),那么A+B的shape是(2,3,4,5)
1. 读取数据集?house_tiny.csv、boston_house_prices.csv、Iris.csv
pandas库可用于读取xls,csv,txt多种文件,在此用于读取csv文件导入pandas
import pandas as pd
使用pd.read_csv()读取文件,读取后的类型为DataFrame类型(df)
df_ht=pd.read_csv('house_tiny.csv')
df_bhp=pd.read_csv('boston_house_prices.csv')
df_iris=pd.read_csv('Iris.csv')
使用df.head()可以查看df的前几行数据
print(df_ht.head())
print(df_bhp.head())
print(df_iris.head())
NumRooms Alley ? Price
0 ? ? ? NaN ?Pave ?127500
1 ? ? ? 2.0 ? NaN ?106000
2 ? ? ? 4.0 ? NaN ?178100
3 ? ? ? NaN ? NaN ?140000
? ? ? CRIM ? ?ZN ?INDUS ?CHAS ? ?NOX ?... ?RAD ?TAX ?PTRATIO ?LSTAT ?MEDV
0 ?0.00632 ?18.0 ? 2.31 ? ? 0 ?0.538 ?... ? ?1 ?296 ? ? 15.3 ? 4.98 ?24.0
1 ?0.02731 ? 0.0 ? 7.07 ? ? 0 ?0.469 ?... ? ?2 ?242 ? ? 17.8 ? 9.14 ?21.6
2 ?0.02729 ? 0.0 ? 7.07 ? ? 0 ?0.469 ?... ? ?2 ?242 ? ? 17.8 ? 4.03 ?34.7
3 ?0.03237 ? 0.0 ? 2.18 ? ? 0 ?0.458 ?... ? ?3 ?222 ? ? 18.7 ? 2.94 ?33.4
4 ?0.06905 ? 0.0 ? 2.18 ? ? 0 ?0.458 ?... ? ?3 ?222 ? ? 18.7 ? 5.33 ?36.2
[5 rows x 13 columns]
? ?Id ?SepalLengthCm ?SepalWidthCm ?PetalLengthCm ?PetalWidthCm ? ? ?Species
0 ? 1 ? ? ? ? ? ?5.1 ? ? ? ? ? 3.5 ? ? ? ? ? ?1.4 ? ? ? ? ? 0.2 ?Iris-setosa
1 ? 2 ? ? ? ? ? ?4.9 ? ? ? ? ? 3.0 ? ? ? ? ? ?1.4 ? ? ? ? ? 0.2 ?Iris-setosa
2 ? 3 ? ? ? ? ? ?4.7 ? ? ? ? ? 3.2 ? ? ? ? ? ?1.3 ? ? ? ? ? 0.2 ?Iris-setosa
3 ? 4 ? ? ? ? ? ?4.6 ? ? ? ? ? 3.1 ? ? ? ? ? ?1.5 ? ? ? ? ? 0.2 ?Iris-setosa
4 ? 5 ? ? ? ? ? ?5.0 ? ? ? ? ? 3.6 ? ? ? ? ? ?1.4 ? ? ? ? ? 0.2 ?Iris-setosa
?NaN表示数据缺失
2. 处理缺失值
常用函数
df.isnull():是缺失值为True,反之为False
print(df_ht.isnull())
?NumRooms ?Alley ?Price
0 ? ? ?True ?False ?False
1 ? ? False ? True ?False
2 ? ? False ? True ?False
3 ? ? ?True ? True ?False
阅读数据发现只有house_tiny.csv存在缺失值
?df.dropna():删除至少缺少一个元素的行
df_ht=df_ht.dropna()
print(df_ht)
?Empty DataFrame
Columns: [NumRooms, Alley, Price]
Index: []
由于house_tiny.csv所有行都存在空元素,所以全删光咯。
df.fillna():补充缺失值
# 将房间数目,有无路径作为输入,价格作为输出,进行缺失值处理
inputs, outputs = df_ht.iloc[:, 0:2], df_ht.iloc[:, 2]
inputs = inputs.fillna(inputs.mean()) # 用输入的平均值填充NA
# Alley作为string没有均值,使用one hot编码
inputs = pd.get_dummies(inputs, dummy_na=True)
inputs['Price']=df_ht['Price']
print(inputs)
? ?NumRooms ?Alley_Pave ?Alley_nan ? Price
0 ? ? ? 3.0 ? ? ? ? ? 1 ? ? ? ? ?0 ?127500
1 ? ? ? 2.0 ? ? ? ? ? 0 ? ? ? ? ?1 ?106000
2 ? ? ? 4.0 ? ? ? ? ? 0 ? ? ? ? ?1 ?178100
3 ? ? ? 3.0 ? ? ? ? ? 0 ? ? ? ? ?1 ?140000?
3. 转换为张量格式
tensor_ht=torch.tensor(inputs.values)
tensor_bhp=torch.tensor(df_bhp.values)
df_iris.replace({"Species":{'Iris-setosa':0,'Iris-versicolor':1,'Iris-virginica':2}},inplace=True)
tensor_iris=torch.tensor(df_iris.values)
print(tensor_ht)
print(tensor_bhp)
print(tensor_iris)
tensor([[3.0000e+00, 1.0000e+00, 0.0000e+00, 1.2750e+05],
? ? ? ? [2.0000e+00, 0.0000e+00, 1.0000e+00, 1.0600e+05],
? ? ? ? [4.0000e+00, 0.0000e+00, 1.0000e+00, 1.7810e+05],
? ? ? ? [3.0000e+00, 0.0000e+00, 1.0000e+00, 1.4000e+05]], dtype=torch.float64)
tensor([[6.3200e-03, 1.8000e+01, 2.3100e+00, ?..., 1.5300e+01, 4.9800e+00,
? ? ? ? ?2.4000e+01],
? ? ? ? [2.7310e-02, 0.0000e+00, 7.0700e+00, ?..., 1.7800e+01, 9.1400e+00,
? ? ? ? ?2.1600e+01],
? ? ? ? [2.7290e-02, 0.0000e+00, 7.0700e+00, ?..., 1.7800e+01, 4.0300e+00,
? ? ? ? ?3.4700e+01],
? ? ? ? ...,
? ? ? ? [6.0760e-02, 0.0000e+00, 1.1930e+01, ?..., 2.1000e+01, 5.6400e+00,
? ? ? ? ?2.3900e+01],
? ? ? ? [1.0959e-01, 0.0000e+00, 1.1930e+01, ?..., 2.1000e+01, 6.4800e+00,
? ? ? ? ?2.2000e+01],
? ? ? ? [4.7410e-02, 0.0000e+00, 1.1930e+01, ?..., 2.1000e+01, 7.8800e+00,
? ? ? ? ?1.1900e+01]], dtype=torch.float64)
tensor([[1.0000e+00, 5.1000e+00, 3.5000e+00, 1.4000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [2.0000e+00, 4.9000e+00, 3.0000e+00, 1.4000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [3.0000e+00, 4.7000e+00, 3.2000e+00, 1.3000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [4.0000e+00, 4.6000e+00, 3.1000e+00, 1.5000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [5.0000e+00, 5.0000e+00, 3.6000e+00, 1.4000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [6.0000e+00, 5.4000e+00, 3.9000e+00, 1.7000e+00, 4.0000e-01, 0.0000e+00],
? ? ? ? [7.0000e+00, 4.6000e+00, 3.4000e+00, 1.4000e+00, 3.0000e-01, 0.0000e+00],
? ? ? ? [8.0000e+00, 5.0000e+00, 3.4000e+00, 1.5000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [9.0000e+00, 4.4000e+00, 2.9000e+00, 1.4000e+00, 2.0000e-01, 0.0000e+00],
? ? ? ? [1.0000e+01, 4.9000e+00, 3.1000e+00, 1.5000e+00, 1.0000e-01, 0.0000e+00],
? ? ? ?
鸢尾花数据按照{'Iris-setosa':0,'Iris-versicolor':1,'Iris-virginica':2}替换Species列
鸢尾花数据太多,省略了......
??
第一部分张量和算子的概念中,我重新回顾了张量的概念,为本次实验奠定了良好的基础;对于算子,我是第一次了解,虽然本次实验没用到,但是写完这个实验我就会好好了解,不至于下次实验看到算子我就两眼一黑晕过去了。
第二部分中,对照着paddlepaddle的代码改写成pytorch的代码,熟悉了pytorch中tensor的基本用法,了解了paddlepaddle和pytorch的差异,但是在张量的设备位置的代码,查阅了很多资料,我还是没弄明白张量的CPU、GPU和固定内存位置原理和torch代码,希望老师能讲讲。同时,广播机制我也是第一次听说,拓宽了眼界。
第三部分数据预处理,对于Alley的处理,本来是想把空值改为Unknown,后来发现无法转换为张量格式,就借鉴了别人使用get_dummies()用0,1表示。对于NumRooms的处理,本来想把空值替换为0,但在借鉴get_dummies()的同时,发现别人使用means()均值替换空值,瞬间觉得用0替换很不妥,就也用均值替换了。
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年12日历 | -2025/12/14 1:17:04- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |