【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理

【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理

  • 项目背景
  • 项目实现
    • 推理过程
    • 训练过程
  • 项目展望
  • 写在最后
  • 项目下载链接

本文为原创文章,若需要转载,请注明出处。
原文地址:https://blog.csdn.net/qq_30270773/article/details/145169580
项目对应的Github地址:https://github.com/IntptrMax/YoloSharp
项目打包的Nuget地址:https://www.nuget.org/packages/IntptrMax.YoloSharp
C#深度学习之路专栏地址:https://blog.csdn.net/qq_30270773/category_12829217.html
关注我的Github,可以获取更多资料,请为你感兴趣的项目送上一颗小星星:https://github.com/IntptrMax

另外本人已经在多平台上发现了不做任何修改直接照抄就发布我的文章的盗版行为,还将我的开源免费资源当成付费资源发布的行为,对此表示强烈的不满。这种“盗窃知识”的行为严重损害了开源项目作者的个人利益以及开源共享精神。

项目背景

本人已经在Github及CSDN上连续发布了Yolov5,Yolov8,Yolov11模型的Predict方法的训练及推理的源码及实现方法介绍,这些项目成功实现了Yolo模型在C#平台上的训练,并且已经在Nuget中进行了打包。项目发布后一些小伙伴在问是否可以实现Segment方法,故进行了进一步的开发,本文就是对Segment的实现。
如果该资料对你有帮助,请在我的Github上送我一颗小星星。该项目的Github链接为https://github.com/IntptrMax/YoloSharp

项目实现

对于单独的Yolov5、Yolov8、Yolov11 Predict方法的实现原理及代码,请参考C#深度学习之路专栏内的相关文章。

Segment方法是在Predict方法上进行了进一步的开发。在Yolo模型上,仅为Segment层代替Predict层,而且Segment是继承自Predict的,加入了cv4这个模块,对Mask的计算。
详细代码如下:

推理过程

