首页 > 其他分享 >深度学习(Lenet网络)

深度学习(Lenet网络)

时间:2023-08-19 10:33:21浏览次数:52  
标签:__ labels nn self torch 网络 Lenet 深度 image

业余时间重新学习一下深度学习,先从基础网络开始,一点一点积累。

Lenet网络模型:

下面程序中输入的数据是28*28的,结构和原始稍微有点不一样。

训练代码:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import ToTensor
from PIL import Image

# 自定义LeNet模型
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.fc1 = nn.Linear(16*4*4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = torch.relu(self.conv1(x))       #28*28   -> 6*24*24
        x = torch.max_pool2d(x, 2)          #6*24*24 -> 6*12*12
        x = torch.relu(self.conv2(x))       #6*12*12 -> 16*8*8
        x = torch.max_pool2d(x, 2)          #16*8*8  -> 16*4*4
        x = x.view(x.size(0), -1)           #16*4*4  -> 256
        x = torch.relu(self.fc1(x))         #256     -> 120
        x = torch.relu(self.fc2(x))         #120     -> 84
        x = self.fc3(x)                     #84      -> 10
        return x

# 自定义数据集类
class MNISTDataset(Dataset):
    def __init__(self, image_folder, label_file, transform=None):
        self.image_folder = image_folder
        self.label_file = label_file
        self.transform = transform
        self.labels = self.load_labels()

    def load_labels(self):
        labels = []
        with open(self.label_file, 'r') as f:
            lines = f.readlines()
            for line in lines:
                label = int(line.strip())
                labels.append(label)
        return labels

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

    def __getitem__(self, index):
        label = self.labels[index]
        image_path = f"{index}.bmp"     # 假设图像的文件名是按照顺序命名的,例如0.jpg, 1.jpg, ...
        image = Image.open(self.image_folder + '/' + image_path).convert('L')
        if self.transform:
            image = self.transform(image)
        return image, label

num_epochs = 10

# 创建LeNet模型和优化器
model = LeNet()
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

# 加载数据集并进行训练
train_dataset = MNISTDataset(
    'mnist/train', 'mnist/train.txt', transform=ToTensor())
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model.to(device)

for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    correct = 0
    total = 0
    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)

        # 前向传播
        outputs = model(images)
        loss = criterion(outputs, labels)

        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

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

    print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}, Accuracy: {(100 * correct / total):.2f}%")

print('Training finished.')

# 保存模型
torch.save(model.state_dict(), 'lenet_mnist.pth')

测试代码:

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import ToTensor
from PIL import Image

# 自定义LeNet模型
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.fc1 = nn.Linear(16*4*4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = torch.relu(self.conv1(x))
        x = torch.max_pool2d(x, 2)
        x = torch.relu(self.conv2(x))
        x = torch.max_pool2d(x, 2)
        x = x.view(x.size(0), -1)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 自定义数据集类
class MNISTDataset(Dataset):
    def __init__(self, image_folder, label_file, transform=None):
        self.image_folder = image_folder
        self.label_file = label_file
        self.transform = transform
        self.labels = self.load_labels()

    def load_labels(self):
        labels = []
        with open(self.label_file, 'r') as f:
            lines = f.readlines()
            for line in lines:
                label = int(line.strip())
                labels.append(label)
        return labels

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

    def __getitem__(self, index):
        label = self.labels[index]
        image_path = f"{index}.bmp"     # 假设图像的文件名是按照顺序命名的,例如0.jpg, 1.jpg, ...
        image = Image.open(self.image_folder + '/' + image_path).convert('L')
        if self.transform:
            image = self.transform(image)
        return image, label


# 加载模型参数
model = LeNet()
model.load_state_dict(torch.load('lenet_mnist.pth'))

# 加载测试数据集
test_dataset = MNISTDataset(
    'mnist/test', 'mnist/test.txt', transform=ToTensor())
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

model.eval()

correct = 0
total = 0

with torch.no_grad():
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)

        # 前向传播
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)

        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f"Test Accuracy: {(100 * correct / total):.2f}%")

