深度学习与神经网络day02-pytorch入门

今天你学习了没?没学习就学下边的。Now please start your study!


前言

在这之前,我们学习了numpy的基操,学习了在深度学习中用到的python语法。今天的精神粮食是pytorch的入门操作,掌握这些基本操作才能在往后的深度学习中如鱼得水。


一、张量(Tensor)是什么?

课本上的defination是这样的: 张量是矩阵的扩展与延伸,可以认为是高阶的矩阵。
emmm,可能确实不是很好理解,那就用我蹩脚的语言形容一下。
my comprehension: 张量的感觉像是一个无形的容器,他可以容纳任意维的向量和矩阵,也可以容纳多个向量和矩阵,张量的出现是为了数据运算更加方便和快捷。

二、算子(Operator)是什么?

讲完tensor了,得谈谈什么是算子吧。看它的英文单词,不难理解,从广义上讲对于函数的任何一项操作就叫做算子,而在深度学习中,我们常用到的卷积算法、一些求值求和过程也可以抽象的理解为一组操作,也可以叫做算子。毕竟,操作+操作也等于操作嘛。

三、尝试创建张量

我们可以采用Anaconda3下的Jupyter记事本进行实践。

引入torch库

这里就不详细介绍torch的安装,不会的可以参考大佬博客:pytorch安装

import torch

尝试创建张量

1.1指定数据创建张量

#1.2.1 创建张量
#1.2.1.1 指定数据创建张量
#(1)通过指定的Python列表数据[2.0, 3.0, 4.0],创建一个一维张量
tensor1 = torch.tensor([2.0,3.0,4.0])
print(tensor1)
#(2)通过指定的Python列表数据来创建类似矩阵(matrix)的二维张量。
matrix_tensor = torch.tensor([[1.0,2.0,3.0],[4.0,5.0,6.0]])
print(matrix_tensor)
#(3)同样地,还可以创建维度为3、4...N等更复杂的多维张量。
tensor_3_matrix = torch.tensor([[[1.0,2.0,3.0],[4.0,5.0,6.0]],[[7.0,8.0,9.0],[1.0,2.0,3.0]],[[4.0,5.0,6.0],[7.0,8.0,9.0]]])
print(tensor_3_matrix)

代码解释:
①其中tensor1为指定数据的一维张量的创建,我们使用torch.tensor([数据])
②matrix_tensor为指定数据的二维张量的创建,同①。
③tensor_3_matrix为指定数据的三维张量的创建,同①。
Jupyter运行结果示意:
在这里插入图片描述

1.2指定形状创建张量

#1.2.1.2 指定形状创建
m, n = 2, 3
# 使用troch.zeros创建数据全为0,形状为[m, n]的Tensor
zeros_tensor = torch.zeros([m,n])
print(zeros_tensor)
# 使用torch.ones创建数据全为1,形状为[m, n]的Tensor
ones_Tensor = torch.ones([m, n])
print(ones_Tensor)
# 使用torch.full创建数据全为指定值,形状为[m, n]的Tensor,这里我们指定数据为10
full_Tensor = torch.full([m, n], 10)
print(full_Tensor)

代码解释:
①zeros_tensor为m行n列的全为0的张量
②ones_Tensor为m行n列的全为1的张量
③full_Tensor为m行n列的全为10的张量

运行结果示意:
在这里插入图片描述

1.3 指定区间创建

#1.2.1.3 指定区间创建
# 使用torch.arange创建以步长step均匀分隔数值区间[start, end)的一维Tensor
arange_tensor = torch.arange(start=2,end=5,step=1)
print(arange_tensor)
# 使用torch.linspace创建以元素个数steps均匀分隔数值区间[start, end]的Tensor
linspace_Tensor = torch.linspace(start=1, end=7, steps=5)#paddle则使用(start=1,stop=7,num=5)的参数格式
print(linspace_Tensor)

代码解释:
①torch.arange(start,end,step),创建从start开始,end结束,中间步长为step的一维张量。
②torch.linspace(start,end,steps),创建从start开始,end结束,以steps作为总个数均分的一维张量。
运行结果示意:
在这里插入图片描述

四、张量的属性

张量的基本属性

2.1张量的形状

#1.2.2 张量的属性
#1.2.2.1 张量的形状
ndim_4_tensor = torch.tensor([2.0,3.0,4.0,5.0])#转为张量
print("Number of dimensions:",ndim_4_tensor.ndim)
print("Shape of Tensor:",ndim_4_tensor.shape)
print("Elements number along axis 0 of Tensor:",ndim_4_tensor.shape[0])
print("Elements number along the last axis of Tensor:", ndim_4_tensor.shape[-1])
print('Number of elements in Tensor: ', ndim_4_tensor.size)

