基于迁移学习的手势分类模型训练

1、基本原理介绍

       这里介绍的单指模型迁移。一般我们训练模型时,往往会自定义一个模型类,这个类中定义了神经网络的结构,训练时将数据集输入,从0开始训练;而迁移学习中(单指模型迁移策略),是在一个已经有过训练基础的模型上,用自己的数据集,进一步训练,使得这个模型能够完成我们需要的任务。

这么做有有这样几个显而易见的好处:

※  因为模型之前被训练过,所以初始参数不会是0,这样能够加速模型训练

※  因为预训练模型(什么是预训练模型下文会讲到)在其他数据集上训练过,而其他数据集往往和我们用的数据集存在一定的区别,所以这可以提高模型的泛化能力

※  通过迁移学习,可以将来自大规模数据的优势转移到小规模或新任务上,提高模型的表现和效果

2、预训练模型

        在进行迁移学习时,我们要先找到一个预训练模型。在分类任务领域,比较流行的如resnet系列、mobilenet系列(更轻量化)、vgg(系列)、efficientnet(系列)等等网络,都是比较常用且容易获得的预训练模型,这些模型都能够通过python直接下载。

        而且由于上述模型基本都是在ImageNet这一大规模,多分类类别的数据集上进行过训练的,所以对于简单的二分类等少数类别分类,能有较好的效果。

3、训练流程

迁移学习完整的训练流程和一般搭建神经网络的训练模型的流程基本类似:数据预处理->数据集的切分->加载预训练模型(搭建神经网络)->设置超参数/损失函数/优化器等->训练模型

3.1 模型训练

下面的代码是一个利用mobilenet网络训练得到的手势分类模型,该模型能够较准确的分类不同类别手势。

相关解释已在代码中注释说明。

from torchvision.models import mobilenet_v2
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
from torchvision.transforms import Compose, Resize, CenterCrop, ToTensor, Normalize, RandomHorizontalFlip, RandomRotation

# 定义数据预处理和增强器
transform = Compose([
    RandomHorizontalFlip(),  # 随机水平翻转
    RandomRotation(10),      # 随机旋转10度
    Resize((224, 224)),
    CenterCrop(224),
    ToTensor(),
    Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 加载数据集并应用预处理和增强器
dataset = ImageFolder(root='data', transform=transform)
# 这里由于数据比较少,将所有数据集全部用来训练,得到的模型直接拿来用了,这其实不算是非常规范的操作,仅供参考


# 定义网络结构
model = mobilenet_v2(pretrained=True)  # 加载预训练模型,也可以试试其他模型,效果差别挺大的
num_ftrs = model.classifier[1].in_features
model.classifier[1] = nn.Linear(num_ftrs, 5)  # 假设是5分类问题,具体几分类,改这里的参数就行了

# 将模型移动到设备上
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)

# 定义优化器和损失函数
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-5)
criterion = nn.CrossEntropyLoss()

# 定义训练循环
def train_model(model, criterion, optimizer, num_epochs, train_loader):
    for epoch in range(num_epochs):
        model.train()  # 设置模型为训练模式
        train_loss = 0.0
        correct = 0
        total = 0

        for inputs, labels in train_loader:
            inputs, labels = inputs.to(device), labels.to(device)

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

            train_loss += loss.item() * inputs.size(0)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

        epoch_loss = train_loss / total
        epoch_acc = 100. * correct / total

        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss:.4f}, Accuracy: {epoch_acc:.2f}%')


# 创建训练集的DataLoader
train_loader = DataLoader(dataset, batch_size=32, shuffle=True)

# 开始训练模型
train_model(model, criterion, optimizer, num_epochs=15, train_loader=train_loader)
torch.save(model, 'my_model(1).pth')

3.2 数据集文件结构

当然,你也可以自己定义读取数据集的data_loader类。

3.3 模型推理

这段代码是用训练得到的模型对一张图片进行推理测试的,如果需要对系列图片进行推理,评估模型效果,可自行修改,调用对应函数即可。

import torch
from PIL import Image
from torchvision.transforms import Compose, Resize, CenterCrop, ToTensor, Normalize
def predict_image(image_path, model_path='my_model(1).pth'):

    image = Image.open(image_path).convert("RGB")
    # 对测试的图片进行预处理,需要和训练时处理的方式一样
    transform = Compose([
        Resize((224, 224)),
        CenterCrop(224),
        ToTensor(),
        Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])

    image_tensor = transform(image).unsqueeze(0)
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    image_tensor = image_tensor.to(device)


    model = torch.load(model_path,map_location=device)
    model.eval()
    with torch.no_grad():
        output = model(image_tensor)
        _, predicted = torch.max(output.data, 1)  # 获得分类标记
    return predicted.item()
if __name__=="__main__":
    image_path = "test2/6.jpg"
    print(predict_image(image_path))

