Pytorch搭建SIGNS数据集训练模型

文章介绍了如何使用SIGNS数据集训练一个卷积神经网络模型进行手势识别,包括数据预处理、模型构建、训练过程以及性能评估。作者展示了如何将H5格式数据转换为TensorFlow所需的格式,并详细描述了模型结构和训练步骤。
摘要由CSDN通过智能技术生成

SIGNS数据集介绍

SIGNS数据集包含了手势从0~5的照片,其中:

  • 训练集:1080张图片(64 x 64像素)的手势表示从0到5的数字(每个数字180张图片)。
  • 测试集:120张图片(64 x 64像素)的手势表示从0到5的数字(每个数字20张图片)。

 数据集处理

本文使用的SIGNS数据集格式为h5,我们可以先将数据集转换为numpy格式,可先用一下代码进行转换:

#下载h5格式的数据集
def load_dataset():
    train_dataset = h5py.File('datasets/train_signs.h5', "r")
    train_set_x_orig = np.array(train_dataset["train_set_x"][:])  # your train set features
    train_set_y_orig = np.array(train_dataset["train_set_y"][:])  # your train set labels

    test_dataset = h5py.File('datasets/test_signs.h5', "r")
    test_set_x_orig = np.array(test_dataset["test_set_x"][:])  # your test set features
    test_set_y_orig = np.array(test_dataset["test_set_y"][:])  # your test set labels

    classes = np.array(test_dataset["list_classes"][:])  # the list of classes

    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))

    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes

train_data, train_label, test_data, test_label, classes=load_dataset()

由于在利用pytorch训练时,输入网络的数据维度应为(个数,通道数,像素,像素),但输出train_data.shape会得到(1080,64,64,3),说明通道数被放在了最后,我们需要进行维度转换,从而将其放在第二位,可利用np.transpose进行numpy格式的维度转换:

# print(train_data.shape) #(1080, 64, 64, 3)
# print(train_label.shape) #(1, 1080)
train_data=np.transpose(train_data,(0,3,1,2)) #因为pytorch训练时输入网络的数据图像的通道数应在像素值之前,因此需进行转换
test_data=np.transpose(test_data,(0,3,1,2))
# print(train_data.shape) #(1080, 3, 64, 64)
# print(test_data.shape) #(120, 3, 64, 64)

最后将numpy格式转换成tensor格式,然后对图像、标签进行打包合并:

#加载数据集
train_xy=TensorDataset(train_data,train_label)
test_xy=TensorDataset(test_data,test_label)
train=DataLoader(train_xy,batch_size=64,shuffle=True)
test=DataLoader(test_xy,batch_size=64)

搭建网络

因为最后需要判断0~5共6种手势,所以网络的最后的输出维度需要是6×1×1。输入维度为3×64×64,笔者搭建的网络先通过4个卷积层将像素变为4、通道数为256后,再进入全连接层。网络模型如下:
 

class signs_cnn(nn.Module):
    def __init__(self):
        super(signs_cnn, self).__init__()
        self.model_conv=nn.Sequential( # n=64
            nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,stride=1,padding=2), #64
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2,stride=2), #32

            nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,stride=1,padding=2), #32
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2), #16

            nn.Conv2d(in_channels=64,out_channels=128,kernel_size=5,stride=1,padding=2), #16
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2), #8

            nn.Dropout(0.5),
            nn.Conv2d(in_channels=128, out_channels=256, kernel_size=5, stride=1, padding=2), #8
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)  #4
        )

        self.model_linear=nn.Sequential(
            nn.Linear(4*4*256,256),
            nn.ReLU(),

            nn.Linear(256,16),
            nn.ReLU(),

            nn.Linear(16,6)
        )

    def forward(self,x):
        x=self.model_conv(x)
        x=x.view(x.shape[0],-1) #一行对应一张照片
        x=self.model_linear(x)
        return x

训练模型

设置相关参数,对模型进行训练,并计算loss、accuracy等值。这里需要注意,输入网络前需要将图像(inputs)强转为float形式;计算损失值loss前需要将标签(labels)强转为long形式。

model=signs_cnn()
model.to(device)

loss_fn=nn.CrossEntropyLoss()
loss_fn.to(device)

learning_rate=0.0001
optimizer=torch.optim.SGD(params=model.parameters(),lr=learning_rate,momentum=0.9)

train_acc_list = []
train_loss_list = []
test_acc_list = []
test_loss_list=[]
epochs=150

for epoch in range(epochs):
    print("-----第{}轮训练开始------".format(epoch + 1))
    train_loss = 0.0
    test_loss = 0.0
    train_sum, train_cor, test_sum, test_cor = 0, 0, 0, 0

    #训练步骤开始
    model.train()
    for batch_idx,data in enumerate(train):
        inputs,labels=data
        inputs, labels = inputs.to(device), labels.to(device)
        labels = torch.tensor(labels, dtype=torch.long)

        optimizer.zero_grad()
        outputs=model(inputs.float())
        loss=loss_fn(outputs,labels)
        loss.backward()
        optimizer.step()

        # 计算每轮训练集的Loss
        train_loss+=loss.item()

        # 计算每轮训练集的准确度
        _, predicted = torch.max(outputs.data, 1)  # 选择最大的(概率)值所在的列数就是他所对应的类别数,
        train_cor += (predicted == labels).sum().item()  # 正确分类个数
        train_sum += labels.size(0)  # train_sum+=predicted.shape[0]

    #测试步骤开始
    model.eval()
    for batch_idx1,data in enumerate(test):
        inputs,labels=data
        inputs,labels=inputs.to(device),labels.to(device)
        labels = torch.tensor(labels, dtype=torch.long)

        outputs=model(inputs.float())
        loss=loss_fn(outputs,labels)

        test_loss += loss.item()
        _, predicted = torch.max(outputs.data, 1)
        test_cor += (predicted == labels).sum().item()
        test_sum += labels.size(0)

    print("Train loss:{}   Train accuracy:{}%   Test loss:{}   Test accuracy:{}%".format(train_loss / batch_idx,
                                                                                         100 * train_cor / train_sum,
                                                                                         test_loss / batch_idx1,
                                                                                         100 * test_cor / test_sum))

    train_loss_list.append(train_loss / batch_idx)
    train_acc_list.append(100 * train_cor / train_sum)
    test_acc_list.append(100 * test_cor / test_sum)
    test_loss_list.append(test_loss / batch_idx1)

