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.functional
、torch
、matplotlib.pyplot
和 numpy
是非常常用的库,它们分别承担不同的功能,涵盖了神经网络构建、训练和数据可视化的各个方面。我们一一分析它们在深度学习中的常见用途。
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() # 显示图形
plt.imshow()
:专门用于显示图像数据。它接受一个二维或三维数组,并将其以图像的形式显示出来,常用于可视化图像数据。imshow()
会将数据映射为颜色,通过颜色表示数据的值。示例:
import numpy as np import matplotlib.pyplot as plt img = np.random.rand(10, 10) # 随机生成一个 10x10 的二维数组 plt.imshow(img) # 显示图像 plt.show() # 显示图像窗口
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. 数值型数据
输入数据应为数值型(如
int
或float
),因为标准化是基于均值和标准差的数值计算。如果数据中有非数值数据(如字符串),你需要先对其进行编码或者转换处理。
- 处理非数值型数据:如果存在非数值数据(如分类特征),需要先进行编码(如
LabelEncoder
、OneHotEncoder
等)。3. 没有缺失值
StandardScaler
不支持直接处理缺失值(即NaN
)。如果输入数据中有缺失值,应该在标准化之前进行填充或删除。
- 处理缺失值:可以使用
pandas
或sklearn
中的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()
要求输入数据:
- 是二维数组或类似结构(如
numpy.ndarray
或pandas.DataFrame
)。- 数据应为数值类型。
- 不能包含缺失值(如
NaN
)。- 不能存在方差为 0 的特征列。
总结:
库 | 常见用途 |
---|---|
torch.nn.functional | 提供无状态的函数接口,包括激活函数、损失函数和卷积等神经网络常用操作 |
torch | PyTorch 的主库,负责张量计算、自动微分、GPU 加速以及构建和训练神经网络 |
matplotlib.pyplot | 用于可视化训练过程中的数据,如绘制损失函数、精度曲线、分类结果等 |
numpy | 提供高效的数值计算,主要用于数据预处理,并可与 PyTorch 张量互操作 |
在深度学习任务中,这些库的组合使用非常常见,帮助我们高效地实现从数据处理、模型定义、训练到结果分析的全流程。
3、模块3
torch.utils.data
和 torchvision
都是 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 | 图像数据的预处理和增强操作,如转换为张量、标准化、裁剪、旋转等 | 用于图像数据的预处理和数据增强,提升模型泛化能力 |
总结:
TensorDataset
和DataLoader
:用于通用数据集(不仅限于图像),尤其是将自定义数据集转换成 PyTorch 的张量并高效加载。torchvision.datasets
和transforms
:专为计算机视觉任务设计,简化图像数据集的加载和预处理。
4、随机模块
在深度学习和数值计算中,生成随机数是一个非常常见的操作,不同的库提供了各自的随机函数。这些函数在生成随机数时,可能生成的范围、分布类型以及数据格式都不尽相同。下面,我将对 NumPy
的 np.random.rand()
、PyTorch
的 torch.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 张量,并且满足以下几个条件:
torch.randn()
: 生成符合 标准正态分布(均值为 0,标准差为 1)的随机数张量。
- 标准正态分布意味着生成的随机数可能为正数也可能为负数。
[784, 10]
: 指定了张量的形状。
- 这个张量是 784 行 10 列的矩阵(2D 张量)。这种尺寸的张量常用于深度学习中的全连接层权重初始化,例如用于手写数字识别任务的输入层(784 维)到输出层(10 类)。
dtype=torch.float
: 指定生成的张量的数据类型为float32
。
- PyTorch 中默认的浮点数类型是
torch.float32
(简写为torch.float
),这个选项确保生成的数是浮点数类型而不是其他类型(例如int
)。
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 内置模块 | 正态分布 | 浮点数 | 生成正态分布的随机数,用于概率实验或模拟。 |
总结
NumPy
的np.random.rand()
生成均匀分布的随机数,常用于数据初始化和处理。PyTorch
的torch.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.Tensor
或None
-
示例:
tensor = torch.randn(3, 4, requires_grad=True) y = tensor * 2 y.backward(torch.ones_like(tensor)) # 对 y 进行反向传播 print(tensor.grad) # 输出张量的梯度
6. .item()
-
作用:将包含单个元素的张量转换为 Python 标量(如
float
或int
)。 -
返回值类型:
float
或int
-
示例:
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 标量 | float 或 int |
.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 原生数据类型(如int
、float
)。- 使用场景:当你处理一个标量张量并需要将其转换为 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、TensorDataset
和 DataLoader
TensorDataset
和 DataLoader
是 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
)打包为可迭代对象的类,方便进行批量化数据读取,支持多线程、随机打乱和数据划分等功能。
参数:
dataset
:Dataset
对象,例如TensorDataset
,或你自定义的继承自torch.utils.data.Dataset
的类实例。batch_size
(可选):每个批次中数据的样本数量。默认为1
。shuffle
(可选):是否在每个 epoch 开始时随机打乱数据。默认为False
。sampler
(可选):自定义的数据采样方式,通常不需要直接指定,使用默认即可。batch_sampler
(可选):自定义批量采样方式,与batch_size
和shuffle
互斥。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、pandas
的 Series
、numpy
的 ndarray
和 Python 的内置 list
pandas
的 Series
、numpy
的 ndarray
和 Python 的内置 list
都是存储和操作数据的结构,但它们在功能、性能和使用场景上有很大的不同。以下是它们之间的详细对比:
特性 | pandas.Series | numpy.ndarray | Python list |
---|---|---|---|
类型 | pandas.Series 对象 | numpy.ndarray 对象 | Python 内置 list |
维度 | 一维 | 通常多维(可以是1D、2D、3D等) | 一维 |
索引 | 有标签索引(可以是非整数) | 只有整数索引 | 只有整数索引 |
元素类型 | 支持混合类型,但通常使用一种类型 | 同一数组中必须是同一数据类型 | 支持不同数据类型 |
缺失值处理 | 原生支持 NaN 或 None | 不原生支持,需要 masked arrays | 支持 None |
广播 | 支持广播 | 支持广播 | 不支持广播 |
性能 | 较高效,但比 ndarray 慢 | 高效,适合数值计算 | 较低效,适合小规模数据处理 |
内置函数 | 丰富的基于标签的操作 | 主要用于数值运算 | 无数值运算或高级数据操作支持 |
主要用途 | 结构化数据分析 | 数值计算,矩阵运算 | 通用的数据存储和简单操作 |
详细解释:
-
数据结构与索引
Series
是pandas
的一维数据结构,类似于带有索引的数组。与ndarray
不同的是,Series
可以拥有标签索引,而不仅限于整数索引,这使得它非常适合与表格数据(如数据库、Excel文件)中的数据一起使用。Series
的索引可以是字符串、日期等非整数类型。ndarray
是numpy
的基础数据结构,支持任意维度的数组(如1D、2D、3D等)。所有的元素必须是相同的类型,且只能通过整数索引访问。list
是 Python 内置的通用容器,可以存储不同类型的数据,但没有像Series
或ndarray
那样的高级数值操作功能。
-
类型一致性
Series
和ndarray
中的元素通常是同一类型(尽管Series
可以支持混合类型,但这样做会导致性能下降),这使得它们在处理数值数据时效率更高。list
可以存储任何类型的数据,灵活性更高,但也因此在进行数值计算时效率较低。
-
缺失值处理
Series
对NaN
(空值)的处理是内置的,并且对操作缺失数据的函数支持良好。ndarray
需要额外的模块(如numpy.ma
)来处理缺失值。list
支持存储None
来表示缺失值,但没有专门的缺失值处理功能。
-
广播机制
ndarray
和Series
都支持广播操作。例如,向ndarray
添加一个标量会将该标量应用到数组中的每个元素。同样的操作对Series
也可以使用。list
不支持广播运算,类似的操作需要用循环实现。
-
性能
ndarray
由于其固定数据类型和底层的C语言实现,性能通常比Series
和list
更好,尤其是处理大型数值计算时。Series
尽管功能强大,但其性能在数值计算方面不如ndarray
,因为它需要维护索引信息。list
在处理大规模数据时性能最差,尤其是在进行大量数值运算时。
-
功能与用途
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
对象,适合处理大规模数据和灵活的格式。 - 特点:
- 可以将多种格式的数据(包括字符串、数值、列表等)自动解析为日期类型。
- 能够处理多个列,如
year
、month
、day
的组合。 - 适合处理时间序列数据,且支持更复杂的日期操作,如处理缺失值、无效数据等。
- 输出的结果是
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() |
---|---|---|
模块 | pandas | datetime |
用途 | 用于处理大规模数据,支持多种格式 | 处理单个字符串,严格按照指定格式解析 |
输入类型 | 字符串、数值、多个列等多种类型 | 单个字符串,必须指定格式 |
返回类型 | pandas.Timestamp 或 DatetimeIndex | datetime.datetime 对象 |
处理多个列 | 支持,如将 year 、month 、day 组合 | 不支持 |
灵活性 | 高,能自动识别多种格式 | 低,格式必须明确指定 |
应用场景 | 数据分析、时间序列处理 | 单次字符串到日期的转换 |
4. 总结
- 如果你处理的是大规模数据或需要从多个列(如
year
、month
、day
)生成日期,使用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)