Bootstrap

深度学习代码学习1

1、模块1

这几个包都是 Python 中非常有用的库,分别提供文件路径处理、序列化、压缩以及与系统交互的功能。以下是它们的主要作用:

1. pathlib.Path

作用: 处理文件和目录的路径操作。

  • Path 提供了一个面向对象的方式来处理文件路径。
  • 支持跨平台使用(Windows 和 Linux 的路径表示方式不同,pathlib 能够统一处理)。
  • 替代了传统的 os.path 模块中的大部分功能。

常见功能:

  • 创建、移动、删除文件或目录。
  • 检查文件或目录是否存在。
  • 获取文件的各种属性(如大小、修改时间等)。
from pathlib import Path

# 创建路径对象
path = Path("example.txt")

# 检查文件是否存在
if path.exists():
    print("File exists")

# 读取文件内容
content = path.read_text()

1. with 结构中的自动关闭和压缩行为

是的,使用 with 语句可以自动管理资源。在你的代码中:

with gzip.open('example.txt.gz', 'rb') as f:
 content = f.read()
 print(content.decode())

==with 语句会自动处理文件的打开和关闭操作,确保即使在代码块内部发生异常,文件也会被正确关闭。==你不用手动调用 f.close()with 块结束时,文件会自动关闭。如果你是在写入文件时使用 gzip,压缩也会自动完成。

2. pickle

作用: 将 Python 对象序列化和反序列化(即保存和加载对象)

  • 将 Python 对象(如字典、列表、自定义对象等)保存到文件中,或从文件中加载回 Python 对象
  • 主要用于在 Python 中持久化数据,例如保存模型、缓存数据等。

常见功能:

  • 序列化:将 Python 对象转换成字节流,以便保存到文件或传输。
  • 反序列化:将字节流还原为 Python 对象。
import pickle

# 序列化并保存对象
data = {'name': 'Alice', 'age': 25}
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)

# 从文件中反序列化对象
with open('data.pkl', 'rb') as f:
    loaded_data = pickle.load(f)
print(loaded_data)

2. pickle.dump 中的 dump 是什么的缩写?

pickle.dump 中的 dump 不是某个单词的缩写,它本身是一个完整的单词,意思是将数据"倾倒"或"写入"某个地方。在计算机领域中,dump 常用来表示把数据从内存中保存到文件里,或者以某种格式转储数据。

pickle.dump() 中,它表示把 Python 对象序列化并"倾倒"到文件中。

import pickle

data = {'key': 'value'}
with open('data.pkl', 'wb') as f:
 pickle.dump(data, f)  # 将序列化后的对象保存到文件中

pickle.load() 中,返回的数据类型和返回值的数量完全取决于你序列化(即 pickle.dump())时存储的数据类型。因此,pickle.load() 的返回值是动态的,它能够加载任意的 Python 对象,并还原为存储时的原始数据结构。

3. gzip

作用: 用于处理 gzip 格式的压缩文件。

  • 可以读取、写入、解压 gzip 压缩格式的文件。
  • 对文件进行压缩和解压缩的操作,节省存储空间或减少传输数据的大小。

常见功能:

  • 压缩文件或数据。
  • 解压 gzip 文件。
import gzip

# 压缩并写入文件
with gzip.open('example.txt.gz', 'wb') as f:
    f.write(b"This is a compressed file.")

# 解压并读取文件内容
with gzip.open('example.txt.gz', 'rb') as f:
    content = f.read()
    print(content.decode())

4. sys

作用: 提供与 Python 解释器和系统相关的功能。

  • 包含访问 Python 解释器的一些功能,如处理命令行参数、退出程序、修改模块搜索路径等。

常见功能:

  • sys.argv:获取命令行参数。
  • sys.exit():终止程序。
  • sys.path:查看和修改模块的导入路径。
import sys

# 获取命令行参数
print("Arguments passed:", sys.argv)

# 退出程序
if len(sys.argv) < 2:
    sys.exit("No arguments provided.")

总结

模块主要功能应用场景
pathlib文件和目录路径操作处理文件、路径的创建、检查、删除等操作
pickle序列化和反序列化持久化数据,保存或加载对象
gzip压缩和解压 gzip 格式文件压缩大文件,减少存储或传输时的大小
sys与 Python 解释器和系统进行交互处理命令行参数、退出程序、修改模块搜索路径

这些包在日常开发和处理数据时都非常实用,特别是在处理文件系统、数据存储、压缩和命令行应用程序时。

from pathlib import Path
import pickle
import gzip

# 指定本地文件路径
file_path = Path(r"C:\Users\HUAWEI\Desktop\资料\大三上\PyTorch\4.第四章 深度学习框架PyTorch\神经网络实战分类与回归任务\mnist.pkl.gz")
# r"...":字符串前缀 r 表示这是一个原始字符串(raw string),用于避免转义字符(如 \n,\t)的误解。在文件路径中通常会有反斜杠 \,
# 加上 r 可以让反斜杠按字面意义使用,不做转义。

# 确认文件是否存在
if file_path.exists():
    # 因为文件是压缩的,直接读取时需要以二进制形式读取数据,之后再解压缩并转化为可用的 Python 对象。
    # file_path.as_posix():将 Path 对象转化为 POSIX 路径字符串,适合在跨平台(如从 Windows 转到 Linux)时使用。
                                                                                                 #即使在 Windows 上使用这个方法,路径中的 \ 会转换成 /。
    with gzip.open(file_path.as_posix(), "rb") as f:  
        (x_train, y_train), (x_valid, y_valid), _ = pickle.load(f, encoding="latin-1")
        #encoding="latin-1":指定了反序列化时使用的字符编码。在某些旧的 Python 版本中,序列化时可能使用了不同的编码,
        #因此在读取时需要显式指定为 latin-1(ISO-8859-1),以便正确加载数据。
        
    # 数据检查
    print(f"训练集大小: {x_train.shape}, 标签集大小: {y_train.shape}")
    print(f"验证集大小: {x_valid.shape}, 标签集大小: {y_valid.shape}")