3.4 整体项目文件

4、补充说明

        这种利用迁移学习策略,进行少类别,不同类别特征差距小的任务需求来说,效果一般来说是比较好的。因为之前做过相关实验,准确率90%以上是很容易的,所以这里没有模型评估,生成混淆矩阵等过程。对于多类别分类,建议有完整的评估体系。

        上述使用的方法仅适用于分类任务,对于真正的目标检测如手势识别,直接使用该模型的问题是:由于无法定位手势的位置,所以导致识别不准确。

        本实验数据集是不同类别手势图片,为自制,不开源。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 非常感谢您的提问。关于使用Python基于迁移学习训练一个模型的问题,我可以回答。 使用Python进行迁移学习训练一个模型的步骤如下: 1. 选择一个预训练模型,如VGG、ResNet或Inception等。 2. 用预训练模型作为特征提取器,提取输入数据集的特征。 3. 将提取的特征输入到一个新的全连接层中,用于分类或回归。 4. 对新的全连接层进行训练,更新权重参数。 5. 对整个模型进行微调,包括预训练模型的权重和新的全连接层的权重。 6. 用测试数据集对模型进行评估,调整模型的超参数和训练参数,直到达到最佳性能。 以上是使用Python基于迁移学习训练一个模型的基本步骤。具体实现过程中,需要根据具体问题和数据集进行调整和优化。希望对您有所帮助。 ### 回答2: 使用Python利用迁移学习训练一个模型可以通过以下步骤进行: 1. 导入所需的Python库,如TensorFlow和Keras等。这些库提供了训练和构建模型所需的功能和工具。 2. 下载预训练模型权重。预训练模型通常是在大型数据集上进行训练后得到的,具有良好的特征提取能力。可以从TensorFlow和Keras的官方网站下载这些模型的权重。 3. 创建模型。使用Keras或TensorFlow等库创建一个模型。可以选择使用预训练模型的全部网络结构,也可以根据需要对其进行调整。 4. 设置迁移学习的方式。迁移学习可以通过冻结预训练模型的一部分或全部层来进行。冻结的层不会在训练过程中更新权重,而是保持原有的特征提取能力。可以根据任务需求选择合适的层进行冻结。 5. 设置自定义的输出层。根据要解决的具体问题,添加适当的自定义输出层。输出层的结构和神经元数量通常根据数据集和任务类型进行调整。 6. 编译和训练模型。编译模型需要设置损失函数、优化器和评估指标等。然后,使用数据集对模型进行训练。可以根据需要设置训练的批次大小、迭代次数和学习率等参数。 7. 进行模型评估和预测。使用测试集对训练好的模型进行评估,计算模型的准确率、损失值等指标。然后,使用模型进行预测,得出对新样本的分类结果。 8. 进行模型微调(可选)。根据实际情况,可以对模型进行微调,以进一步提高模型性能。可以解冻一些层进行训练,并根据需要进行调整。 9. 保存模型。将训练好的模型保存到硬盘上,以便在需要时进行加载和使用。 使用Python进行迁移学习训练模型可以简化模型构建的过程,并节省大量的训练时间。通过利用预训练模型的特征提取能力,可以在小规模数据集上实现高效的训练和预测。同时,Python提供了丰富的工具和库,使得迁移学习训练模型的过程更加方便和灵活。 ### 回答3: 基于迁移学习使用Python训练模型可以大大加快模型训练的速度和提高模型的准确性。迁移学习是指将已经在大规模数据集上训练好的深度学习模型的参数、网络架构等迁移到一个新的任务上进行训练。 首先,在Python中使用深度学习框架(如TensorFlow、PyTorch等)加载预训练好的模型。这些模型通常是在大规模数据集上进行训练得到的,如ImageNet数据集。可以使用框架提供的函数加载模型的参数,并创建一个新的模型结构。 接下来,冻结预训练模型的参数,即将这些参数设置为不可训练。这样做是因为预训练模型已经在大规模数据集上训练得到了较好的特征提取能力,我们只需要在新的任务上微调这些特征。 然后,在新的任务上构建新的模型结构,一般需要去掉原模型的输出层,并添加新的层来适应新的任务。根据新任务的要求,可以选择添加全连接层、卷积层或其他类型的层。 在构建新的模型结构后,使用Python编写代码进行模型训练。这包括指定损失函数、优化算法、学习率等超参数,并使用新的数据集进行训练。可以根据需要调整超参数,使用训练集和验证集来监控模型的性能,并进行适当的调整。 最后,使用训练好的模型在测试集或实际应用中进行评估。可以通过计算准确率、召回率、F1得分等指标来评估模型的性能。 总之,通过使用Python进行迁移学习,我们可以充分利用已有的预训练模型,快速训练一个适应新任务的模型。这种方法不仅可以节省数据集和计算资源的成本,还可以提高模型的准确性和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值