将pth模型转为onnx模型:

import torch
import torch.nn as nn

# 自定义LeNet模型
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.fc1 = nn.Linear(16*4*4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = torch.relu(self.conv1(x))
        x = torch.max_pool2d(x, 2)
        x = torch.relu(self.conv2(x))
        x = torch.max_pool2d(x, 2)
        x = x.view(x.size(0), -1)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x


# 加载模型参数
model = LeNet()
model.load_state_dict(torch.load('lenet_mnist.pth'))
model.eval()

# 创建一个虚拟的输入张量
dummy_input = torch.randn(1, 1, 28, 28)  # 假设输入图像尺寸为28*28

# 导出模型为ONNX格式
onnx_filename = 'lenet_mnist.onnx'

torch.onnx.export(model, dummy_input, onnx_filename, verbose=False,input_names=["image"],output_names=["class"])

print(f"Model successfully exported as {onnx_filename}.")

安装netron可以查看onnx模型。

下面利用c++做测试:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <onnxruntime_cxx_api.h>

std::vector<float> ApplyTransform(const cv::Mat& image)
{
    cv::Mat resized, floatImage;
    image.convertTo(floatImage, CV_32FC1);
    float mean = 0.0f;
    float std = 0.0f;
    cv::Scalar meanScalar, stdScalar;
    meanStdDev(floatImage, meanScalar, stdScalar);
    mean = static_cast<float>(meanScalar.val[0]);
    std = static_cast<float>(stdScalar.val[0]);

    std::vector<float> imgData;
    for (int h = 0; h < image.rows; h++)
    {
        for (int w = 0; w < image.cols; w++)
        {
            imgData.push_back((floatImage.at<float>(h, w) - mean) / std);
        }
    }
    return imgData;
}

int main()
{
    // 读取图像
    cv::Mat image = cv::imread("4.bmp", cv::IMREAD_GRAYSCALE);
    if (image.empty()) {
        std::cerr << "Failed to read image." << std::endl;
        return 1;
    }

    cv::Mat resized_image;
    cv::resize(image, resized_image, cv::Size(28, 28));
    std::vector<float> imgData = ApplyTransform(resized_image);
    // 加载ONNX模型
    Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "ONNXModel");
    Ort::SessionOptions session_options;
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);

    std::wstring onnx_model_path = L"lenet_mnist.onnx";
    Ort::Session session(env, onnx_model_path.c_str(), session_options);

    std::vector<int64_t> inputShape{ 1, 1, resized_image.rows, resized_image.cols };
    Ort::MemoryInfo memoryInfo =  Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
    Ort::Value inputTensor = Ort::Value::CreateTensor<float>(memoryInfo, imgData.data(), imgData.size(), inputShape.data(), inputShape.size());

    const char* input_names[] = { "image" };
    const char* output_names[] = { "class" };
    Ort::RunOptions run_options;
    std::vector<Ort::Value> outputs = session.Run(run_options, input_names, &inputTensor, 1, output_names, 1);

    std::vector<int64_t> kpshape = outputs[0].GetTensorTypeAndShapeInfo().GetShape();
    float* kp = outputs[0].GetTensorMutableData<float>();

    std::cout << kpshape[0]<<"  "<<kpshape[1] << std::endl;

    for (int i = 0; i < kpshape[1]; i++)
    {
        std::cout << kp[i] << std::endl;
    }

    return 0;
}

测试数据下载地址:https://pan.baidu.com/s/1lrOfLyYbz94C9IoFv0hmGQ

标签:__,labels,nn,self,torch,网络,Lenet,深度,image
From: https://www.cnblogs.com/tiandsp/p/17612706.html