else:
    print("文件不存在,请检查路径。")
训练集大小: (50000, 784), 标签集大小: (50000,)
验证集大小: (10000, 784), 标签集大小: (10000,)

2、模块2

在深度学习中,torch.nn.functionaltorchmatplotlib.pyplotnumpy 是非常常用的库,它们分别承担不同的功能,涵盖了神经网络构建、训练和数据可视化的各个方面。我们一一分析它们在深度学习中的常见用途。

1. torch.nn.functional

torch.nn.functional 是 PyTorch 中的一个子模块,==包含了各种神经网络层的函数形式以及常见的激活函数、损失函数等。它与 torch.nn 模块中的类式 API 有点不同,因为它提供的是无状态的函数接口,适合在定义网络的“前向传播”==中直接调用,而不需要定义类来管理状态。

常见用途:

  • 激活函数:如 F.relu()F.sigmoid()F.softmax()
  • 损失函数:如 F.cross_entropy()F.mse_loss()
  • 卷积和池化操作:如 F.conv2d()F.max_pool2d()
import torch.nn.functional as F

# 使用 ReLU 激活函数
output = F.relu(input_tensor)

# 使用交叉熵损失
loss = F.cross_entropy(predictions, labels)

1. 传给 torch.nn.functional 的参数必须是 Tensor 吗?为什么?

是的,传给 torch.nn.functional 里的大多数函数的参数必须是 PyTorch 的 Tensor,这是因为 PyTorch 的核心概念和操作都是围绕 Tensor 进行的。Tensor 是 PyTorch 中的基本数据结构,它类似于 NumPy 的数组,但具有更强的功能,尤其是支持自动求导和 GPU 加速。

  • 自动求导:PyTorch 的 Tensor 支持自动求导,这意味着当你进行张量操作时,PyTorch 会自动构建计算图以支持反向传播,从而进行梯度计算。这是深度学习模型训练的关键步骤。
  • GPU 加速:PyTorch 的 Tensor 可以方便地在 GPU 上执行计算,显著加快深度学习模型的训练和推理过程。

例如,F.relu()F.cross_entropy() 等函数接受的输入一般是 Tensor,因为它们需要利用 Tensor 的计算图和自动求导功能来进行深度学习模型的训练和推理。

2. torch

torch 是 PyTorch 的主库,支持张量操作自动微分、以及GPU 加速计算,是构建和训练神经网络的核心工具。它类似于 NumPy,但支持 GPU 加速并且内置了计算图。

常见用途:

  • 张量(Tensor)操作:PyTorch 中的一切数据都是基于张量的,类似于 NumPy 数组,但具有自动求导能力。
  • 自动微分:通过 autograd 模块进行梯度计算,支持反向传播。
  • GPU/CPU 切换:可以将张量转移到 GPU 上进行加速计算。
  • 深度学习模型:定义神经网络、训练循环、优化器等。
import torch

# 创建一个随机张量并移动到 GPU
x = torch.randn(3, 3).cuda()

# 张量的基本操作
y = torch.ones(3, 3)
z = x + y

# 自动求导
x.requires_grad_(True)
loss = x.sum()
loss.backward()
自动微分

自动微分(autograd)是 PyTorch 的核心功能之一,它使得你可以自动计算张量操作的导数或梯度。它会记录你对张量的所有操作,并在反向传播时计算梯度,这对于深度学习模型的训练至关重要,因为你需要通过反向传播来更新模型的参数。

例如,当你进行前向传播(计算损失)时,PyTorch 会自动为你构建一个计算图,在调用 backward() 函数时,PyTorch 会通过计算图计算梯度。

3. matplotlib.pyplot

matplotlib.pyplot 是一个数据可视化工具,常用于深度学习模型的训练过程中,用来绘制损失函数的变化曲线、分类结果的可视化、图像处理结果的展示等。

常见用途:

  • 绘制损失和精度曲线:在训练过程中,绘制损失函数和模型精度的变化趋势。
  • 可视化图像数据:可以用来展示数据集中的图像,或训练过程中生成的图像,如 GAN 生成的图片等。
  • 绘制混淆矩阵:用于分类任务结果的可视化,显示分类正确和错误的情况。
import matplotlib.pyplot as plt

# 绘制训练损失曲线
epochs = [1, 2, 3, 4]
loss_values = [0.9, 0.6, 0.4, 0.3]

