PyTorch实现建立自己的数据集(以MNIST为例)
在PyTorch中,我们可以使用自己的数据集来训练模型。本文将提供一个完整的攻略,介绍如何使用Python和PyTorch实现建立自己的数据集,并提供两个示例,分别是使用自己的数据集进行多分类和使用自己的数据集进行图像分类。
示例1:使用自己的数据集进行多分类
以下是一个示例,展示如何使用自己的数据集进行多分类。
准备数据
首先,我们需要准备数据。我们可以使用scikit-learn库中的make_classification函数生成一个随机的多分类数据集。
from sklearn.datasets import make_classification
import torch
from torch.utils.data import Dataset
class MyDataset(Dataset):
def __init__(self):
X, y = make_classification(n_samples=1000, n_features=10, n_classes=5)
self.X = torch.from_numpy(X).float()
self.y = torch.from_numpy(y).long()
def __len__(self):
return len(self.X)
def __getitem__(self, idx):
return self.X[idx], self.y[idx]
dataset = MyDataset()
在这个示例中,我们定义了一个名为MyDataset的类,该类继承自PyTorch中的Dataset类。在MyDataset类的构造函数中,我们使用make_classification函数生成一个随机的多分类数据集,并将数据集转换为PyTorch张量。在MyDataset类中,我们还实现了__len__和__getitem__方法,以便在训练过程中使用PyTorch的DataLoader类加载数据。
定义模型
接下来,我们需要定义一个模型。在这个示例中,我们定义了一个简单的全连接神经网络模型。
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(10, 20)
self.fc2 = nn.Linear(20, 5)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
net = Net()
在这个示例中,我们定义了一个名为Net的类,该类继承自PyTorch中的nn.Module类。在Net类的构造函数中,我们定义了两个全连接层。在Net类中,我们还实现了forward方法,以便在训练过程中使用PyTorch的优化器更新权重。
训练模型
现在,我们可以开始训练模型了。在这个示例中,我们使用PyTorch的DataLoader类加载数据,并使用PyTorch的交叉熵损失函数和随机梯度下降优化器。
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.1)
for epoch in range(100):
running_loss = 0.0
for i, data in enumerate(dataset, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch + 1}, Loss: {running_loss / len(dataset)}')
在这个示例中,我们使用PyTorch的DataLoader类加载数据,并在每个epoch中计算损失函数的值。最后,我们使用测试集评估模型的准确性。
示例2:使用自己的数据集进行图像分类
以下是一个示例,展示如何使用自己的数据集进行图像分类。
准备数据
首先,我们需要准备数据。在这个示例中,我们将使用自己的数据集,该数据集包含一些手写数字图像。
import os
import numpy as np
from PIL import Image
import torch
from torch.utils.data import Dataset
class MyDataset(Dataset):
def __init__(self, root_dir):
self.root_dir = root_dir
self.images = []
self.labels = []
for i, label in enumerate(os.listdir(root_dir)):
for file_name in os.listdir(os.path.join(root_dir, label)):
image = Image.open(os.path.join(root_dir, label, file_name))
image = np.array(image)
self.images.append(image)
self.labels.append(i)
self.images = np.array(self.images)
self.labels = np.array(self.labels)
self.images = torch.from_numpy(self.images).float()
self.labels = torch.from_numpy(self.labels).long()
def __len__(self):
return len(self.images)
def __getitem__(self, idx):
return self.images[idx], self.labels[idx]
dataset = MyDataset('data')
在这个示例中,我们定义了一个名为MyDataset的类,该类继承自PyTorch中的Dataset类。在MyDataset类的构造函数中,我们遍历数据集中的所有图像,并将它们转换为PyTorch张量。在MyDataset类中,我们还实现了__len__和__getitem__方法,以便在训练过程中使用PyTorch的DataLoader类加载数据。
定义模型
接下来,我们需要定义一个模型。在这个示例中,我们定义了一个卷积神经网络模型。
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = torch.relu(self.conv1(x))
x = self.pool(x)
x = torch.relu(self.conv2(x))
x = self.pool(x)
x = x.view(-1, 64 * 7 * 7)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
net = Net()
在这个示例中,我们定义了一个名为Net的类,该类继承自PyTorch中的nn.Module类。在Net类的构造函数中,我们定义了两个卷积层和两个全连接层。在Net类中,我们还实现了forward方法,以便在训练过程中使用PyTorch的优化器更新权重。
训练模型
现在,我们可以开始训练模型了。在这个示例中,我们使用PyTorch的DataLoader类加载数据,并使用PyTorch的交叉熵损失函数和随机梯度下降优化器。
import torch.optim as optim
from torchvision.transforms import ToTensor
transform = ToTensor()
train_dataset = MyDataset('data/train', transform=transform)
test_dataset = MyDataset('data/test', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.1)
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(train_loader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch + 1}, Loss: {running_loss / len(train_loader)}')
correct = 0
total = 0
with torch.no_grad():
for data in test_loader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy: {correct / total}')
在这个示例中,我们使用PyTorch的DataLoader类加载数据,并在每个epoch中计算损失函数的值。最后,我们使用测试集评估模型的准确性。
总结
本文提供了一个完整的攻略,介绍了如何使用Python和PyTorch实现建立自己的数据集,并提供了两个示例,分别是使用自己的数据集进行多分类和使用自己的数据集进行图像分类。在实现过程中,我们使用了PyTorch和scikit-learn等库,并介绍了一些常用的函数和技术。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:pytorch实现建立自己的数据集(以mnist为例) - Python技术站