基于吴恩达老师的深度学习作业,老师所用的是tensorflow,而且版本较老,因为近期接触的是pytorch,打算自己通过pytorch来搭建。
Dataset:
class CNNTrainDataSet(Dataset):
def __init__(self, data_file, transform=None, target_transform=None):
self.transform = transform
self.target_transform = target_transform
data = h5py.File(data_file, 'r') # 这里的内容以实际情况为准
self.train_set_x_orig = data['train_set_x']
self.train_set_y_orig = data['train_set_y']
def __len__(self):
return len(self.train_set_y_orig)
def __getitem__(self, idx):
x = self.train_set_x_orig[idx]
y = self.train_set_y_orig[idx]
if self.transform:
x = self.transform(x)
if self.target_transform:
y = self.target_transform(y)
return x, y
# 测试数据集
class CNNTestDataSet(Dataset):
def __init__(self, data_file, transform=None, target_transform=None):
self.transform = transform
self.target_transform = target_transform
data = h5py.File(data_file, 'r')
self.test_set_x_orig = data['test_set_x']
self.test_set_y_orig = data['test_set_y']
def __len__(self):
return len(self.test_set_y_orig)
def __getitem__(self, idx):
x = self.test_set_x_orig[idx]
y = self.test_set_y_orig[idx]
if self.transform:
x = self.transform(x)
if self.target_transform:
y = self.target_transform(y)
return x, y
# 主函数main.py
# Loading the data
train_data = CNNTrainDataSet(
data_file='datasets/train_signs.h5',
transform=Lambda(lambda x: torch.tensor(x / 255).permute(2, 0, 1).float()), # HWC转CHW
target_transform=Lambda(lambda x: torch.tensor(x))
)
test_data = CNNTestDataSet(
data_file='datasets/test_signs.h5',
transform=Lambda(lambda x: torch.tensor(x / 255).permute(2, 0, 1).float()),
target_transform=Lambda(lambda x: torch.tensor(x))
)
获取到数据集后加载到dataloader打乱
# shuffle the data
train_loader = DataLoader(train_data, batch_size=90, shuffle=True)
test_loader = DataLoader(test_data, batch_size=10, shuffle=True)
图片示例:

index = 6
plt.imshow(train_data.train_set_x_orig[index])
print('y = ' + str(train_data.train_set_y_orig[index]))
plt.show()
y = 2
检查数据大小:
print('number of training examples = ' + str(train_data.__len__()))
print('number of test examples = ' + str(test_data.__len__()))
print('X_train shape = ' + str(train_data.train_set_x_orig.shape))
print('Y_train shape = ' + str(train_data.train_set_y_orig.shape))
print('X_test shape = ' + str(test_data.test_set_x_orig.shape))
print('Y_test shape = ' + str(test_data.test_set_y_orig.shape))
number of training examples = 1080
number of test examples = 120
X_train shape = (1080, 64, 64, 3)
Y_train shape = (1080,)
X_test shape = (120, 64, 64, 3)
Y_test shape = (120,)
搭建卷积神经网络:
class ConvolutionNeuralNetwork(nn.Module):
def __init__(self):
super(ConvolutionNeuralNetwork, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(3, 8, kernel_size=(4, 4), stride=(1, 1)),
nn.ReLU(),
nn.MaxPool2d(kernel_size=(8, 8), stride=8),
)
self.conv2 = nn.Sequential(
nn.Conv2d(8, 16, kernel_size=(2, 2), stride=(1, 1)),
nn.ReLU(),
nn.MaxPool2d(kernel_size=(4, 4), stride=4),
)
self.fc = nn.Sequential(
nn.Flatten(),
nn.Linear(16, 6)
)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.fc(x)
return x
将模型载入到硬件设备:
# define hardware
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# load device
model = ConvolutionNeuralNetwork().to(device)
定义参数:
# parameter
epoch = 100
learning_rate = 0.009
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), learning_rate)
训练函数:
def train_loop(loader, model, loss_fn, optimizer, epoch, train):
for epoch in range(epoch):
for batch, (x, y) in enumerate(loader):
batch_x = Variable(x)
batch_y = Variable(y)
res = model(batch_x)
loss = loss_fn(res, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if batch % 12 == 0:
print(loss)
torch.save(model, 'model.pth') # 保存模型
训练:
train_loop(train_loader, model, loss_fn, optimizer, epoch, train_data)
测试函数:
def test_loop(loader, model, loss_fn):
# 这里的训练都是抽出一部分,没有进行全体的测试
size = len(loader.dataset)
num_batches = len(loader)
test_loss, accuracy = 0, 0
with torch.no_grad():
for Batch, (x, y) in enumerate(loader):
pred = model(x)
test_loss += loss_fn(pred, y).item()
accuracy += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batches
accuracy /= size
print(f"Test Error: \n Accuracy: {(100 * accuracy):>0.1f}%, Avg loss: {test_loss:>8f} \n")
测试:
model = torch.load('model.pth')
test_loop(train_loader, model, loss_fn) # 训练集准确率
test_loop(test_loader, model, loss_fn) # 测试集准确率
因为mini_batch下降的特点,每次的训练结果都不太一样,这里我得到了以下的结果:
Test Error:
Accuracy: 81.9%, Avg loss: 0.512246
Test Error:
Accuracy: 77.5%, Avg loss: 0.595191
看着还行。附上引入的库:
import h5py
import torch
from cnn_myutils import * # 自定义的工具类
from torchvision.transforms import ToTensor, Lambda
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from torch import nn
import numpy as np
import torchvision.models as models
from torch.utils.data import Dataset
from torch.autograd import Variable
本文档展示了如何使用PyTorch构建卷积神经网络,从数据集加载到模型训练,再到测试。作者首先定义了CNNTrainDataSet和CNNTestDataSet类,分别用于加载训练和测试数据。然后创建了一个简单的卷积神经网络模型,并将其部署到GPU(如果可用)。训练过程使用Adam优化器,损失函数为交叉熵损失。最后,提供了训练和测试数据的准确率及平均损失。

1000

被折叠的 条评论
为什么被折叠?



