
将 Pandas DataFrame 转换为 PyTorch DataLoader 以便进行自定义深度学习模型训练。
图片来自:Editor | Ideogram
Pandas DataFrame 是功能强大且用途广泛的数据操作和分析工具。虽然这种数据结构的通用性无可否认,但在某些情况下——例如在使用 PyTorch 时——更结构化、更适合批处理的格式会更有效率,也更适合于训练深度学习模型,在这种情况下,DataLoader
类是首选解决方案。
在本文中,我们将展示如何将 Pandas DataFrame
对象中包含的数据集转换为 PyTorch DataLoader
对象,这将有助于在训练和评估期间更有效地将数据的小批量提供给模型,作为自定义深度学习模型训练工作流的一部分。我们将以一个简单的自定义深度学习模型为例,说明如何训练和评估该模型——即估计房价。
准备数据:从 DataFrame 到 DataLoader
该过程首先导入我们将需要的 Python 库和模块,主要是 Pandas 用于将数据集加载到 DataFrame
并进行预处理,PyTorch 模块如 Dataset
、DataLoader
,以及用于建模和训练神经网络模型的其他几个模块,以及用于支持初始数据准备的 scikit-learn 组件。
1 2 3 4 5 6 7 |
import pandas as pd import torch from torch.utils.data import Dataset, DataLoader import torch.nn as nn import torch.optim as optim from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler |
接下来的几条指令加载加州住房数据集,其中包含 20,000 多个实例,由八个预测属性描述——在 scikit-learn 的这个内置版本的数据集中,所有这些都是数值型的——外加一个目标数值标签:房屋中值。数据被加载到 Pandas DataFrame 中。
1 2 3 4 5 |
from sklearn.datasets import fetch_california_housing housing = fetch_california_housing(as_frame=True) df = housing.frame df.head() |
在将数据转换为适合 PyTorch 的格式之前,我们将目标变量分离到一个名为 y
的变量中,将其余数据输入保留在一个新的 DataFrame X
中。两者都被分成训练集(80%)和测试集(20%),以便之后进行模型训练和测试。由于某些属性的值范围比其他属性宽得多,我们还应用了特征缩放,由 scikit-learn 的 StandardScaler
类提供帮助。
1 2 3 4 5 6 7 8 |
X = df.drop(columns='MedHouseVal') y = df['MedHouseVal'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) |
通过这些步骤,数据预处理基本完成!现在是时候将它们转换为两个 DataLoader:一个用于训练集,一个用于测试集。我们通过定义一个继承 PyTorch Dataset
的自定义类来实现这一点。该类的对象,我们称之为 HousingDataset
,将包含两个属性:来自 X
的输入,以及来自 y
的输出。同样,我们重写了特殊的类方法 __len__()
和 __getitem()__
,它们分别返回实例数量和第i个实例。
1 2 3 4 5 6 7 8 9 10 |
class HousingDataset(Dataset): def __init__(self, features, targets): self.X = torch.tensor(features, dtype=torch.float32) self.y = torch.tensor(targets.values, dtype=torch.float32).view(-1, 1) def __len__(self): return len(self.X) def __getitem__(self, idx): return self.X[idx], self.y[idx] |
我们现在实例化两个新创建类的对象,一个用于训练数据/标签,一个用于测试数据/标签,如下所示:
1 2 |
train_dataset = HousingDataset(X_train, y_train) test_dataset = HousingDataset(X_test, y_test) |
最后,是时候创建两个相关的 DataLoader
实例了。用于训练数据的那一个将被打乱,以确保模型训练的无偏性。
1 2 |
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=64) |
您可能已经注意到,两个 DataLoader
对象都是基于前面两个 Dataset
对象实例化的。DataLoader
对象实际上不包含数据——这是自定义类 HousingDataset
的职责——但它负责迭代和管理其关联的数据集。
自定义模型训练和测试
既然我们有了可以使用的 PyTorch DataLoader
对象,为什么不构建一个简单的神经网络模型进行回归,然后使用这些对象对其进行训练和在测试数据上进行评估呢?下面的代码定义了一个非常直接的神经网络架构,它由两个全连接的线性层组成,中间用 ReLU 激活函数连接。
1 2 3 4 5 6 7 8 9 10 11 |
class SimpleModel(nn.Module): def __init__(self, input_dim): super(SimpleModel, self).__init__() self.net = nn.Sequential( nn.Linear(input_dim, 32), nn.ReLU(), nn.Linear(32, 1) ) def forward(self, x): return self.net(x) |
接下来,我们实例化一个基于此架构的模型,指定输入大小等于数据集中原始预测属性的数量,设置损失函数和优化器,并开始一个为期 10 个迭代或周期的训练循环。理想情况下,损失函数在每次训练迭代后应逐渐减小,这表明模型在训练数据本身上的预测能力正在收敛。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
model = SimpleModel(input_dim=X_train.shape[1]) criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=0.01) for epoch in range(10): model.train() total_loss = 0 for batch_X, batch_y in train_loader: optimizer.zero_grad() predictions = model(batch_X) loss = criterion(predictions, batch_y) loss.backward() optimizer.step() total_loss += loss.item() print(f"Epoch {epoch+1}, Loss: {total_loss:.4f}") |
请注意,在训练过程中,用于训练数据的 DataLoader train_loader
会被使用并分割成批次。最后,可以使用以下代码快速测试模型在测试实例上的预测误差(即使用均方误差 MSE),这得益于另一个 DataLoader test_loader
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from torch.nn import MSELoss model.eval() test_loss = 0 criterion = MSELoss() with torch.no_grad(): for batch_X, batch_y in test_loader: predictions = model(batch_X) loss = criterion(predictions, batch_y) test_loss += loss.item() * batch_X.size(0) average_test_loss = test_loss / len(test_loader.dataset) print(f"Test Mean Squared Error: {average_test_loss:.4f}") |
输出:Test Mean Squared Error: 0.3385
总结
本文介绍了将 Pandas DataFrame 中的数据集转换为 PyTorch DataLoader 的过程,这是高效训练和使用自定义深度学习模型的理想方法。
暂无评论。