基于pytorch的手势识别

该文介绍了使用PyTorch进行手势识别的实验,包括数据集处理、神经网络构建(含两个隐藏层,LeakyReLU激活函数和LayerNorm层)、网络训练(采用BCELoss损失函数和Adam优化器)及测试。训练集和测试集的准确率分别达到约99.83%和97.50%,显示出良好的模型性能。
摘要由CSDN通过智能技术生成

本次实验主要是使用pytorch完成手势识别。网络包含两个隐藏层,第一层隐藏层有576个节点,第二层隐藏层有144个节点,输入784个节点(图片大小为28×28),输出10个节点(10种手势)。

目录

1. 数据集处理

2. 神经网络的建立

3. 神经网络的训练

4. 神经网络的测试


1. 数据集处理

本次实验所用数据集为自建数据集,首先预览了解数据,确保数据能够被正常载入。

import pandas
from torch.utils.data import Dataset

import torch
import matplotlib.pyplot as plt


class GestureDataset(Dataset):
    def __init__(self, csv_file):
        self.dataset = pandas.read_csv(csv_file, header=0)

    def __len__(self):
        return len(self.dataset)

    def __getitem__(self, index):
        # 图像标签
        label = self.dataset.iloc[index, 0]
        target = torch.zeros(10)  # 神经网络预期输出
        target[label] = 1.0
        # 图像数据,取值范围是0~255,标准化为0~1
        image_value = torch.FloatTensor(self.dataset.iloc[index, 1:].values) / 255
        # 返回标签、图像数据张量以及目标张量
        return label, image_value, target

    def plot_image(self, index):
        arr = self.dataset.iloc[index, 1:].values.reshape(28, 28)
        plt.title("label = " + str(self.dataset.iloc[index, 0]))
        plt.imshow(arr, interpolation='none', cmap='gray')
        plt.show()


# 查看图片
gesture_dataset = GestureDataset('train.csv')
gesture_dataset.plot_image(9)
print(gesture_dataset[100])
print(len(gesture_dataset))

以上代码中各函数含义如下:

__len__() 函数的作用是返回DataFrame的大小。

__getitem__()函数索引获取数据集中的第 n 项,数据集中的第index项中提取一个标签(label)。返回值中的 target 表示神经网络的预期输出。除了与标签相对应的位置是1之外,其他值皆为0。比如手势 2 的 target 应该表示为[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]。

运行以上代码,结果如下:

2. 神经网络的建立

import torch
import torch.nn as nn

import pandas, numpy
import matplotlib.pyplot as plt


class Classifier(nn.Module):
    def __init__(self):
        # 初始化pytorch父类
        super().__init__()
        # 定义神经网络
        self.model = nn.Sequential(
            nn.Linear(784, 576),
            nn.LeakyReLU(0.02),

            nn.LayerNorm(576),

            nn.Linear(576, 144),
            nn.LeakyReLU(0.02),

            nn.LayerNorm(144),

            nn.Linear(144, 10),
            nn.Sigmoid()
        )

        # 创建损失函数
        self.Loss_function = nn.BCELoss()
        # 优化器
        self.optimiser = torch.optim.Adam(self.parameters(),
                                          lr=0.0001)
        # 记录训练进展的计数器和列表
        self.counter = 0
        self.process = []

    def forward(self, inputs):
        # 直接运行模型
        return self.model(inputs)

    def cnn_train(self, inputs, targets):
        # 计算网络的输出值
        outputs = self.forward(inputs)
        # 计算损失值
        loss = self.Loss_function(outputs, targets)
        # 梯度归零,反向传播,并更新权重
        self.optimiser.zero_grad()  # 梯度全部归零
        loss.backward()
        self.optimiser.step()  # 使用梯度更新可学习参数

        # 每隔10个训练样本增加一次计数器的值,并将损失值添加进列表的末尾,共36080张图片
        self.counter += 1
        if self.counter % 10 == 0:
            self.process.append(loss.item())

        # 在每10000次训练后打印计数器的值,了解训练进展的快慢
        if self.counter % 10000 == 0:
            print("counter=", self.counter)

    # 绘制训练过程的损失值
    def plot_progress(self):
        df = pandas.DataFrame(self.process, columns=["loss"])
        df.plot(ylim=(0, 1.0), figsize=(16, 8), alpha=0.1, marker='.',
                grid=True, yticks=(0, 0.25, 0.5))
        plt.show()

3. 神经网络的训练

数据集处理部分代码保存为gesture_dataset.py,神经网络的建立部分代码保存为gesture_cnn.py,在创建了网络后,需要使用数据集训练网络,并保存网络参数以便后续使用。

import torch

from gesture_dataset import GestureDataset
from gesture_cnn import Classifier

# 创建神经网络
C = Classifier()
gesture_dataset = GestureDataset('train.csv')
# 在数据集训练神经网络
epochs = 3
for i in range(epochs):
    print('training epoch', i + 1, "of", epochs)
    for label, image_data_tensor, target_tensor in gesture_dataset:
        C.cnn_train(image_data_tensor, target_tensor)
    pass
pass

# 绘制分类器损失值
C.plot_progress()
# 保存网络
torch.save(C.model, 'gesture_cnn_model.pkl')

4. 神经网络的测试

from gesture_dataset import GestureDataset

import torch
import pandas
import numpy as np
import matplotlib.pyplot as plt

# 加载测试集数据
test_dataset = GestureDataset('test.csv')
record = 19
test_dataset.plot_image(record)

image_data = test_dataset[record][1]
# 调用训练后的神经网络
cnn_model = torch.load('gesture_cnn_model.pkl')
output = cnn_model(image_data)
# 绘制输出张量
# pandas.DataFrame(output.detach().numpy()).plot(kind='bar',
#                                                legend=False, ylim=(0, 1))
# plt.show()

predict = output.detach().numpy()
print(np.where(predict == np.max(predict))[0][0])

# 测试正确率
T_test = 0
counter_test = 0

for label, image_data_tensor, target_tensor in test_dataset:
    predict = cnn_model(image_data_tensor).detach().numpy()
    if np.where(predict == np.max(predict))[0][0] == label:
        T_test += 1
    pass
    counter_test += 1
    if counter_test % 100 == 0:
        print('counter_test = ', counter_test)
pass

test_accuracy = T_test/len(test_dataset)
print('Test Accuracy = ', test_accuracy)

# 训练集正确率
train_dataset = GestureDataset('train.csv')

T_train = 0
counter_train = 0

for label, image_data_tensor, target_tensor in train_dataset:
    predict = cnn_model(image_data_tensor).detach().numpy()
    if np.where(predict == np.max(predict))[0][0] == label:
        T_train += 1
    pass
    counter_train += 1
    if counter_train % 1000 == 0:
        print('counter_train = ', counter_train)
pass

train_accuracy = T_train/len(train_dataset)
print('Train Accuracy = ', train_accuracy)
print(len(train_dataset))

测试结果如下:

网络最终在训练集上的正确率约为99.83%,在测试集上的正确率约为97.50%,测试结果表明网络性能较好,训练结果较好,最终的手势识别效果较好。

代码注释详细,作者能力有限,如有发现问题欢迎评论提出。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值