plt.plot(epochs, loss_values, label='Training Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

2. plt.show()plt.imshow() 的区别?

matplotlib.pyplot 中的 plt.show()plt.imshow() 用途不同,它们解决的是两个不同的任务。

  • plt.show():用于显示整个绘图窗口。==它是一个全局的显示函数,可以在绘图的最后一步使用,将之前定义的所有图像、曲线、坐标轴等内容一起显示。==一般会将所有绘图命令结束后调用 plt.show(),这样可以一次性展示所有图表。

    示例:

    import matplotlib.pyplot as plt
    
    plt.plot([1, 2, 3, 4])
    plt.show()  # 显示图形
    
    image-20241014210927573
  • plt.imshow():专门用于显示图像数据。它接受一个二维或三维数组,并将其以图像的形式显示出来,常用于可视化图像数据。imshow() 会将数据映射为颜色,通过颜色表示数据的值。

    示例:

    import numpy as np
    import matplotlib.pyplot as plt
    
    img = np.random.rand(10, 10)  # 随机生成一个 10x10 的二维数组
    plt.imshow(img)  # 显示图像
    plt.show()  # 显示图像窗口
    
    image-20241014210903073

4. numpy

numpy 是一个数值计算库,主要用于深度学习中的数据处理。虽然 PyTorch 的 torch.Tensor 提供了很多类似 NumPy 的功能,但 NumPy 仍然广泛用于处理张量之前的数据加载和预处理。

常见用途:

  • 数据处理:在深度学习任务中,经常需要对原始数据进行处理,如标准化、归一化、图像的尺寸调整等操作,NumPy 提供了丰富的工具来实现这些操作。
  • 张量与 NumPy 之间的互操作:可以方便地将 PyTorch 张量转换为 NumPy 数组,进行某些 NumPy 支持的操作。
  • 统计分析:计算均值、标准差、方差等统计量,在数据预处理中非常常见。
import numpy as np

# 创建一个 NumPy 数组
arr = np.array([1, 2, 3, 4, 5])

# 归一化数据
arr_normalized = (arr - np.mean(arr)) / np.std(arr)

# PyTorch 张量和 NumPy 互操作
tensor = torch.from_numpy(arr)  # NumPy 转 PyTorch 张量
numpy_arr = tensor.numpy()      # PyTorch 张量转 NumPy 数组

5、from sklearn import preprocessing

from sklearn import preprocessing
input_features = preprocessing.StandardScaler().fit_transform(features)  #标准化数据

preprocessing.StandardScaler().fit_transform() 对输入的数据有一定的要求,主要是确保数据能够顺利进行标准化处理。具体要求如下:

1. 数据格式要求

  • 数组格式:输入数据通常需要是二维数组,常见的格式是 numpy.ndarray 或者 pandas.DataFrame

    • 每一行表示一个样本。
    • 每一列表示一个特征。
  • 例如:输入的 features 数据应该形如 (n_samples, n_features),即 n_samples 为样本数量,n_features 为特征数量。

    import numpy as np
    from sklearn import preprocessing
    
    features = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  # 三个样本,三个特征
    input_features = preprocessing.StandardScaler().fit_transform(features)
    

2. 数值型数据

  • 输入数据应为数值型(如 intfloat),因为标准化是基于均值和标准差的数值计算。如果数据中有非数值数据(如字符串),你需要先对其进行编码或者转换处理。

    • 处理非数值型数据:如果存在非数值数据(如分类特征),需要先进行编码(如 LabelEncoderOneHotEncoder 等)。

3. 没有缺失值

  • StandardScaler 不支持直接处理缺失值(即 NaN)。如果输入数据中有缺失值,应该在标准化之前进行填充或删除。

    • 处理缺失值:可以使用 pandassklearn 中的 SimpleImputer 对缺失值进行填补。
    from sklearn.impute import SimpleImputer
    imputer = SimpleImputer(strategy='mean')  # 使用均值填补缺失值
    features = imputer.fit_transform(features_with_nan)
    

4. 数据不是常量列

  • 输入的特征数据不能全是常量值(即方差为 0)。如果某一列特征的值都相同,标准化时会报错,因为标准差为 0 会导致无法进行除法操作。

5. 适用于浮点型计算

  • 尽量将输入数据转换为 float 类型。虽然 int 类型的输入也可以进行标准化,但输出结果通常是浮点数。

举例:

假设你的输入数据是一个二维的 numpy 数组:

import numpy as np
from sklearn import preprocessing

# 假设输入数据
features = np.array([[1.0, 2.0, 3.0],
                     [4.0, 5.0, 6.0],
                     [7.0, 8.0, 9.0]])

# 使用 StandardScaler 进行标准化
input_features = preprocessing.StandardScaler().fit_transform(features)
print(input_features)

总结:

preprocessing.StandardScaler().fit_transform() 要求输入数据:

  1. 是二维数组或类似结构(如 numpy.ndarraypandas.DataFrame)。
  2. 数据应为数值类型。
  3. 不能包含缺失值(如 NaN)。
  4. 不能存在方差为 0 的特征列。

总结:

常见用途
torch.nn.functional提供无状态的函数接口,包括激活函数、损失函数和卷积等神经网络常用操作
torchPyTorch 的主库,负责张量计算、自动微分、GPU 加速以及构建和训练神经网络
matplotlib.pyplot用于可视化训练过程中的数据,如绘制损失函数、精度曲线、分类结果等
numpy提供高效的数值计算,主要用于数据预处理,并可与 PyTorch 张量互操作

在深度学习任务中,这些库的组合使用非常常见,帮助我们高效地实现从数据处理、模型定义、训练到结果分析的全流程。

3、模块3

torch.utils.datatorchvision 都是 PyTorch 中用于处理数据的模块,分别在数据加载、预处理以及数据增强等方面提供了重要工具。我们来看它们的具体作用,并进行对比。

1. torch.utils.data.TensorDataset

  • 作用TensorDataset 是一个简单的数据集包装类。它允许我们将特征和标签打包在一起作为一个数据集,这样在训练时,模型能够同时获取特征和对应的标签。常用于将预处理后的 NumPy 数组或张量封装成 PyTorch 数据集,方便与 DataLoader 一起使用。
  • 主要用途
    • 将多个张量(如输入特征和标签)打包成一个可以迭代的数据集对象
    • 适用于自定义的小型数据集或预处理后的数据。
from torch.utils.data import TensorDataset

# 例子:将训练数据 x_train 和 y_train 打包为 TensorDataset
train_ds = TensorDataset(x_train, y_train)

2. torch.utils.data.DataLoader

  • 作用DataLoader 是 PyTorch 提供的数据加载器,主要用于==从数据集中按批次(batch)加载数据。它能够实现多线程加载数据、批量迭代和数据打乱(shuffle)等功能,非常适合处理大规模数据集。==
  • 主要用途
    • 通过 batch_size 参数分批加载数据。
    • 支持 shuffle 参数打乱数据顺序,防止模型过拟合数据顺序。
    • 支持多进程并行加载数据,提升数据加载的效率。
from torch.utils.data import DataLoader

# 例子:为打包好的数据集创建一个 DataLoader,并设置 batch_size 和 shuffle
train_dl = DataLoader(train_ds, batch_size=32, shuffle=True)

3. torchvision.datasets

  • 作用torchvision.datasets 模块提供了一系列常用的计算机视觉数据集(如 MNIST、CIFAR-10、ImageNet 等)的封装。通过该模块,你可以直接加载流行的数据集,而无需手动下载和预处理。
  • 主要用途
    • 提供了常见数据集的封装,并且自动处理数据的下载和格式化。
    • 在计算机视觉任务中,它极大地简化了数据加载的工作,减少了重复劳动。
from torchvision import datasets

# 例子:加载 MNIST 数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transforms.ToTensor())

4. torchvision.transforms

  • 作用transforms 模块提供了图像数据的各种预处理和增强操作,如转换为张量、标准化、随机裁剪等。常与 datasets 模块结合使用,以便在加载数据时对其进行预处理或数据增强。
  • 主要用途
    • 图像数据的预处理(如将 PIL 图像转换为张量)。
    • 数据增强(如旋转、裁剪、翻转等操作),以提高模型的泛化能力。
from torchvision import transforms

# 例子:定义一个 transforms 管道,将图像转换为张量并归一化
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

# 例子:加载 MNIST 数据集时应用上述 transforms
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)

