深度学习—实验二 练习张量

本文介绍了深度学习框架中张量的基本概念,包括张量的定义、创建方式(指定数据、形状、区间)、属性(形状、类型、设备位置),以及张量与Numpy数组的转换。此外,文章详细讲解了张量的索引、切片、运算(加法、逻辑、矩阵)和广播机制,以及数据预处理中的CSV读取、缺失值处理和张量化过程。
摘要由CSDN通过智能技术生成

在深度学习框架中,数据经常用张量(Tensor)的形式来存储。张量是矩阵的扩展与延伸,可以认为是高阶的矩阵。1阶张量为向量,2阶张量为矩阵。如果你对Numpy熟悉,那么张量是类似于Numpy的多维数组(ndarray)的概念,可以具有任意多的维度。

张量的大小可以用形状(shape)来描述。比如一个三维张量的形状是 [2,2,5][2,2,5],表示每一维(也称为轴(axis))的元素的数量,即第0轴上元素数量是2,第1轴上元素数量是2,第2轴上的元素数量为5。

图1.5给出了3种纬度的张量可视化表示。

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

1.2.1.1 指定数据创建张量

1)通过指定的Python列表数据[2.0, 3.0, 4.0],创建一个一维张量。

# 导入torch
import torch
# 创建一维Tensor
from numpy import shape
data = torch.Tensor([2.0,3.0,4.0])
print(data)
print(shape(data))
print(data.dtype)

(2)通过指定的Python列表数据来创建类似矩阵(matrix)的二维张量。

# 导入torch
import torch
# 创建一维Tensor
from numpy import shape
data = torch.Tensor([[1.0,2.0,3.0],[4.0,5.0,6.0]])
print(data)
print(shape(data))
print(data.dtype)

(3)同样地,还可以创建维度为3、4...N等更复杂的多维张量。

# 导入torch
import torch
# 创建一维Tensor
from numpy import shape
data = torch.Tensor([[[1, 2, 3, 4, 5],
                                   [6, 7, 8, 9, 10]],
                                  [[11, 12, 13, 14, 15],
                                   [16, 17, 18, 19, 20]]])
print(data)
print(shape(data))
print(data.dtype)

1.2.1.2 指定形状创建
# 导入torch
import torch
m,n=2,3
zeros_tensor=torch.zeros([m,n])
ones_tensor=torch.ones([m,n])
full_tensor=torch.full([m,n],10)
print('zeros tensor',zeros_tensor)
print('ones tensor',ones_tensor)
print('full tensor',full_tensor)

1.2.1.3 指定区间创建
# 导入torch
import torch
m,n=2,3
arange_tensor=torch.arange(start=1,end=5,step=1)
linspace_tensor=torch.linspace(1,5,5)
print('arange tensor',arange_tensor,arange_tensor.shape,arange_tensor.dtype)
print('linspace tensor',linspace_tensor,linspace_tensor.shape,linspace_tensor.dtype)

1.2.2 张量的属性

1.2.2.1 张量的形状

    张量具有如下形状属性:

  • Tensor.ndim:张量的维度,例如向量的维度为1,矩阵的维度为2。
  • Tensor.shape: 张量每个维度上元素的数量。
  • Tensor.shape[n]:张量第n维的大小。第n维也称为轴(axis)。
  • Tensor.size:张量中全部元素的个数。

为了更好地理解ndim、shape、axis、size四种属性间的区别,创建一个四维张量。

# 导入torch
import torch
ndim_4_Tensor = torch.ones([2, 3, 4, 5])

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)

1.2.2.2 形状的改变
# 导入torch
import torch
# 定义一个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:", reshape_Tensor)

 torch.reshape 可以保持在输入数据不变的情况下,改变数据形状。

new_Tensor2 = ndim_3_Tensor.reshape([-1, 5, 2])中-1的值:总元素的个数/其他维度的个数

分别对上文定义的ndim_3_Tensor进行reshape为[-1]和reshape为[0, 5, 2]两种操作,观察新张量的形状。

new_Tensor1 = ndim_3_Tensor.reshape([-1])
print('new Tensor 1 shape: ', new_Tensor1.shape)
new_Tensor2 = ndim_3_Tensor.reshape([-1, 5, 2])
print('new Tensor 2 shape: ', new_Tensor2.shape)

1.2.2.3 张量的数据类型