代码解释:
①ndim_4_tensor.ndim: 即ndim_4_tensor这个张量的维度。
②ndim_4_tensor.shape: 即ndim_4_tensor这个张量的大小。
③ndim_4_tensor.shape[0]: 即ndim_4_tensor这个张量的大小中的第一个数。(当张量是多维时,会出现张量的大小是一个一维张量,从而确定每个维度下的个数和多少个维度。)
④ndim_4_tensor.shape[0]: 即ndim_4_tensor这个张量的大小中的最后一个数。
运行结果示意:
在这里插入图片描述

2.2形状的改变

#1.2.2.2 形状的改变
# 定义一个shape为[3,2,5]的三维Tensor
ndim_3_Tensor = 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 ndim_3_Tensor:", ndim_3_Tensor.shape)
# torch.reshape 可以保持在输入数据不变的情况下,改变数据形状。这里我们设置reshape为[2,5,3]
reshape_Tensor = torch.reshape(ndim_3_Tensor, [2, 5, 3])
print("After reshape:\n", reshape_Tensor)
"""
    paddle使用reshape的一些技巧:
    ①-1表示这个维度的值是从张量的元素总数和剩余维度推断出来的。因此,有且只有一个维度可以被设置为-1。
    ②0表示实际的维数是从张量的对应维数中复制出来的,因此shape中0所对应的索引值不能超过张量的总维度。
"""
#在这里用pytorch对reshape实现的两个example:
new_Tensor1 = ndim_3_Tensor.reshape([-1])
print('new Tensor 1 shape: ', new_Tensor1.shape)
#reshape表示的是转成[1,5,6]的三维张量的大小
new_Tensor2 = ndim_3_Tensor.reshape((1, 5, 6))
print('new Tensor 2 shape: ', new_Tensor2.shape)

#torch.unsqueeze的参数解析:(input,dim,out=None)
#torch.unsqueeze作用是用来扩展维度的,其中:
    #input表示输入的参数即某个张量
    #dim表示插入维度的索引(在哪儿插入维度1?)
    #out表示结果张量
ones_Tensor = torch.ones([5, 10])
new_Tensor1 = torch.unsqueeze(ones_Tensor, dim=0)
print('new Tensor 1 shape: ', new_Tensor1.shape)
new_Tensor2 = torch.unsqueeze(ones_Tensor, dim=1)
print('new Tensor 2 shape: ', new_Tensor2.shape)

代码解释:
①ndim_3_tensor是一个定义了的三维张量。
②torch.reshape(tensor,shape)将tensor的形状变为规定的shape的形状。
③torch.unsqueeze(input,dim)的作用是用来扩展维度的,其中input输入为一个tensor.dim则表示插入维度的索引值(即在哪儿插入?),插入维度1

运行结果示意:
在这里插入图片描述

2.3张量的数据类型

#1.2.2.3 张量的数据类型
# 使用torch.tensor通过已知数据来创建一个Tensor
print("Tensor dtype from Python integers:", torch.tensor(1).dtype)
print("Tensor dtype from Python floating point:", torch.tensor(1.0).dtype)

# 定义dtype为float32的Tensor
float32_Tensor = torch.tensor(1.0)
print(float32_Tensor)
# 在torch中某个tensor.int()或者tensor.float()可以将输入数据的数据类型转换为int/float并输出。支持输出和输入数据类型相同。
int64_Tensor = float32_Tensor.int()
print("Tensor after cast to int64:",int64_Tensor)

代码解释:
①torch.tensor().dtype:返回tensor中元素的类型
②转化类型可以使用.int()、.float()、.double()
运行结果示意:
在这里插入图片描述

2.4张量的设备位置

#1.2.2.4 张量的设备位置
# 创建CPU上的Tensor
cpu_Tensor = torch.tensor(1, dtype=torch.int32, device = torch.device('cpu'))
# 通过Tensor.device查看张量所在设备位置
print('cpu Tensor: ', cpu_Tensor.device)
# 创建GPU上的Tensor
gpu_Tensor = torch.tensor(1, dtype=torch.int32, device = torch.device('cuda',0))
print('gpu Tensor: ', gpu_Tensor.device)
# 创建固定内存上的Tensor
pin_memory_Tensor = torch.tensor(1, dtype=torch.int32, device = torch.device('cuda'))
print('pin memory Tensor: ', pin_memory_Tensor.device)

代码解释:
①torch.tensor(input,dtype,device):input表示输入,dtype表示类型,device表示存放位置,采用torch.device(‘cpu’)放入cpu中。
②放入cuda中同上
运行结果示意:
在这里插入图片描述

一个特别说明