对比总结

模块/函数名主要作用用途
TensorDataset将多个张量(如特征和标签)打包成一个可迭代的数据集用于自定义数据集,特别是小型或预处理后的数据
DataLoader批量加载数据,支持多线程并行加载和数据打乱适合大规模数据集的加载和训练,用于迭代获取批量数据
torchvision.datasets提供常见的图像数据集(如 MNIST、CIFAR-10),自动下载和处理简化图像数据集的加载,适用于计算机视觉任务
torchvision.transforms图像数据的预处理和增强操作,如转换为张量、标准化、裁剪、旋转等用于图像数据的预处理和数据增强,提升模型泛化能力

总结:

  • TensorDatasetDataLoader:用于通用数据集(不仅限于图像),尤其是将自定义数据集转换成 PyTorch 的张量并高效加载。
  • torchvision.datasetstransforms:专为计算机视觉任务设计,简化图像数据集的加载和预处理。

4、随机模块

在深度学习和数值计算中,生成随机数是一个非常常见的操作,不同的库提供了各自的随机函数。这些函数在生成随机数时,可能生成的范围、分布类型以及数据格式都不尽相同。下面,我将对 NumPynp.random.rand()PyTorchtorch.randn() 以及 Python 内置的随机函数 进行详细对比和总结。

1. np.random.rand()(NumPy 随机函数)

用途
  • 生成符合均匀分布的随机数,范围在 [0, 1) 之间。
特性
  • 生成的数值分布是 均匀分布,即每个数在 [0, 1) 区间内出现的概率是相等的。
  • 可以生成任意维度的数组,通过传递形状参数来指定输出数组的形状。
示例
import numpy as np

# 生成 10x10 的随机数组,每个数的取值范围为 [0, 1)
arr = np.random.rand(10, 10)
print(arr)
常见应用
  • 数据初始化:在深度学习中,可以用于随机初始化权重矩阵。
  • 数据归一化:可以生成小范围的随机数据,用于生成标准化的随机样本。

2. torch.randn()(PyTorch 随机函数)

用途
  • 生成符合标准正态分布的随机数,均值为 0,标准差为 1。
特性
  • 生成的数值分布是 标准正态分布(均值为 0,方差为 1)。与 np.random.rand() 不同,生成的随机数可能为正数或负数。
  • 可以生成任意维度的张量,传递形状参数即可指定输出张量的形状。
  • 支持 GPU 运算:torch.randn() 生成的张量可以轻松地通过 .cuda() 移动到 GPU 上,便于深度学习中的大规模计算。
示例
import torch

# 生成 3x3 的随机张量,每个数的分布为标准正态分布(均值 0,方差 1)
tensor = torch.randn(3, 3)
print(tensor)
常见应用
  • 初始化神经网络的权重:标准正态分布的随机数常用于权重的初始化。
  • 数据增强:可以为输入数据添加噪声,生成一些随机扰动,用于数据增强。

这行代码:

torch.randn([784, 10], dtype=torch.float, requires_grad=True)

的作用是生成一个形状为 [784, 10] 的 PyTorch 张量,并且满足以下几个条件:

  1. torch.randn(): 生成符合 标准正态分布(均值为 0,标准差为 1)的随机数张量。

    • 标准正态分布意味着生成的随机数可能为正数也可能为负数。
  2. [784, 10]: 指定了张量的形状。

    • 这个张量是 784 行 10 列的矩阵(2D 张量)。这种尺寸的张量常用于深度学习中的全连接层权重初始化,例如用于手写数字识别任务的输入层(784 维)到输出层(10 类)。
  3. dtype=torch.float: 指定生成的张量的数据类型为 float32

    • PyTorch 中默认的浮点数类型是 torch.float32(简写为 torch.float),这个选项确保生成的数是浮点数类型而不是其他类型(例如 int)。
  4. requires_grad=True: 设置张量的 requires_grad 属性为 True,意味着这个张量的所有操作都将被追踪以计算梯度。

    • 在深度学习中,requires_grad=True 通常用于需要对参数进行 反向传播(即梯度计算)的场景。这个张量可能是模型的某个参数,在训练过程中,PyTorch 会自动计算它的梯度,以用于优化(例如使用梯度下降法)。

