关于深度学习的基础的Python知识(PyTorch)

文章目录

  • 关于深度学习的基础的Python知识(PyTorch)
  • 一、概念:张量
  • 1、张量的定义:
  • 2、个人理解:
  • 二.、使用PyTorch实现张量运算
  • 1、创建张量
  • (1)以指定数据创建张量(以三阶张量为例)
  • (2)指定形状创建张量
  • 2、张量的属性
  • (1)张量的形状属性
  • (2)张量形状的改变
  • (3)张量的数据类型
  • (4)张量的设备位置
  • 3、张量与Numpy数组转换
  • 4、张量的访问
  • (1)索引和切片
  • (2)访问张量
  • (3)修改张量
  • 5、张量的运算
  • (1)数学运算
  • (2)逻辑运算
  • 三、数据预处理
  • 1、读取数据集 house_tiny.csv、boston_house_prices.csv、Iris.csv
  • 2、处理缺失值
  • 3、转换为张量格式
  • 关于深度学习的基础的Python知识(PyTorch)


    一、概念:张量

    1、张量的定义:

    张量是矩阵的扩展与延伸,可以认为是高阶的矩阵。1阶张量为向量,2阶张量为矩阵。张量是类似于Numpy的多维数组(ndarray)的概念,可以具有任意多的维度。

    img

    (图片来自邱锡鹏老师和飞桨的《神经网络与深度学习:案例与实践》)

    2、个人理解:

    张量是用向量组成的维度空间的实体,可以很方便地存放各式各样的信息。

    二.、使用PyTorch实现张量运算

    首先导入torch

    import torch
    
    1、创建张量
    (1)以指定数据创建张量(以三阶张量为例)
    # 创建一个三阶张量(指定数据创建张量)
    ndim_1_Tensor = torch.tensor([[[1, 9], [6, 3]], [[0, 1], [2, 8]]])
    print(ndim_1_Tensor)
    

    运行结果:

    (2)指定形状创建张量
    # 指定形状创建
    size = ndim_1_Tensor.size()
    zero_Tensor = torch.zeros(size)  # 全零张量
    print(zero_Tensor)
    one_Tensor = torch.ones(size)  # 全一张量
    print(one_Tensor)
    full_Tensor = torch.full(size, 10)  #指定数据
    print(full_Tensor)
    

    运行结果:

    2、张量的属性
    (1)张量的形状属性

    张量具有如下形状属性:

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

    (图片来自邱锡鹏老师和飞桨的《神经网络与深度学习:案例与实践》)

    创建如图张量:

    ndim_4_Tensor = torch.ones([2, 3, 4, 5])  # 创建一个每个维度的宽度分别为2,3,4,5的4维张量
    

    打印出此向量的shapendimshape[n]numel()属性:

    # 打印出此向量的`shape`、`ndim`、`shape[n]`、`numel()`属性
    print("shape:", ndim_4_Tensor.shape)
    print("ndim:", ndim_4_Tensor.ndim)
    print("shape[2]:", ndim_4_Tensor.shape[1])
    print("numel:", ndim_4_Tensor.numel())
    

    运行结果:

    (2)张量形状的改变

    在实际使用中,还可以通过使用torch.reshape接口来改变张量的形状:

    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("shape:", ndim_3_Tensor.shape)
    # 改变数据形状
    reshape_Tensor = torch.reshape(ndim_3_Tensor, [2, 5, 3])
    print("After reshape:", reshape_Tensor)
    

    运行结果:

    可以看到,通过此接口改变张量的形状后,张量内部的数据顺序是不变的。

    除使用torch.reshape进行张量形状的改变外,还可以通过torch.unsqueeze将张量中的某一维度中插入尺寸为1的维度:

    ones_Tensor = torch.ones([5, 10])
    new_Tensor1 = torch.unsqueeze(ones_Tensor, dim=0)
    print('new shape: ', new_Tensor1.shape)
    

    运行结果

    其他技巧:

    reshape值设为-1,使张量变为一维:

    new_Tensor1 = ndim_3_Tensor.reshape(-1)
    print('new shape: ', new_Tensor1.shape)
    

    运行结果:

    (3)张量的数据类型

    通过Tensor.dtype可以查看张量的数据类型:

    Tensor1 = torch.ones([2, 3, 4, 5])
    print("data type: ", Tensor1.dtype)
    

    运行结果:

    通过Numpy数组创建的张量,则与其原来的数据类型保持相同。通过torch.tensor()函数可以将Numpy数组转化为张量:

    # 使用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)
    

    运行结果:

    如果想改变张量的数据类型,可以通过Tensor.to或者Tensor.type来实现:

    # 定义dtype为float32的Tensor
    float32_Tensor = torch.tensor(1.0)
    # Tensor.to或Tensor.type可以将输入数据的数据类型转换为指定的dtype并输出。支持输出和输入数据类型相同。
    float32_Tensor = float32_Tensor.to(torch.int64)
    print("Tensor after change to int64:", float32_Tensor.dtype)
    float32_Tensor = float32_Tensor.type(torch.float32)
    print("Tensor after change to float32:", float32_Tensor.dtype)
    

    运行结果:

    (4)张量的设备位置

    初始化张量时可以通过device来指定其分配的设备位置。

    如下代码分别创建了CPU和GPU上的张量,并通过Tensor.device查看张量所在的设备位置:

    # 创建CPU上的Tensor
    cpu_Tensor = torch.tensor(1, device=torch.device('cpu'))
    # 通过Tensor.device查看张量所在设备位置
    print('cpu Tensor: ', cpu_Tensor.device)
    # 创建GPU上的Tensor
    gpu_Tensor = torch.tensor(1, device=torch.device('cuda'))
    # 通过Tensor.device查看张量所在设备位置
    print('gpu Tensor: ', gpu_Tensor.device)
    

    运行结果:

    此外,通过通过Tensor.to还可以改变张量所在的设备位置:

    gpu_Tensor2 = cpu_Tensor.to('cuda')
    print('gpu Tensor: ', gpu_Tensor2.device)
    

    运行结果:

    3、张量与Numpy数组转换

    张量和Numpy数组可以相互转换。使用Numpy数组生成张量之前就已经使用过,现在主要探讨将张量转化为Numpy数组:

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

    运行结果:

    4、张量的访问
    (1)索引和切片

    在PyTorch中,我们可以通过索引或切片方便地访问或修改张量。PyTorch使用标准的Python索引规则与NumPy索引规则,具有以下特点:

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

    运行结果:

    注意,PyTorch不允许以这种方式来进行翻转操作:

    print("Reverse:", ndim_1_Tensor[::-1])
    

    报错:

    翻转操作应该使用torch.flip

    print("Reverse:", torch.flip(ndim_1_Tensor, dims=[0]))
    

    运行结果:

    dims指的是翻转的维度。

    针对二维及以上维度的张量,在多个维度上进行索引或切片。索引或切片的第一个值对应第0维,第二个值对应第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])
    

    运行结果:

    (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)
    

    运行结果:

    5、张量的运算

    张量支持包括基础数学运算、逻辑运算、矩阵运算等100余种运算操作,以加法为例,有如下两种实现方式:

    1)使用PyTorch API torch.add(x,y)
    2)使用张量类成员函数x.add(y)

    # 定义两个Tensor
    x = torch.tensor([[1.1, 2.2], [3.3, 4.4]], dtype=torch.float32)
    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))
    

    运行结果:

    (1)数学运算

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

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

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

    x + y  -> x.add(y)            # 逐元素加
    x - y  -> x.sub(y)            # 逐元素减
    x * y  -> x.mul(y)            # 逐元素乘(积)
    x / y  -> x.div(y)            # 逐元素除
    x % y  -> x.fmod(y)           # 逐元素除并取余
    x ** y -> x.pow(y)            # 逐元素幂
    

    测试代码:

    # 创建张量x和y
    x = torch.tensor([[1, 1], [4, 5], [1, 4]], dtype=torch.float32)
    y = torch.tensor([[1, -2], [3, -4], [5, -6]], dtype=torch.float64)
    
    # 打印张量x和y
    print("x : ", x)
    print("y : ", y)
    
    # 测试逐元素取绝对值
    print("x.abs() : ", x.abs())
    
    # 测试逐元素向上取整
    print("x.ceil() : ", x.ceil())
    
    # 测试逐元素向下取整
    print("x.floor() : ", x.floor())
    
    # 测试逐元素四舍五入
    print("x.round() : ", x.round())
    
    # 测试逐元素计算自然常数为底的指数
    print("x.exp() : ", x.exp())
    
    # 测试逐元素计算自然对数
    print("x.log() : ", x.log())
    
    # 测试逐元素求倒数
    print("x.reciprocal() : ", x.reciprocal())
    
    # 测试逐元素计算平方
    print("x.square() : ", x.square())
    
    # 测试逐元素计算平方根
    print("x.sqrt() : ", x.sqrt())
    
    # 测试逐元素计算正弦
    print("x.sin() : ", x.sin())
    
    # 测试逐元素计算余弦
    print("x.cos() : ", x.cos())
    
    # 测试逐元素加法
    print("x + y : ", x + y)
    
    # 测试逐元素减法
    print("x - y : ", x - y)
    
    # 测试逐元素乘法
    print("x * y : ", x * y)
    
    # 测试逐元素除法
    print("x / y : ", x / y)
    
    # 测试逐元素取余
    print("x % y : ", x % y)
    
    # 测试逐元素幂运算
    print("x ** y : ", x ** y)
    
    # 测试指定维度上的元素最大值
    print("x.max(dim=1) : ", x.max(dim=1))
    
    # 测试指定维度上的元素最小值
    print("x.min(dim=1) : ", x.min(dim=1))
    
    # 测试指定维度上的元素均值
    print("x.mean(dim=1) : ", x.mean(dim=1))
    
    # 测试指定维度上的元素和
    print("x.sum(dim=1) : ", x.sum(dim=1))
    
    # 测试指定维度上的元素乘积
    print("x.prod(dim=1) : ", x.prod(dim=1))
    

    运行结果:

    (2)逻辑运算

    在 PyTorch 中,张量类的逻辑运算和矩阵运算函数如下:

    # 逻辑运算函数
    x.isfinite()                  # 判断Tensor中元素是否是有限的数字,即不包括inf与nan
    x.equal_all(y)                # 判断两个Tensor的全部元素是否相等,并返回形状为[1]的布尔类Tensor
    x.equal(y)                    # 判断两个Tensor的每个元素是否相等,并返回形状相同的布尔类Tensor
    x.not_equal(y)                # 判断两个Tensor的每个元素是否不相等
    x.less_than(y)                # 判断Tensor x的元素是否小于Tensor y的对应元素
    x.less_equal(y)               # 判断Tensor x的元素是否小于或等于Tensor y的对应元素
    x.greater_than(y)             # 判断Tensor x的元素是否大于Tensor y的对应元素
    x.greater_equal(y)            # 判断Tensor x的元素是否大于或等于Tensor y的对应元素
    x.allclose(y)                 # 判断两个Tensor的全部元素是否接近
    
    # 矩阵运算函数
    x.t()                         # 矩阵转置
    x.transpose([1, 0])           # 交换第 0 维与第 1 维的顺序
    x.norm('fro')                 # 矩阵的弗罗贝尼乌斯范数
    x.dist(y, p=2)                # 矩阵(x-y)的2范数
    x.matmul(y)                   # 矩阵乘法
    
    # 对于多维张量的矩阵乘法,例如x是形状为[j, k, n, m]的张量,另一个y是[j, k, m, p]的张量
    # 则x.matmul(y)输出的张量形状为[j, k, n, p]
    

    三、数据预处理

    1、读取数据集 house_tiny.csv、boston_house_prices.csv、Iris.csv
    # 1. 读取数据集 house_tiny.csv
    house_tiny_path = 'house_tiny.csv'
    process_dataset(house_tiny_path)
    
    # 2. 读取数据集 boston_house_prices.csv
    boston_house_prices_path = 'boston_house_prices.csv'
    process_dataset(boston_house_prices_path)
    
    # 3. 读取数据集 Iris.csv
    iris_path = 'Iris.csv'
    process_dataset(iris_path)
    
    2、处理缺失值
    	# 读取数据集
        df = pd.read_csv(file_path)
    
        # 打印原始数据
        print(f"{file_path} 原始数据:")
        print(df)
    
        # 处理缺失值,填充为每列的均值
        # 首先将不能转换为数值类型的数据转换为 NaN
        df = df.apply(pd.to_numeric, errors='coerce')
        # 然后填充缺失值
        df.fillna(df.mean(), inplace=True)
    
        # 打印处理后的数据
        print(f"\n{file_path} 处理缺失值后的数据:")
        print(df)
    
    3、转换为张量格式
        # 转换为张量格式
        tensor = torch.tensor(df.values, dtype=torch.float32)
    
        # 打印张量
        print(f"\n{file_path} 张量:")
        print(tensor)
        print("\n")
    

    运行结果:

    作者:Asitwas

    物联沃分享整理
    物联沃-IOTWORD物联网 » 关于深度学习的基础的Python知识(PyTorch)

    发表回复