由于我这个电脑是比较菜的(人比较菜计算了,电脑还菜,你说这这这找谁说理去?我真的栓Q,所以你们凑合看吧。),电脑未配置CUDA所以这里会报错,如果安装了CUDA就不会报错了。这里就放一个反面例子吧。

五、张量与Numpy数组转换

张量与Numpy数组之间的转换

#1.2.3 张量与Numpy数组转换
ndim_1_Tensor = torch.tensor([1., 2.])
# 将当前 Tensor 转化为 numpy.ndarray
print('Tensor to convert: ', ndim_1_Tensor.numpy())

代码解释:
直接使用ndim_1_Tensor.numpy()转为numpy数组。
运行结果示意:
在这里插入图片描述

六、张量的访问

张量的访问方法

3.1 索引和切片

“”"
通过冒号“:”分隔切片参数start:stop:step来进行切片操作,也就是访问start到stop范围内的部分元素并生成一个新的序列。
其中start为切片的起始位置,stop为切片的截止位置,step是切片的步长,这三个参数均可缺省。
“”"

3.2 访问张量

#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)#打印tensor
print("First element:", ndim_1_Tensor[0])#获取tensor中的第0个位置上的索引
print("Last element:", ndim_1_Tensor[-1])#获取tensor中最后一个位置上的索引
print("All element:", ndim_1_Tensor[:])#获取tensor的全部值序列
print("Before 3:", ndim_1_Tensor[:3])#获取从开始到位置3(不包括位置3)的全部值序列
print("Interval of 3:", ndim_1_Tensor[::3])#从开始到结束,从0开始,每次位置+3获取值序列
print("Reverse:", ndim_1_Tensor.flip(dims=[0]))#函数flip可以实现对某一维的数据进行翻转其中,dims=[x1,x2,...]控制的哪一维进行翻转
print("**************分割线**************")
# 定义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)#打印tensor
print("First row:", ndim_2_Tensor[0])#获取二维张量的第一行
print("First row:", ndim_2_Tensor[0, :])#获取二维张量中第一行的全部值序列
print("First column:", ndim_2_Tensor[:, 0])#获取所有行中的第一个值,作为值序列的tensor输出
print("Last column:", ndim_2_Tensor[:, -1])#获取所有行中的最后一个值,作为值序列的tensor输出
print("All element:", ndim_2_Tensor[:])#获取所有行
print("First row and second column:", ndim_2_Tensor[0, 1])#获取tensor中第一行第二列的某个值

代码解释:这里直接看代码注释即可(可能是UP累了。)
运行结果示意:
在这里插入图片描述

3.3 修改张量

#1.2.4.3 修改张量
# 定义1个二维Tensor
ndim_2_Tensor = torch.ones([2,3], dtype=torch.float)
print('Origin Tensor: ', ndim_2_Tensor)#获取ndim_2_Tensor
# 修改第1维为0
ndim_2_Tensor[0] = 0#将第一位的值改为0
print('change Tensor: ', ndim_2_Tensor)
# 修改第1维为2.1
ndim_2_Tensor[0:1] = 2.1#将第从0到1行(不包括一行)的值
print('change Tensor: ', ndim_2_Tensor)
# 修改全部Tensor
ndim_2_Tensor[...] = 3#将全部值改为3
print('change Tensor: ', ndim_2_Tensor)

代码解释:看注释即可。
运行结果示意:
在这里插入图片描述

七、张量的运算

张量的运算

4.1基本运算