总结

这行代码生成了一个随机初始化的 2D 张量,形状为 [784, 10],数据类型为 float32,并且开启了自动求导功能(即反向传播时将计算它的梯度)。这个张量可以用于深度学习模型的参数,例如用于神经网络的权重矩阵。

示例:

如果你打印这个张量,类似的输出会是:

tensor = torch.randn([784, 10], dtype=torch.float, requires_grad=True)
print(tensor)

输出将是一个形状为 [784, 10] 的矩阵,里面充满随机生成的浮点数。

3. Python 内置的随机函数random 模块)

Python 内置的随机库 random 提供了多种生成随机数的方法。

常见函数
  • random.random():生成一个在 [0, 1) 范围内的随机浮点数,符合均匀分布。
  • random.randint(a, b):生成一个在 [a, b] 范围内的整数,包含两端。
  • random.uniform(a, b):生成一个在 [a, b) 范围内的随机浮点数,符合均匀分布。
  • random.gauss(mu, sigma):生成一个符合正态分布的随机浮点数,均值为 mu,标准差为 sigma
示例
import random

# 生成一个 [0, 1) 之间的随机浮点数
print(random.random())

# 生成一个 [1, 10] 之间的随机整数
print(random.randint(1, 10))

# 生成一个符合正态分布的随机数,均值为 0,标准差为 1
print(random.gauss(0, 1))
常见应用
  • 随机事件模拟:random 模块提供了用于生成随机数的多种方法,可以用于模拟随机事件或实现随机抽样。
  • 游戏开发或概率实验:内置的 random 函数适合用于非科学计算中的随机性,比如游戏中的随机数生成、抽奖等。

4. 对比总结

函数所属库随机数分布返回数据类型特点和常见用途
np.random.rand()NumPy均匀分布 [0, 1)NumPy 数组常用于生成均匀分布随机数,可指定任意维度。
torch.randn()PyTorch标准正态分布(均值 0,方差 1)PyTorch 张量生成符合正态分布的随机数,常用于神经网络的权重初始化。
random.random()Python 内置模块均匀分布 [0, 1)浮点数简单生成随机浮点数,主要用于非科学计算中的随机性。
random.randint(a, b)Python 内置模块均匀分布整数,区间 [a, b]整数生成随机整数,包含两端,适用于游戏开发或简单随机实验。
random.uniform(a, b)Python 内置模块均匀分布浮点数 [a, b)浮点数生成指定区间内的随机浮点数。
random.gauss(mu, sigma)Python 内置模块正态分布浮点数生成正态分布的随机数,用于概率实验或模拟。

总结

  • NumPynp.random.rand() 生成均匀分布的随机数,常用于数据初始化和处理。
  • PyTorchtorch.randn() 生成标准正态分布的随机数,适合用于深度学习模型中的权重初始化和数据增强,并且支持 GPU 加速。
  • Python 内置的 random 模块 提供了多种生成随机数的方法,适合非科学计算的场景,如游戏、模拟随机事件等。

每个函数都有特定的用途和场景,选择时应根据具体的应用需求来决定。

5、tensor的常用属性

在 PyTorch 中,张量(Tensor)有许多常见的属性和方法,用于查看张量的基本信息或进行常见操作。以下是 PyTorch 张量的一些常见属性和方法,以及它们的用途:

1. .shape.size()

  • 作用:返回张量的形状,即每个维度的大小。

  • 返回值类型torch.Size(类似于 Python 中的元组)

  • 示例

    tensor = torch.randn(3, 4, 5)
    print(tensor.shape)  # 输出: torch.Size([3, 4, 5])
    print(tensor.size()) # 同样输出: torch.Size([3, 4, 5])
    

2. .dtype

  • 作用:返回张量的数据类型(如 torch.float32, torch.int64 等)。

  • 返回值类型torch.dtype

  • 示例

    tensor = torch.randn(3, 4, dtype=torch.float32)
    print(tensor.dtype)  # 输出: torch.float32
    

3. .device

  • 作用:返回张量所在的设备类型(CPU 或 GPU)。

  • 返回值类型torch.device

  • 示例

    tensor = torch.randn(3, 4, device='cuda')
    print(tensor.device)  # 输出: cuda:0 (表示在第一个 GPU 上)
    

4. .requires_grad

  • 作用:指示张量是否需要计算梯度。若设置为 True,该张量会参与反向传播。

  • 返回值类型bool

  • 示例

    tensor = torch.randn(3, 4, requires_grad=True)
    print(tensor.requires_grad)  # 输出: True
    

5. .grad

  • 作用:当 requires_grad=True 时,反向传播后该属性会存储该张量的梯度值。未进行反向传播时值为 None

  • 返回值类型torch.TensorNone

  • 示例

    tensor = torch.randn(3, 4, requires_grad=True)
    y = tensor * 2
    y.backward(torch.ones_like(tensor))  # 对 y 进行反向传播
    print(tensor.grad)  # 输出张量的梯度
    

6. .item()

  • 作用:将包含单个元素的张量转换为 Python 标量(如 floatint)。

  • 返回值类型floatint

  • 示例

    tensor = torch.tensor([3.0])
    print(tensor.item())  # 输出: 3.0
    

7. .data

  • 作用:获取张量的原始数据部分(跳过 autograd 的计算图)。这通常用于禁用梯度追踪,但不推荐直接使用,建议使用 torch.no_grad() 来实现类似功能。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4, requires_grad=True)
    print(tensor.data)  # 返回张量的原始数据
    

8. .is_cuda

  • 作用:检查张量是否在 GPU 上。

  • 返回值类型bool

  • 示例

    tensor = torch.randn(3, 4, device='cuda')
    print(tensor.is_cuda)  # 输出: True
    

