使用pytorch搭建卷积神经网络

本文档展示了如何使用PyTorch构建卷积神经网络,从数据集加载到模型训练,再到测试。作者首先定义了CNNTrainDataSet和CNNTestDataSet类,分别用于加载训练和测试数据。然后创建了一个简单的卷积神经网络模型,并将其部署到GPU(如果可用)。训练过程使用Adam优化器,损失函数为交叉熵损失。最后,提供了训练和测试数据的准确率及平均损失。
摘要由CSDN通过智能技术生成
使用pytorch构建卷积神经网络

基于吴恩达老师的深度学习作业,老师所用的是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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值