# 定义两个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)
# 第一种调用方法,paddle.add逐元素相加算子,并将各个位置的输出元素保存到返回结果中
print('Method 1: ', torch.add(x, y))
# 第二种调用方法
print('Method 2: ', x.add(y))
print("***********分割线*************")
print(x.abs())                       # 逐元素取绝对值
print(x.ceil())                      # 逐元素向上取整
print(x.floor())                     # 逐元素向下取整
print(x.round())                     # 逐元素四舍五入
print(x.exp())                       # 逐元素计算自然常数为底的指数
print(x.log())                       # 逐元素计算x的自然对数
print(x.reciprocal())                # 逐元素求倒数
print(x.square())                    # 逐元素计算平方
print(x.sqrt())                      # 逐元素计算平方根
print(x.sin())                       # 逐元素计算正弦
print(x.cos())                       # 逐元素计算余弦
print(x.add(y))                      # 逐元素加
print(x.subtract(y))                 # 逐元素减
print(x.multiply(y))                 # 逐元素乘(积)
print(x.divide(y))                   # 逐元素除
print(x.fmod(y))                      # 逐元素除并取余
print(x.pow(y))                      # 逐元素幂
print(x.max())                       # 指定维度上元素最大值,默认为全部维度
print(x.min())                       # 指定维度上元素最小值,默认为全部维度
print(x.prod())                      # 指定维度上元素累乘,默认为全部维度
print(x.sum())                       # 指定维度上元素的和,默认为全部维度
print("***********分割线*************")
print(x + y);print(x.add(y))            # 逐元素加
print(x - y);print(x.subtract(y))       # 逐元素减
print(x * y);print(x.multiply(y))       # 逐元素乘(积)
print(x / y);print(x.divide(y))         # 逐元素除
print(x % y);print(x.fmod(y))            # 逐元素除并取余
print(x ** y);print(x.pow(y))            # 逐元素幂
print("***********分割线*************")
print(x.isfinite())                  # 判断Tensor中元素是否是有限的数字,即不包括inf与nan
print(x.equal(y))                # 判断两个Tensor的全部元素是否相等,并返回形状为[1]的布尔类Tensor
print(x.equal(y))                    # 判断两个Tensor的每个元素是否相等,并返回形状相同的布尔类Tensor
print(x.not_equal(y))                # 判断两个Tensor的每个元素是否不相等
print(x.gt(y))                # 判断Tensor x的元素是否小于Tensor y的对应元素
print(x.less_equal(y))               # 判断Tensor x的元素是否小于或等于Tensor y的对应元素
print(x.gt(y))             # 判断Tensor x的元素是否大于Tensor y的对应元素
print(x.greater_equal(y))            # 判断Tensor x的元素是否大于或等于Tensor y的对应元素
print(x.allclose(y))                 # 判断两个Tensor的全部元素是否接近

代码解释:见注释
运行结果:
长图片:张量的运算

4.2矩阵运算

#1.2.5.3 矩阵运算
print(x.t())                         # 矩阵转置
print(x.transpose(1, 0))           # 交换第 0 维与第 1 维的顺序
print(x.norm('fro'))                 # 矩阵的弗罗贝尼乌斯范数
print(x.dist(y, p=2))                # 矩阵(x-y)的2范数
print(x.matmul(y))                   # 矩阵乘法

代码解释:
x.transpose(dim0,dim1):交换dim0和dim1这两个维度。
运行结果示意:
在这里插入图片描述

4.3 广播机制

#1.2.5.4 广播机制
# 当两个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)

"""x = torch.ones((2, 3, 4))
y = torch.ones((2, 3, 6))
z = x + y
#会输出关于dimension mismatch的错误"""

x = torch.ones([10, 1, 5, 2])
y = torch.ones([3, 2, 5])
z = torch.matmul(x, y)
print('After matmul: ', z.shape)

运行结果示意:
在这里插入图片描述

八、数据预处理

操作一个简单的数据集

5.1写一个简单的数据集

import os

os.makedirs(os.path.join('C:\\Users\\86155', 'data'), exist_ok=True)
data_file = os.path.join('C:\\Users\\86155', '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')

5.2处理数据集中的缺失值

import pandas as pd

data = pd.read_csv(data_file)
print(data)
#因为自制数据的数据量较小,所以我们使用插值法处理缺失值
inputs,outputs = data.iloc[:,0:2],data.iloc[:,2]#将数据集划分为属性和标签
inputs = inputs.fillna(inputs.mean())#将连续属性中取值为NaN的值取值为该属性的均值
print(inputs)
inputs = pd.get_dummies(inputs, dummy_na=True)#将离散属性中的属性值分开来写,化为Alley_Pave和Alley_NaN的形式
print(inputs)

5.3数据转化为张量格式

#将数据转化为张量格式
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
X, y

全部Code结果:
在这里插入图片描述

读入两个数据集

读入数据集boston_house_prices.csv和Iris.csv

#读入数据集boston_house_prices.csv
datafile_boston = os.path.join("C:\\Users\\86155",'data','boston_house_prices.csv')
data_boston = pd.read_csv(datafile_boston)
#读入数据集Iris.csv
datafile_iris = os.path.join("C:\\Users\\86155",'data','Iris.csv')
data_iris = pd.read_csv(datafile_iris)

九、总结

首先,我们知道了什么是张量,什么是算子。
其次,我们知道了如何用torch去创建张量,并讲了一下张量有什么属性。
然后,我们应该打好对于张量运算的基本操作,我觉得这部分应该是深度学习的基础,所以要扎实一些。
最后,我们讲了数据集的预处理,然后对于缺失值的处理和如何将数据转化为张量格式,方便以后进行数据运算。
这就是day02的全部内容,简单总结一下,就是pytorch的基本操作还是要扎实一些,就比如pytorch的张量的数据类型转化用的则是torch.float32这种,而之前则只是直接int()。
老师的出题博客:NNDL 实验二 pytorch入门可以关注一下。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鬼缠身、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值