9. .T(转置)

  • 作用:返回张量的转置(仅适用于 2D 张量,或者在高维张量中交换最后两个维度)。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4)
    print(tensor.T)  # 输出 4x3 的转置张量
    

10. .to()

  • 作用:将张量转换到指定的数据类型或设备(如从 CPU 移动到 GPU,或从 float 转为 int)。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4)
    tensor_gpu = tensor.to('cuda')  # 将张量移动到 GPU
    tensor_int = tensor.to(torch.int32)  # 将张量转换为 int32 类型
    

11. .clone()

  • 作用:创建张量的一个拷贝(深拷贝,保留原始数据和计算图)。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4)
    tensor_clone = tensor.clone()
    

12. .detach()

  • 作用:返回一个新的张量,从当前计算图中分离出来,不会追踪梯度计算。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4, requires_grad=True)
    tensor_detach = tensor.detach()  # tensor_detach 不会参与反向传播
    

13. .cpu().cuda()

  • 作用:将张量从 GPU 转移到 CPU(cpu())或者从 CPU 转移到 GPU(cuda())。

  • 返回值类型torch.Tensor

  • 示例

    tensor = torch.randn(3, 4, device='cuda')
    tensor_cpu = tensor.cpu()  # 将张量移回 CPU
    

14. .numpy()

  • 作用:将 PyTorch 张量转换为 NumPy 数组(仅适用于 CPU 张量)。如果张量是在 GPU 上的,需要先调用 .cpu()

  • 返回值类型numpy.ndarray

  • 示例

    tensor = torch.randn(3, 4)
    numpy_array = tensor.numpy()  # 转换为 NumPy 数组
    

总结表格

属性/方法作用返回值类型
.shape / .size()返回张量的形状torch.Size
.dtype返回张量的数据类型torch.dtype
.device返回张量所在的设备torch.device
.requires_grad是否需要梯度计算bool
.grad反向传播后张量的梯度torch.Tensor or None
.item()将单个元素张量转换为 Python 标量floatint
.data获取张量的数据部分(不推荐)torch.Tensor
.is_cuda检查张量是否在 GPU 上bool
.T张量的转置torch.Tensor
.to()将张量转换到指定设备或数据类型torch.Tensor
.clone()深拷贝一个张量torch.Tensor
.detach()返回一个不计算梯度的新张量torch.Tensor
.cpu() / .cuda()在 CPU 和 GPU 之间移动张量torch.Tensor
.numpy()将张量转换为 NumPy 数组(仅适用于 CPU 张量)numpy.ndarray

这些属性和方法在日常操作 PyTorch 张量时非常有用,帮助你控制张量的计算行为、设备位置、数据类型等。

.data 属性和 .item() 方法都是 PyTorch 中用于访问张量中值的方式,但它们有不同的使用场景和作用。

1. .data 属性

  • .data 属性是 PyTorch 中的一个属性,主要用于直接访问张量的原始数据,而不通过自动微分(autograd)机制。它会返回张量的原始数据部分,绕过梯度计算。
  • 使用场景:当你只想要获取张量的值而不希望与自动求导系统发生交互时,可以使用 .data。不过,使用 .data 存在风险,因为它可能破坏自动求导机制,不再追踪梯度。因此,现在不推荐使用 .data,而是使用 .detach() 来获得同样的效果。
  • 返回值:如果张量是多维的,.data 仍然返回一个多维张量。

示例:

import torch

# 创建一个张量并启用梯度追踪
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)

# 使用 .data 访问原始数据
print(x.data)  # tensor([[1., 2.], [3., 4.]])

2. .item() 方法

  • .item() 是一个 PyTorch 张量的方法,用于从包含单个元素的张量中提取该元素的 Python 标量值。这个方法只能用于标量张量(即只有一个值的张量),并且返回一个 Python 原生数据类型(如 intfloat)。
  • 使用场景:当你处理一个标量张量并需要将其转换为 Python 的标量类型时使用 .item()。它通常用于获取损失值、单个预测结果等。
  • 返回值:返回的是 Python 标量值,而不是张量。如果张量中有多个元素,不能直接使用 .item(),会报错。

示例:

import torch

# 创建一个标量张量
x = torch.tensor(2.0)

# 使用 .item() 获取标量值
print(x.item())  # 2.0

主要区别:

特性.data.item()
作用返回张量的原始数据,跳过梯度追踪返回张量中单个元素的 Python 标量
返回值多个元素时返回张量,单个元素时返回张量只能用于包含单个元素的张量
自动微分的影响跳过梯度追踪,可能破坏 autograd 机制不影响自动微分机制
推荐使用不推荐(建议使用 .detach() 替代)推荐用于标量张量
适用场景用于直接获取张量的值,但要注意 autograd 影响从标量张量中提取单一的数值

小结:

  • .data:返回张量的原始数据,用于跳过梯度计算。对于多维张量依然返回多维张量,但不推荐使用,建议使用 .detach()
  • .item():用于从标量张量中提取单一的数值,返回的是一个 Python 标量类型,适用于只有一个元素的张量。

6、TensorDatasetDataLoader

TensorDatasetDataLoader 是 PyTorch 中用于数据处理和加载的两个重要类。它们帮助你将数据打包成可迭代的形式,并方便地用于模型训练和评估。

1. TensorDataset

==TensorDataset 是一个包装数据的类,允许将多个 Tensor 组合在一起,形成一个数据集。==你可以将输入和目标标签等数据存储在一起,以便于后续使用。

参数:
  • *tensors:可以是任意数量的张量,要求它们的第一个维度(通常是样本数量)相同
作用:

TensorDataset 将多个张量组合成一个 Dataset,这样可以方便地通过索引访问对应的样本数据和标签。

示例:
import torch
from torch.utils.data import TensorDataset

# 创建示例张量
x = torch.randn(100, 3)  # 100 个样本,3 个特征
y = torch.randint(0, 2, (100,))  # 100 个样本的标签(0 或 1)

# 创建数据集
dataset = TensorDataset(x, y)
 
# 访问第 0 个样本及其标签
print(dataset[0])  # (张量 x[0], 张量 y[0])

2. DataLoader

DataLoader 是一个将数据集(如 TensorDataset)打包为可迭代对象的类,方便进行批量化数据读取,支持多线程、随机打乱和数据划分等功能。

参数:
  • datasetDataset 对象,例如 TensorDataset,或你自定义的继承自 torch.utils.data.Dataset 的类实例。
  • batch_size(可选):每个批次中数据的样本数量。默认为 1
  • shuffle(可选):是否在每个 epoch 开始时随机打乱数据。默认为 False
  • sampler(可选):自定义的数据采样方式,通常不需要直接指定,使用默认即可。
  • batch_sampler(可选):自定义批量采样方式,与 batch_sizeshuffle 互斥。
  • num_workers(可选):加载数据时使用的子进程数量。默认为 0(表示在主线程中加载数据)。
  • collate_fn(可选):自定义的批量数据拼接方式。默认情况下,它会将张量按批次堆叠为一个大的张量。
  • pin_memory(可选):是否将张量的内存页锁定到 RAM 中,提升数据从 CPU 到 GPU 的传输效率。默认为 False
  • drop_last(可选):如果数据集不能被 batch_size 整除,是否丢弃最后一个不完整的 batch。默认为 False
  • timeout(可选):等待数据加载的超时时间。默认为 0,即无限等待。
  • worker_init_fn(可选):子进程初始化函数,在每个 worker 启动时调用。
示例:
from torch.utils.data import DataLoader

# 使用上面创建的 TensorDataset
dataloader = DataLoader(dataset, batch_size=16, shuffle=True, num_workers=4)

# 迭代 DataLoader,获取每个批次
for batch in dataloader:
    inputs, labels = batch
    print(inputs.shape, labels.shape)  # 每个批次有 16 个样本

总结:

  • TensorDataset:用于将多个张量组合为一个 Dataset,例如训练数据和标签。
  • DataLoader:将 Dataset 打包为可迭代对象,支持批量化、数据打乱、多线程加载等功能。

这两者配合使用,可以方便地管理和加载数据,为模型训练提供批量化的数据。

你可以直接遍历 valid_dl 来查看其中的批次内容,具体包括每个批次的输入数据(x_valid)和标签(y_valid)。由于 DataLoader 是可迭代的对象,你可以通过循环访问它。你可以用以下代码打印每个批次的数据:

# 遍历 valid_dl 查看验证集的批次
for i, (inputs, labels) in enumerate(valid_dl):
 print(f"Batch {i+1}:")
 print(f"Inputs: {inputs}")
 print(f"Labels: {labels}")
 print(f"Batch size: {inputs.shape[0]}")
 print("-" * 50)  # 分割线,便于阅读

解释:

  • inputs 是批次中的输入数据(即 x_valid 的一部分)。
  • labels 是批次中的标签(即 y_valid 的一部分)。
  • inputs.shape[0] 会输出当前批次的大小。

这样可以查看每个批次中的数据和标签。如果你不想一次性打印所有数据,可以选择打印某一个特定批次:

# 查看 valid_dl 中的第一个批次
first_batch = next(iter(valid_dl))
inputs, labels = first_batch
print(f"Inputs: {inputs}")
print(f"Labels: {labels}")
print(f"Batch size: {inputs.shape[0]}")

这段代码会输出验证集的第一个批次的输入和标签。

7、pandasSeriesnumpyndarray 和 Python 的内置 list

pandasSeriesnumpyndarray 和 Python 的内置 list 都是存储和操作数据的结构,但它们在功能、性能和使用场景上有很大的不同。以下是它们之间的详细对比:

特性pandas.Seriesnumpy.ndarrayPython list
类型pandas.Series 对象numpy.ndarray 对象Python 内置 list
维度一维通常多维(可以是1D、2D、3D等)一维
索引有标签索引(可以是非整数)只有整数索引只有整数索引
元素类型支持混合类型,但通常使用一种类型同一数组中必须是同一数据类型支持不同数据类型
缺失值处理原生支持 NaNNone不原生支持,需要 masked arrays支持 None
广播支持广播支持广播不支持广播
性能较高效,但比 ndarray高效,适合数值计算较低效,适合小规模数据处理
内置函数丰富的基于标签的操作主要用于数值运算无数值运算或高级数据操作支持
主要用途结构化数据分析数值计算,矩阵运算通用的数据存储和简单操作