1)通过Python元素创建的张量,可以通过dtype来指定数据类型,如果未指定:

  • 对于Python整型数据,则会创建int64型张量。
  • 对于Python浮点型数据,默认会创建float32型张量。
  • 可以使用torch.dtype查看数据类型
import torch
# 使用paddle.to_tensor通过已知数据来创建一个Tensor
# 定义一个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("Tensor dtype from Python integers:",ndim_3_Tensor.dtype)
print("Tensor dtype from Python floating point:",ndim_3_Tensor.dtype)

1.2.2.4 张量的设备位置

可以用device函数查看位置

import torch
data = torch.ones([2, 3])
print(data.device)

1.2.3 张量与Numpy数组转换

import torch
ndim_1_Tensor = torch.tensor([1, 2])
# 将当前 Tensor 转化为 numpy.ndarray
print('Tensor to convert: ', ndim_1_Tensor.numpy())

1.2.4 张量的访问

1.2.4.1 索引和切片
  • 基于0−n的下标进行索引,如果下标为负数,则从尾部开始计算。
  • 通过冒号“:”分隔切片参数start:stop:step来进行切片操作,也就是访问start到stop范围内的部分元素并生成一个新的序列。其中start为切片的起始位置,stop为切片的截止位置,step是切片的步长,这三个参数均可缺省。
1.2.4.2 访问张量

针对一维张量,对单个轴进行索引和切片。

import torch
# 定义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:", ndim_1_Tensor.flip(-1))

针对二维及以上维度的张量,在多个维度上进行索引或切片

import torch
# 定义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])

 

1.2.4.3 修改张量 

与访问张量类似,可以在单个或多个轴上通过索引或切片操作来修改张量。

import torch
# 定义1个二维Tensor
ndim_2_Tensor = torch.ones([2, 3])
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)

1.2.5 张量的运算

以加法为例子

1、torch.add(x,y)

2、a.add(y)

import torch
# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]])
# 第一种调用方法,torch.add逐元素相加算子,并将各个位置的输出元素保存到返回结果中
print('Method 1: ', torch.add(x, y))
# 第二种调用方法
print('Method 2: ', x.add(y))

 

张量类的基础数学函数如下:

x.abs()                       # 逐元素取绝对值
x.ceil()                      # 逐元素向上取整
x.floor()                     # 逐元素向下取整
x.round()                     # 逐元素四舍五入
x.exp()                       # 逐元素计算自然常数为底的指数
x.log()                       # 逐元素计算x的自然对数
x.reciprocal()                # 逐元素求倒数
x.square()                    # 逐元素计算平方
x.sqrt()                      # 逐元素计算平方根
x.sin()                       # 逐元素计算正弦
x.cos()                       # 逐元素计算余弦
x.add(y)                      # 逐元素加
x.subtract(y)                 # 逐元素减
x.multiply(y)                 # 逐元素乘(积)
x.divide(y)                   # 逐元素除
x.mod(y)                      # 逐元素除并取余
x.pow(y)                      # 逐元素幂
x.max()                       # 指定维度上元素最大值,默认为全部维度
x.min()                       # 指定维度上元素最小值,默认为全部维度
x.prod()                      # 指定维度上元素累乘,默认为全部维度
x.sum()                       # 指定维度上元素的和,默认为全部维度

同时,为了更方便地使用张量,飞桨对Python数学运算相关的魔法函数进行了重写,以下操作与上述结果相同。

x + y  -> x.add(y)            # 逐元素加
x - y  -> x.subtract(y)       # 逐元素减
x * y  -> x.multiply(y)       # 逐元素乘(积)
x / y  -> x.divide(y)         # 逐元素除
x % y  -> x.mod(y)            # 逐元素除并取余
x ** y -> x.pow(y)            # 逐元素幂
import torch
# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]])
print("加法运算结果:", x + y)
print("减法运算结果:", x - y)
print("乘法运算结果:", x * y)
print("除法运算结果:", x / y)
print("幂运算结果:", x ** y)

 

1.2.5.2 逻辑运算

import torch
# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]])
print("判断两个张量对应位置元素是否相同:", x == y)

 

 1.2.5.3 矩阵运算

import torch
# 定义两个Tensor
x = torch.tensor([[1.1, 2.2], [3.3, 4.4]])
y = torch.tensor([[5.5, 6.6], [7.7, 8.8]])
print("按行连结结果", torch.cat((x, y), dim=0))
print("按列连结结果:", torch.cat((x, y), dim=1))

