<Pytorch,Libtorch 调试记录3>Pytorch模型训练到Libtorch部署到QT软件上

1 pytorch模型训练
2 libtorch模型部署
(后续研究一下结合TensorRT)

python模型训练以及模型转换

import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

# 定义网络结构
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, 5, 1)
        self.conv2 = nn.Conv2d(10, 20, 5, 1)
        self.fc1 = nn.Linear(4 * 4 * 20, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 4 * 4 * 20)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

# 定义训练函数
def train(args, model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))

# 定义测试函数
def test(args, model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

# 主函数用于训练和测试
def main():
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=16, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=100, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=10, metavar='N',
                        help='number of epochs to train (default: 10)')
    parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--save-model', action='store_true', default=True,
                        help='For Saving the current Model')

    args = parser.parse_args()
    use_cuda = not args.no_cuda and torch.cuda.is_available()
    torch.manual_seed(args.seed)
    device = torch.device("cuda" if use_cuda else "cpu")
    kwargs = {'num_workers': 0, 'pin_memory': True} if use_cuda else {}
    train_loader = torch.utils.data.DataLoader(
        datasets.MNIST('../data', train=True, download=False,
                       transform=transforms.Compose([
                           transforms.ToTensor(),
                           transforms.Normalize((0.1307,), (0.3081,))
                       ])),
        batch_size=args.batch_size, shuffle=True, **kwargs)
    test_loader = torch.utils.data.DataLoader(
        datasets.MNIST('../data', train=False, transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.1307,), (0.3081,))
        ])),
        batch_size=args.test_batch_size, shuffle=True, **kwargs)

    model = Net().to(device)
    optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)

    for epoch in range(1, args.epochs + 1):
        train(args, model, device, train_loader, optimizer, epoch)
        test(args, model, device, test_loader)

    if (args.save_model):
        torch.save(model.state_dict(), "mnist_cnn.pt")
        model = model.to(torch.device("cpu"))
        model.eval()
        var = torch.ones((1, 1, 28, 28))
        traced_script_module = torch.jit.trace(model, var)
        traced_script_module.save("mnist_cnn_jit.pt")


from torchvision.models import resnet101
import torch.nn.functional as F
import torch.nn as nn
import torch
import cv2

# import os
# os.system("pip install opencv-python") # 代码安装opencv


# 讲训练好的模型通过jit进行转换/ 测试单张图片
def test2():
    #读取一张图片,并转换成[1,3,224,224]的float张量并归一化
    image = cv2.imread("E:/test/0/10.png")
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    resized_image = cv2.resize(gray_image, (28, 28))
    # image = cv2.resize(image,(224,224))
    input_tensor = torch.tensor(resized_image).unsqueeze(0).unsqueeze(0).float() / 255.0
    # input_tensor = torch.tensor(image).permute(2,0,1).unsqueeze(0).float()/225.0

    # model = resnet101(pretrained=True)
    model = Net()
    model.load_state_dict(torch.load("D:\proj\python\dl_demo\mnist_cnn.pt"))
    model.eval()
    #查看模型预测该付图的结果
    output = model(input_tensor)
    output = F.softmax(output,1)
    print("模型预测结果为第{}类,置信度为{}".format(torch.argmax(output),output.max()))

    #生成pt模型,按照官网来即可
    model=model.to(torch.device("cpu"))
    model.eval()
    var=torch.ones((1,1,28,28))
    traced_script_module = torch.jit.trace(model, var)
    traced_script_module.save("testModel.pt")

if __name__ == '__main__':
    # main()
    test2()





QT创建 用软件调用模型

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <qDebug>

#undef slots
#include <torch/script.h>
#include<torch/torch.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#define slots Q_SLOTS
#include <QFileDialog>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Assuming your pushButton is named pushButton
    bool test = connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::slt_pushButton_clicked);
    bool test2 = connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::slt_pushButton_2_clicked);
	//定义使用cuda
	auto device = torch::Device(torch::kCUDA, 0);
    auto model = torch::jit::load("D:/proj/cpp/deploy_qt_pytorch/testModel.pt");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slt_pushButton_clicked()
{
    filePath = QFileDialog::getOpenFileName(this,
        tr("Open Image"), QDir::currentPath(), tr("Images (*.png *.jpg *.bmp)"));
    if (!filePath.isEmpty()) {
        cv::Mat image = cv::imread(filePath.toStdString());
        if (!image.empty()) {
            cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
            cv::resize(image, image, cv::Size(28, 28));
            QImage qImage(image.data, image.cols, image.rows, static_cast<int>(image.step), QImage::Format_Grayscale8);
            ui->label_4->setPixmap(QPixmap::fromImage(qImage));
            ui->label_4->setScaledContents(true);
        }
        else {
            qDebug() << "Error loading image!";
        }
    }
}

void MainWindow::slt_pushButton_2_clicked()
{
    if (!filePath.isEmpty()) {
        cv::Mat image = cv::imread(filePath.toStdString());
        if (!image.empty()) {
            cv::cvtColor(image, image, cv::COLOR_BGR2GRAY); // 单通道图像一定要做灰度变换
            cv::resize(image, image, cv::Size(28, 28));
            // 单通道
            auto input_tensor = torch::from_blob(image.data, { image.rows, image.cols }, torch::kByte).unsqueeze(0).unsqueeze(0).to(torch::kFloat32) / 225.0;
            // RGB
            //auto input_tensor = torch::from_blob(image.data, { image.rows, image.cols, 3 }, torch::kByte).permute({ 2, 0, 1 }).unsqueeze(0).to(torch::kFloat32) / 225.0;
            auto model = torch::jit::load("D:/proj/cpp/deploy_qt_pytorch/testModel.pt");
            model.to(torch::Device(torch::kCUDA, 0));
            model.eval();
            //前向传播
            auto output = model.forward({ input_tensor.to(torch::Device(torch::kCUDA, 0)) }).toTensor();
            output = torch::softmax(output, 1);

            argmax_value = torch::argmax(output).item<int>();
            max_value = output.max().item<float>();
            ui->label->setText(QString("Result: %1").arg(argmax_value));
            ui->label_3->setText(QString("Ratio: %1").arg(max_value));
            //qDebug() << "label" << argmax_value;
            //qDebug() << "value" << max_value;

        }
        else {
            qDebug() << "Error loading image!";
        }
    }
}


软件打包

在这里插入图片描述

软件最终运行结果

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值