#保存网络
torch.save(model,"signs_epoch{}.pth".format(epochs))

画图

fig=plt.figure()
plt.plot(range(len(train_loss_list)),train_loss_list,'blue')
plt.plot(range(len(test_loss_list)),test_loss_list,'red')
plt.legend(['Train Loss','Test Loss'],fontsize=14,loc='best')
plt.xlabel('Epoch',fontsize=14)
plt.ylabel('Loss',fontsize=14)
plt.grid()
plt.savefig('figLOSS_SIGNS_epoch{}'.format(epochs))
plt.show()

fig=plt.figure()
plt.plot(range(len(train_acc_list)),train_acc_list,'blue')
plt.plot(range(len(test_acc_list)),test_acc_list,'red')
plt.legend(['Train Accuracy','Test Accuracy'],fontsize=14,loc='best')
plt.xlabel('Epoch',fontsize=14)
plt.ylabel('Accuracy(%)',fontsize=14)
plt.grid()
plt.savefig('figAccuracy_SIGNS_epoch{}'.format(epochs))
plt.show()

### 回答1: 手势识别是一种通过分析人类手部动作进行交互的技术。其中,Signs数据集是一个常用的手势识别数据集,它包含了用于手势识别的图像和标签。 Signs数据集由一个多类别手势图像组成,每个类别代表一个手势,例如数字0到5和字母A到Z等。数据集中的每个图像的尺寸相同,并且以RGB格式表示。标签是通过将每个手势映射到一个类别标签而获得的。 使用Signs数据集可以进行手势识别的模型训练和评估。为了训练,可以使用卷积神经网络(Convolutional Neural Network,CNN)等深度学习模型来提取图像特征并进行分类。训练的过程中,可以使用训练数据对模型进行优化,以提高其在手势识别任务上的准确性。 在模型训练完成后,可以使用Signs数据集的测试数据对模型进行评估。通过评估模型在测试数据上的准确性,可以判断其在实际手势识别任务中的表现。通过反复调整模型的结构和参数,可以提高模型的准确率并逐步接近最佳性能。 手势识别的应用非常广泛,例如虚拟现实、智能家居和医疗领域等。通过准确地识别手势,可以实现手势控制的交互方式,使人机交互更加自然和便捷。因此,Signs数据集对于手势识别算法的研究和应用具有重要意义。 ### 回答2: 手势识别是一种技术,通过分析和解释人类手部的动作和姿势,来实现对手势的识别和理解。signs数据集是一个用于手势识别研究的数据集,它包含了一系列不同的手势图像。这些手势图像是由不同的人以不同的角度和动作拍摄而成。 signs数据集中的手势图像包括了一些常见的手势,比如数字手势、字母手势等。通过对这些手势图像进行分析和处理,可以帮助计算机系统理解人类的手势动作,进而实现与人的交互。 在手势识别的研究中,signs数据集可以用来训练和测试手势识别算法和模型。通过对这个数据集进行机器学习和深度学习的算法训练,可以建立更加准确和稳定的手势识别系统。 除了手势识别,signs数据集还可以用于其他相关研究领域,比如人机交互、增强现实等。通过对这个数据集的研究和分析,可以提高人机交互的效率和便捷性,为用户提供更好的交互体验。 总之,手势识别signs数据集是一个用于手势识别研究的数据集,通过对其中的手势图像进行分析和处理,可以实现对人类手势动作的识别和理解。这个数据集对于机器学习、深度学习和人机交互等领域的研究都具有重要的意义。 ### 回答3: 手势识别是一种计算机视觉技术,旨在识别和理解人类手势的意图和动作。手势识别signs数据集是一个常用的数据集,用于训练和测试手势识别算法。 该数据集包含了手势识别的相关图像和标签。图像是以数字形式表示的像素矩阵,其中包含了手部的图像信息。每个图像对应一个标签,标签表示了该手势的类别,例如数字手势识别中的0到9,或者其他指定的手势类别。 使用手势识别signs数据集,可以进行训练和测试手势识别算法。首先,需要将数据集划分为训练集和测试集。训练集用于训练算法模型,而测试集用于评估算法的性能。 常见的手势识别算法包括深度学习算法,如卷积神经网络(CNN)。通过深度学习的方法,可以提取图像中的特征,并将其与对应的手势类别进行关联。在训练过程中,算法会通过反向传播来优化模型的参数,使其能够更准确地进行手势识别。 在测试过程中,可以使用测试集来评估算法的准确性。通过比较预测结果和真实标签,可以计算出准确率、精确率、召回率等评价指标,从而评估算法的性能。 总结来说,手势识别signs数据集是用于训练和测试手势识别算法的数据集。通过合理划分数据集,使用适当的算法和评价指标,可以实现对手势图像的自动识别和分类。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值