public class Segment : YolovDetect
{private readonly int nm;private readonly int npr;private readonly Proto proto;private readonly int c4;private readonly ModuleList<Sequential> cv4 = new ModuleList<Sequential>();public Segment(int[] ch, int nc = 80, int nm = 32, int npr = 256, bool legacy = false) : base(nc, ch, legacy){this.nm = nm; // number of masksthis.npr = npr;  // number of protosthis.proto = new Proto(ch[0], this.npr, this.nm);  // protosc4 = Math.Max(ch[0] / 4, this.nm);foreach (int x in ch){cv4.append(Sequential(new Conv(x, c4, 3), new Conv(c4, c4, 3), nn.Conv2d(c4, this.nm, 1)));}//RegisterComponents();}public override Tensor[] forward(Tensor[] x){Tensor p = this.proto.forward(x[0]); // mask protoslong bs = p.shape[0]; //batch sizevar mc = torch.cat(this.cv4.Select((module, i) => module.forward(x[i]).view(bs, this.nm, -1)).ToArray(), dim: 2); // mask coefficients				x = base.forward(x);x = base.forward(x);if (this.training){x = (x.Append(mc).Append(p)).ToArray();return x;}else{return [torch.cat([x[0], mc], dim: 1), x[1], x[2], x[3], p];}}
}

经过Segment层的计算,得到了与Predict后相同的输出,并且额外得到了一组与Predict对应,且形状为[160,160]的Mask张量。这组张量里保存Mask的信息,按尺寸和比例进行缩放,即为原始图像中对应的分割区域。

训练过程

Segment下的训练与Predict方法下的训练相似,不过需要对Mask进行额外处理。
这里有一个精巧的构思,为了在一个Mask(形状为[160,160])里容纳所有Label对应的掩码,在有Mask的区域使用label的index+1的值表示。其余0的区域表示没有Mask。处理图像本体、label、mask的具体代码如下:

public (Tensor, Tensor, Tensor) GetLetterBoxSegmentData(long index)
{using var _ = NewDisposeScope();int maskSize = 160;Tensor orgImageTensor = torchvision.io.read_image(imageFiles[(int)index], torchvision.io.ImageReadMode.RGB);int originalWidth = (int)orgImageTensor.shape[2];int originalHeight = (int)orgImageTensor.shape[1];float scale = Math.Min((float)imageSize / originalWidth, (float)imageSize / originalHeight);int padWidth = imageSize - (int)(scale * originalWidth);int padHeight = imageSize - (int)(scale * originalHeight);float maskWidthScale = scale * originalWidth / imageSize;float maskHeightScale = scale * originalHeight / imageSize;Tensor imgTensor = torchvision.transforms.functional.resize(orgImageTensor, (int)(originalHeight * scale), (int)(originalWidth * scale));imgTensor = torch.nn.functional.pad(imgTensor, [0, padWidth, 0, padHeight], PaddingModes.Zeros);Tensor outputImg = torch.zeros([3, imageSize, imageSize]);outputImg[TensorIndex.Colon, ..(int)imgTensor.shape[1], ..(int)imgTensor.shape[2]] = imgTensor;string labelName = GetLabelFileNameFromImageName(imageFiles[(int)index]);string[] lines = File.ReadAllLines(labelName);float[,] labelArray = new float[lines.Length, 5];Tensor mask = torch.zeros([maskSize, maskSize]);for (int i = 0; i < lines.Length; i++){string[] datas = lines[i].Split(' ');labelArray[i, 0] = float.Parse(datas[0]);List<PointF> points = new List<PointF>();for (int j = 1; j < datas.Length; j = j + 2){points.Add(new PointF(float.Parse(datas[j]) * scale * originalWidth * maskSize / imageSize, float.Parse(datas[j + 1]) * scale * originalHeight * maskSize / imageSize));}float maxX = points.Max(p => p.X) / maskSize;float maxY = points.Max(p => p.Y) / maskSize;float minX = points.Min(p => p.X) / maskSize;float minY = points.Min(p => p.Y) / maskSize;float width = maxX - minX;float height = maxY - minY;labelArray[i, 1] = minX + width / 2;labelArray[i, 2] = minY + height / 2;labelArray[i, 3] = width;labelArray[i, 4] = height;Bitmap bitmap = new Bitmap(maskSize, maskSize);Brush brush = new SolidBrush(Color.White);Graphics g = Graphics.FromImage(bitmap);g.FillClosedCurve(brush, points.ToArray());g.Save();Tensor msk = Lib.GetTensorFromBitmap(bitmap);msk = msk[0] > 0;mask[msk] = i + 1;}Tensor labelTensor = tensor(labelArray);long p = imgTensor.shape[0];return (imgTensor.MoveToOuterDisposeScope(), labelTensor.MoveToOuterDisposeScope(), mask.MoveToOuterDisposeScope());
}

另外Loss的计算也加入了Mask部分,此处不再仔细讲解。

项目效果如下
请添加图片描述

项目展望

目前已经实现了Yolov8、Yolov11 Segment方法的训练和推理,并且已经可以成功加载官方的预训练模型进行,或作为训练的基础权重。
接下来还有Pose和Obb方法,过段时间估计会有新的进展。

写在最后

使用C#深度学习项目是很多人所希望的。不过在该方向上资料很少,开发难度大。常规使用C#进行深度学习项目的方法为使用Python训练,转为Onnx模型再用C#调用。
目前我希望能够改变这一现象,希望能用纯C#平台进行训练和推理。这条路还很长,也很困难,希望有兴趣的读者能跟我一起让让C#的深度学习开发环境更为完善,以此能帮助到更多的人。

另外随着项目的关注度增多,已经开始有人盗版我的项目并将免费开源的项目当成付费项目在卖了。这种行为极其恶劣,请各位小伙伴积极抵制这种行为,还开源项目一片干净的环境,也让开源项目开发者有动力继续贡献更多的项目。

我在Github上已经将完整的代码发布了,项目地址为:https://github.com/IntptrMax/YoloSharp,期待你能在Github上送我一颗小星星。在我的Github里还GGMLSharp这个项目,这个项目也是C#平台下深度学习的开发包,希望能得到你的支持。

项目下载链接

https://download.csdn.net/download/qq_30270773/89969923

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2675.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】制造业转型:机器学习如何推动工业 4.0 的深度发展

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 引言 在当今科技飞速发展的时代&#xff0c;制造业正经历着前所未有的变革&#xff0c;工业4.0的浪潮席卷而来。工业4.0旨在通过将…

半导体数据分析: 玩转WM-811K Wafermap 数据集(三) AI 机器学习

前面我们已经通过两篇文章&#xff0c;一起熟悉了WM-811K Wafermap 数据集&#xff0c;并对其中的一些数据进行了调用&#xff0c;生成了一些统计信息和图片。今天我们接着继续往前走。 半导体数据分析&#xff1a; 玩转WM-811K Wafermap 数据集&#xff08;二&#xff09; AI…

ClickHouse-CPU、内存参数设置

常见配置 1. CPU资源 1、clickhouse服务端的配置在config.xml文件中 config.xml文件是服务端的配置&#xff0c;在config.xml文件中指向users.xml文件&#xff0c;相关的配置信息实际是在users.xml文件中的。大部分的配置信息在users.xml文件中&#xff0c;如果在users.xml文…

Elasticsearch:Jira 连接器教程第一部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 将我们的 Jira 内容索引到 Elaasticsearch 中以创建统一的数据源并使用文档级别安全性进行搜索。 在本文中&#xff0c;我们将回顾 Elastic Jira 原生连接器的一个用例。我们将使用一个模拟项目&#xff0c;其中一家银行正在开发…

Linux自学指南(学习路线大纲)

Linux入门与进阶指南 目录 第一部分 入门篇 第一章 Linux 系统 1.1 Unix&#xff1a;Linux的“祖师爷” 1.2 Linux 操作系统的诞生与发展历程 1.3 Linux 主要应用领域的归纳 1.4 开源社区的兴起 第二章 如何选择Linux发行版&#xff1f; 2.1 Debian GNU/Linux 2.2 Ubu…

CCLINKIE转ModbusTCP网关,助机器人“掀起”工业智能的“惊涛骇浪”

以下是一个稳联技术CCLINKIE转ModbusTCP网关&#xff08;WL-CCL-MTCP&#xff09;连接三菱PLC与机器人的配置案例&#xff1a;设备与软件准备设备&#xff1a;稳联技术WL-CCL-MTCP网关、三菱FX5UPLC、支持ModbusTCP协议的机器人、网线等。 稳联技术ModbusTCP转CCLINKIE网关&…

c#删除文件和目录到回收站

之前在c上遇到过这个问题&#xff0c;折腾许久才解决了&#xff0c;这次在c#上再次遇到这个问题&#xff0c;不过似乎容易了一些&#xff0c;亲测代码如下&#xff0c;两种删除方式都写在代码中了。 直接上完整代码&#xff1a; using Microsoft.VisualBasic.FileIO; using Sy…

windows远程桌面连接限定ip

1&#xff0c;Windows防火墙->高级设置->远程桌面 - 用户模式(TCP-In)->作用域->远程IP地址 2&#xff0c;启用规则

Linux 下配置 Golang 环境

go sdk 下载环境&#xff1a;https://golang.google.cn/dl/选择对应的版本&#xff1a; 使用 wget 直接拉包下载到服务器中 wget https://golang.google.cn/dl/go1.23.4.linux-amd64.tar.gz如果找不到 wget 命令&#xff0c;yum 下载 wget yum -y install wget配置 go 的环境…

打造更安全的Linux系统:玩转PAM配置文件

在Linux系统中&#xff0c;用户认证是确保系统安全的关键步骤。PAM&#xff08;可插拔认证模块&#xff09;为我们提供了一个非常灵活的框架&#xff0c;帮助我们管理各种服务的认证过程。其中&#xff0c;/etc/pam.d目录是PAM配置的核心部分&#xff0c;这里存放了每个服务所需…

LLM - 大模型 ScallingLaws 的 Causal/Masked (PLM) 目标系数差异 教程(2)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145188660 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…

【docker踩坑记录】

docker踩坑记录 踩坑记录(持续更新中.......)docker images 权限问题 踩坑记录(持续更新中…) docker images 权限问题 permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.s…

本地部署Web-Check网站检测与分析利器并实现远程访问实时监测

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本文我们将详细介绍如何在Ubuntu系统上使用Docker部署Web-Check&#xf…

森林网络部署,工业4G路由器实现林区组网远程监控

在广袤无垠的林区&#xff0c;每一片树叶的摇曳、每一丝空气的流动&#xff0c;都关乎着生态的平衡与安宁。林区监控正以强大的力量&#xff0c;为这片绿色家园筑起一道坚固的防线。 工业 4G 路由器作为林区监控组网的守护者&#xff0c;凭借着卓越的通讯性能&#xff0c;突破…

Django框架:python web开发

1.环境搭建&#xff1a; &#xff08;a&#xff09;开发环境&#xff1a;pycharm &#xff08;b&#xff09;虚拟环境&#xff08;可有可无&#xff0c;优点&#xff1a;使用虚拟环境可以把使用的包自动生成一个文件&#xff0c;其他人需要使用时可以直接选择导入包&#xff…

vmware虚拟机配置ubuntu 18.04(20.04)静态IP地址

VMware版本 &#xff1a;VMware Workstation 17 Pro ubuntu版本&#xff1a;ubuntu-18.04.4-desktop-amd64 主机环境 win11 1. 修改 VMware虚拟网络编辑器 打开vmware&#xff0c;点击顶部的“编辑"菜单&#xff0c;打开 ”虚拟化网络编辑器“ 。 选择更改设置&#…

【Unity】unity3D 调用LoadSceneAsync 场景切换后比较暗 部门材质丢失

解决方法&#xff1a;两个场景使用同样灯光 现象 直接进入第二个场景是可以正常显示 调用LoadSceneAsync来切换后&#xff0c;第二个场景出现比较暗的情况 解决方法&#xff1a;两个场景使用同样灯光&#xff0c;在loading 的场景中加入灯光。 Light—Directional Light 如果…

R5天气识别学习笔记

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 LSTM-天气识别预测 雨天百分比数据预处理模型训练结果可视化个人总结 import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyp…

SpringMVC (1)

目录 1. 什么是Spring Web MVC 1.1 MVC的定义 1.2 什么是Spring MVC 1.3 Spring Boot 1.3.1 创建一个Spring Boot项目 1.3.2 Spring Boot和Spring MVC之间的关系 2. 学习Spring MVC 2.1 SpringBoot 启动类 2.2 建立连接 1. 什么是Spring Web MVC 1.1 MVC的定义 MVC 是…

【混合开发】CefSharp+Vue 解决Cookie问题

问题表现 使用Element-admin架构搭建Vue前端项目&#xff0c;在与CefSharp搭配时&#xff0c;出现无法使用cookie的问题。 无法将token存入cookiecookie无法被读取 如下图&#xff0c;Cookies下显示file://。 正常的Cookies显示&#xff0c;Cookies显示为http://域名&#x…