相关文章

  • 网络流专项
    飞行员配对方案问题二分图最大匹配模板,最大流即可.负载平衡问题显然,当库存比平均数大时,这个仓库就应当向外输送货物;反之,这个仓库就应该接收货物.每一个仓库都要接收货物或输出货物,因此拆成两个点,一个输出,一个接收.当库存比平均值大时,超级源点向该点的输出......
  • 智安网络|零信任安全框架:保障数字化时代网络安全的最佳实践
    随着数字化时代的快速发展,网络安全问题变得越来越突出。传统的安全防御模式已经不再适用于现代复杂的网络环境中。为了应对日益增长的网络威胁,零信任安全模式应运而生。一、什么是零信任?零信任是一种安全框架和哲学,它基于一个简单的原则:不信任任何用户或设备,即使它们已经位于网络内......
  • 直播平台源码之实现网络请求的方法
    直播平台源码开发中如果你不会网络请求,那么你开发的应用软件就是一具没有灵魂的枯骨。当你下载完软件后会要求你给与权限,否则就没办法使用,网络请求也需要对应的权限,否则就没法进行联网操作。在直播平台源码开发中首先在AndroidManifest.xml文件中添加网络请求权限要在manifest......
  • 真知灼见|鲸图知识图谱平台,助力金融业务深度洞察(下)
    ​导语大数据时代的背景下,数据早就成为数字经济重要的生产资料。对数据的挖掘能力成为企业数字化转型的驱动力。就金融行业来说,如果经营和管理方式跟不上大数据时代的发展脚步就会使得数据价值无法得到充分发挥。知识图谱作为一个结合了知识存储、知识表示和知识推理的综合数据......
  • 深度云化时代,什么样的云网络才是企业的“心头好”?
    科技云报道原创。近年来企业上云的快速推进,对云网络提出了更多需求。最初,云网络只是满足互联网业务公网接入。随着移动互联网的发展,企业对云上网络安全隔离能力和互访能力、企业数据中心与云上网络互联、构建混合云的能力,以及在云上多地域部署业务后的多地域网络互联能力等,都推动着......
  • Java 网络编程
    网络编程1.概述地球村:你在西安,你一个美国的朋友!信件:计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。网络编程的目的:无线电台..........
  • 网络工程师,你的钱途在哪里?
    下午好,我是老杨。转眼一年又过去了,就马上就到了秋招的时间节点。哈哈,问句每年都会问的:今年,你对自己的行业环境有什么感知吗?是好了还是差了?是想跑路还是想深耕?或许答案众说纷纭,或许你的内心也躁动不安或早已躺平,但在行动之前,先看完我这篇分析。耐下心,分两点和你聊聊,最近你可能会想知......
  • 离谱,居然还有网络工程师不懂什么是Overlay网络?
    下午好,我是老杨。伴随着网络技术的发展,数据中心的二层组网结构早已出现了阶段性的架构变化。数据中心网络分为了Underlay和Overlay两个部分,网络进入了Overlay虚拟化阶段。很多小友希望能多输出一些新技术,这不,今天就给你展开说说。Overlay网络是怎么形成的?与Underlay的区别又在哪?试......
  • TedNet:一个用于张量分解网络的Pytorch工具包
    摘要张量分解网络(TensorDecompositionNetworks,TDNs)因其固有的紧凑架构而流行。为了给更多的研究人员提供一种灵活的方式来利用TDNs,我们提出了一个名为TedNet的Pytorch工具包。TedNet实现了5种张量分解(即,CANDECOMP/PARAFAC(CP)、Block-TermTucker(BTT)、Tucker-2、TensorTrain(TT)和......
  • X710网卡LACP模式下ifdown网卡后交换机侧依然处于UP状态,导致网络通信异常
    以下配置属于临时配置,重启后失效,具体建议在bios或者固件中解决。主要包含两个配置:1、使用ifdown命令关闭网卡无法使linkdown,交换机侧依然认为端口UP进行流量转发,无法正常通信2、在某些环境中,LACP可能无法正常工作,这些环境要求将包含LCAP信息的LLDP帧转发到网络堆栈。#查看网卡......