1.2.5.4 广播机制

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

广播机制的条件

飞桨的广播机制主要遵循如下规则(参考Numpy广播机制):

1)每个张量至少为一维张量。

2)从后往前比较张量的形状,当前维度的大小要么相等,要么其中一个等于1,要么其中一个不存在。

import torch
# 当两个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)

 

广播机制的计算规则

现在我们知道在什么情况下两个张量是可以广播的。两个张量进行广播后的结果张量的形状计算规则如下:

1)如果两个张量shape的长度不一致,那么需要在较小长度的shape前添加1,直到两个张量的形状长度相等。

2) 保证两个张量形状相等之后,每个维度上的结果维度就是当前维度上较大的那个。

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

1.2.6数据预处理

1. 读取数据集 house_tiny.csv、boston_house_prices.csv、Iris.csv

pandas库可用于读取xls,csv,txt多种文件,在此用于读取csv文件导入pandas

import pandas as pd
data_file1 = r"C:\Users\hp\Desktop\house_tiny.csv"
data_file2 = r"C:\Users\hp\Desktop\boston_house_prices.csv"
data_file3 = r"C:\Users\hp\Desktop\Iris.csv"
data1 = pd.read_csv(data_file1)
data2 = pd.read_csv(data_file2)
data3 = pd.read_csv(data_file3)
# print(data1)
print(data3)
# print(data3)

 

2. 处理缺失值

常用函数

  • df.isnull()、df.notnull():两个函数互为取反
  • df.isna():等同于df.isnull()
  • df.dropna():删除缺失值
  • df.fillna():填充缺失值

df.isnull():是缺失值为True,反之为False

 下述代码可以查看缺失值

import pandas as pd
data_file1 = r"C:\Users\hp\Desktop\house_tiny.csv"
data_file2 = r"C:\Users\hp\Desktop\boston_house_prices.csv"
data_file3 = r"C:\Users\hp\Desktop\Iris.csv"
data1 = pd.read_csv(data_file1)
data2 = pd.read_csv(data_file2)
data3 = pd.read_csv(data_file3)
print(data1.isnull())
print(data2.isnull())
print(data3.isnull())

3、将缺失的数据补齐 
inputs, outputs = data1.iloc[:, 0:2], data1.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())  # 用输入的平均值填充NA
# Alley作为string没有均值,使用one hot编码
inputs = pd.get_dummies(inputs, dummy_na=True)
inputs['Price']=data1['Price']
print(inputs)

 

4、转换为张量格式
import pandas as pd
import torch
data_file1 = r"C:\Users\hp\Desktop\house_tiny.csv"
data_file2 = r"C:\Users\hp\Desktop\boston_house_prices.csv"
data_file3 = r"C:\Users\hp\Desktop\Iris.csv"
data1 = pd.read_csv(data_file1)
data2 = pd.read_csv(data_file2)
data3 = pd.read_csv(data_file3)
data3.replace({"Species":{'Iris-setosa':0,'Iris-versicolor':1,'Iris-virginica':2}},inplace=True)
tensor_iris=torch.tensor(data3.values)
print(tensor_iris)

 只展示部分结果

1.2.7实验心得

1、new_Tensor2 = ndim_3_Tensor.reshape([-1, 5, 2])中-1的值:总元素的个数/其他维度的个数

2、张量在任何一个维度上的元素数量必须相等

3、平时在python中让一个数组发生反转,一般用reverse()函数,在张量中不能用reverse()会报错,用flip()函数。

4、注意:广播机制中是从后往前比较,缺少的部分用1代替

例如:对应位置进行相加运算,结果的shape是:x.shape和y.shape对应位置的最大值,比如:x.shape=(2,3,1,5),y.shape=(3,4,1),那么A+B的shape是(2,3,4,5)

5、不匹配的两个矩阵,如果让它们相加,它们的形状不匹配。 我们将两个矩阵广播为一个更大的矩阵,如上所示:矩阵a将复制列, 矩阵b将复制行,然后再按元素相加

6、数据预处理很多函数的具体使用方法可以csdn

df.isnull()、df.notnull():两个函数互为取反

df.isna():等同于df.isnull()

df.dropna():删除缺失值

df.fillna():填充缺失值

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值