详细解释:

  1. 数据结构与索引

    • Seriespandas 的一维数据结构,类似于带有索引的数组。与 ndarray 不同的是,Series 可以拥有标签索引,而不仅限于整数索引,这使得它非常适合与表格数据(如数据库、Excel文件)中的数据一起使用。Series 的索引可以是字符串、日期等非整数类型。
    • ndarraynumpy 的基础数据结构,支持任意维度的数组(如1D、2D、3D等)。所有的元素必须是相同的类型,且只能通过整数索引访问。
    • list 是 Python 内置的通用容器,可以存储不同类型的数据,但没有像 Seriesndarray 那样的高级数值操作功能。
  2. 类型一致性

    • Seriesndarray 中的元素通常是同一类型(尽管 Series 可以支持混合类型,但这样做会导致性能下降),这使得它们在处理数值数据时效率更高。
    • list 可以存储任何类型的数据,灵活性更高,但也因此在进行数值计算时效率较低。
  3. 缺失值处理

    • SeriesNaN(空值)的处理是内置的,并且对操作缺失数据的函数支持良好。
    • ndarray 需要额外的模块(如 numpy.ma)来处理缺失值。
    • list 支持存储 None 来表示缺失值,但没有专门的缺失值处理功能。
  4. 广播机制

    • ndarraySeries 都支持广播操作。例如,向 ndarray 添加一个标量会将该标量应用到数组中的每个元素。同样的操作对 Series 也可以使用。
    • list 不支持广播运算,类似的操作需要用循环实现。
  5. 性能

    • ndarray 由于其固定数据类型和底层的C语言实现,性能通常比 Serieslist 更好,尤其是处理大型数值计算时。
    • Series 尽管功能强大,但其性能在数值计算方面不如 ndarray,因为它需要维护索引信息。
    • list 在处理大规模数据时性能最差,尤其是在进行大量数值运算时。
  6. 功能与用途

    • Series 在数据分析中非常有用,提供了非常强大的基于标签的操作,可以轻松进行数据筛选、聚合等操作。
    • ndarray 更适合用于科学计算和矩阵运算,提供了丰富的数值运算和线性代数函数。
    • list 是通用的数据存储工具,但没有高级的数据操作和运算支持。

适用场景:

  • 如果你需要处理结构化数据(带有行索引、标签)并进行数据分析,Series 更加适合。
  • 如果你需要进行高效的数值运算或矩阵操作,选择 ndarray
  • 如果你只需简单地存储和操作数据,而不需要高性能的数值运算,list 就足够了。

希望这个总结能够帮助你更好地理解这三者的区别!

8、时间格式

pandas 中的 pd.to_datetime()datetime 模块的 datetime.datetime.strptime() 都用于将字符串转换为日期时间格式,但它们有不同的用途和功能。下面详细说明它们的区别。

1. pd.to_datetime()(pandas)

  • 用途pd.to_datetime()pandas 中的一个函数,主要用于将各种形式的日期数据(字符串、数字等)转换为 pandas.Timestamp 对象,适合处理大规模数据灵活的格式
  • 特点
    • 可以将多种格式的数据(包括字符串、数值、列表等)自动解析为日期类型。
    • 能够处理多个列,如 yearmonthday 的组合。
    • 适合处理时间序列数据,且支持更复杂的日期操作,如处理缺失值、无效数据等。
    • 输出的结果是 pandas.Timestamp 对象,或者是 pandas.DatetimeIndex,方便与 pandas 的其他功能(如时间序列分析)配合使用。
示例:
import pandas as pd

# 使用字符串
df = pd.DataFrame({
    'date_str': ['2020-01-01', '2021-02-15', '2022-03-10']
})

# 自动解析为日期类型
df['date'] = pd.to_datetime(df['date_str'])
print(df)

输出:

    date_str       date
0  2020-01-01 2020-01-01
1  2021-02-15 2021-02-15
2  2022-03-10 2022-03-10
import pandas as pd

# 创建示例数据
data = {
 'year': [2020, 2021, 2022],
 'month': [5, 6, 7],
 'day': [10, 15, 20],
 'value': [100, 200, 300]
}

df = pd.DataFrame(data)

# 使用 pd.to_datetime() 将 year, month, day 列组合成日期
df['date'] = pd.to_datetime(df[['year', 'month', 'day']])

# 将 'date' 列设置为行索引
df = df.set_index('date')

# 打印结果
print(df)

         year  month  day  value
date                                
2020-05-10  2020      5   10    100
2021-06-15  2021      6   15    200
2022-07-20  2022      7   20    300

2. datetime.datetime.strptime()(datetime)

  • 用途datetime.datetime.strptime()datetime 模块中的方法,用于严格按照指定格式将字符串转换为 datetime 对象。
  • 特点
    • 需要明确指定日期字符串的格式,如 '%Y-%m-%d'
    • 适合处理单个字符串日期格式,不支持直接处理多列的组合。
    • 更适合单独使用,而不是专门为大规模数据操作设计。
    • 输出的是 datetime.datetime 对象,而不是 pandas.Timestamp 对象。
示例:
import datetime

# 字符串转换为日期
date_str = '2020-01-01'
date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
print(date)

输出:

2020-01-01 00:00:00

3. 主要区别

特性pd.to_datetime()datetime.datetime.strptime()
模块pandasdatetime
用途用于处理大规模数据,支持多种格式处理单个字符串,严格按照指定格式解析
输入类型字符串、数值、多个列等多种类型单个字符串,必须指定格式
返回类型pandas.TimestampDatetimeIndexdatetime.datetime 对象
处理多个列支持,如将 yearmonthday 组合不支持
灵活性高,能自动识别多种格式低,格式必须明确指定
应用场景数据分析、时间序列处理单次字符串到日期的转换

4. 总结

  • 如果你处理的是大规模数据或需要从多个列(如 yearmonthday)生成日期,使用 pd.to_datetime() 更加灵活高效。
  • 如果你只需要从单个日期字符串中按照特定格式解析日期,可以使用 datetime.datetime.strptime()

这两者的使用取决于你的具体场景,如果你是在 pandas 数据处理中,pd.to_datetime() 无疑是首选工具。

8、CPU,GPU

默认是CPU

# 默认转换为 CPU 上的 tensor
x = torch.tensor(input_features, dtype=torch.float)
y = torch.tensor(labels, dtype=torch.float)

# 如果你想将数据转换到 GPU 上,你需要使用 .to() 方法或 .cuda() 方法
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
x = torch.tensor(input_features, dtype=torch.float).to(device)
y = torch.tensor(labels, dtype=torch.float).to(device)
;