使用Python脚本转换YOLOv5配置文件到https://github.com/ultralytics/ultralytics:一个详细的指南

news2025/2/24 22:23:41

在深度学习领域,YOLO(You Only Look Once)系列模型因其高效和准确性而广受欢迎。然而,随着项目需求的变化,有时我们需要对预训练模型的配置文件进行调整。本文将详细介绍如何使用Python脚本自动转换YOLOv5的配置文件到https://github.com/ultralytics/ultralytics,并解释每个步骤的目的和实现方法。

准备工作

首先,确保安装了必要的库:

pip install pyyaml

代码详解

定义格式化和过滤函数

def format_and_filter_list(lst):
    formatted_items = []
    for item in lst:
        if isinstance(item, list):
            processed_item = format_and_filter_list(item)
            if processed_item:  # 只添加非空列表
                formatted_items.append(processed_item)
        elif isinstance(item, str):
            if item == 'nearest':
                formatted_items.append(f"'{item}'")
            elif item != 'anchors':  # 过滤掉 'anchors'
                formatted_items.append(item)
        else:
            formatted_items.append(str(item))
    return f"[{', '.join(formatted_items)}]"

定义转换配置函数

def transform_config(original_config):
    transformed = {
        'nc': original_config['nc'],  # number of classes
        'scales': {
            'n': [original_config['depth_multiple'], original_config['width_multiple'], 1024]
        },
        'backbone': [],
        'head': []
    }

    # Transform backbone
    for layer in original_config['backbone']:
        if not isinstance(layer, list):
            layer = [layer]
        transformed['backbone'].append(layer)

    # Adjust the head to match the desired format, also updating nc and anchors usage
    for i, layer in enumerate(original_config['head']):
        if not isinstance(layer, list):
            layer = [layer]

        if isinstance(layer[0], list) and len(layer[0]) > 3 and layer[0][3] == 'Detect':
            layer[0][3] = ['nc', 'anchors']
            transformed['head'].append([layer[0]])
        else:
            transformed['head'].append(layer)

    # Special case: update the final Detect layer configuration
    if transformed['head'] and isinstance(transformed['head'][-1], list) and transformed['head'][-1]:
        last_layer = transformed['head'][-1]
        if isinstance(last_layer[0], list) and len(last_layer[0]) > 3:
            last_layer[0][3] = ['nc']

    return transformed

定义主函数以更改YAML文件


def change_yaml(yolov5_config):
    # Check if input file exists
    if not os.path.exists(yolov5_config):
        print(f"Error: Input file '{yolov5_config}' does not exist.")
    else:
        old_path = os.path.dirname(yolov5_config)
        save_path = os.path.dirname(old_path)
        new_yaml_name_path = os.path.join(save_path, "yolov5_" + os.path.basename(yolov5_config))
        # Load your YAML file
        with open(yolov5_config, 'r') as file:
            try:
                original_config = yaml.safe_load(file)
            except yaml.YAMLError as exc:
                print(f"Error: Failed to parse YAML file. {exc}")
                exit(1)

        transformed_config = transform_config(original_config)

        # Ensure that each element in backbone and head is a list
        def ensure_list_format(config_part):
            new_config_part = []
            for item in config_part:
                if not isinstance(item, list):
                    item = [item]
                new_config_part.append(item)
            return new_config_part

        transformed_config['backbone'] = ensure_list_format(transformed_config['backbone'])
        transformed_config['head'] = ensure_list_format(transformed_config['head'])

        # Generate the formatted YAML content
        formatted_yaml_content = f"""# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# Ultralytics YOLOv5 object detection model with P3/8 - P5/32 outputs
# Model docs: https://docs.ultralytics.com/models/yolov5
# Task docs: https://docs.ultralytics.com/tasks/detect

# Parameters
nc: {transformed_config['nc']} # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov5n.yaml' will call yolov5.yaml with scale 'n'
  # [depth, width, max_channels]
  n: {transformed_config['scales']['n']}
# YOLOv5 v6.0 backbone
backbone:
"""

    for layer in transformed_config['backbone']:
        layer = format_and_filter_list(layer)
        print(layer)
        formatted_yaml_content += f"  - {layer}\n"

    formatted_yaml_content += """
# YOLOv5 v6.0 head with (P2, P3, P4, P5) outputs
head:
"""

    for layer in transformed_config['head']:

        print(layer)
        if isinstance(layer, list) and layer[2] == 'Conv':
            formatted_yaml_content += '\n'

        layer = format_and_filter_list(layer)
        print(layer)
        formatted_yaml_content += f"  - {layer}\n"

    # Save the transformed configuration to a new YAML file
    with open(new_yaml_name_path, 'w') as file:
        file.write(formatted_yaml_content)

    print(f"Configuration has been transformed and saved to '{new_yaml_name_path}'.")

批量处理多个配置文件

input_path = "/media/lindsay/data/ultralytics-main/ultralytics/cfg/models/v5/yolov5"
input_path_list = [os.path.join(input_path, i) for i in os.listdir(input_path)]
for i in input_path_list:
    change_yaml(i)

总结

通过上述步骤,您可以轻松地将YOLOv5的配置文件转换为ultralytics-yolov8所需的格式,并且可以批量处理多个配置文件。这个脚本不仅可以帮助您节省时间,还能减少手动操作带来的错误。希望这篇博客能为您提供有价值的指导,让您更高效地管理深度学习项目的配置文件。

完整代码

import yaml
import os

# 函数用于格式化列表为所需形式
def format_and_filter_list(lst):
    formatted_items = []
    for item in lst:
        if isinstance(item, list):
            # 如果是列表类型,则递归调用此函数进行格式化和过滤
            processed_item = format_and_filter_list(item)
            if processed_item:  # 只添加非空列表
                formatted_items.append(processed_item)
        elif isinstance(item, str):
            # 特殊处理需要保留引号的字符串
            if item == 'nearest':
                formatted_items.append(f"'{item}'")
            elif item != 'anchors':  # 过滤掉 'anchors'
                formatted_items.append(item)
        else:
            # 其他类型直接转换成字符串表示
            formatted_items.append(str(item))

    # 返回格式化后的列表字符串表示
    return f"[{', '.join(formatted_items)}]"


def transform_config(original_config):
    transformed = {
        'nc': original_config['nc'],  # number of classes
        'scales': {
            'n': [original_config['depth_multiple'], original_config['width_multiple'], 1024]
        },
        'backbone': [],
        'head': []
    }

    # Transform backbone
    for layer in original_config['backbone']:
        if not isinstance(layer, list):
            layer = [layer]
        transformed['backbone'].append(layer)

    # Adjust the head to match the desired format, also updating nc and anchors usage
    for i, layer in enumerate(original_config['head']):
        if not isinstance(layer, list):
            layer = [layer]

        if isinstance(layer[0], list) and len(layer[0]) > 3 and layer[0][3] == 'Detect':
            # Update Detect layer to use 'nc' instead of specific numbers for classes
            layer[0][3] = ['nc', 'anchors']
            transformed['head'].append([layer[0]])
        else:
            transformed['head'].append(layer)

    # Special case: update the final Detect layer configuration
    if transformed['head'] and isinstance(transformed['head'][-1], list) and transformed['head'][-1]:
        last_layer = transformed['head'][-1]
        if isinstance(last_layer[0], list) and len(last_layer[0]) > 3:
            last_layer[0][3] = ['nc']

    return transformed


def change_yaml(yolov5_config):
    # Check if input file exists
    if not os.path.exists(yolov5_config):
        print(f"Error: Input file '{yolov5_config}' does not exist.")
    else:
        old_path = os.path.dirname(yolov5_config)
        save_path = os.path.dirname(old_path)
        new_yaml_name_path = os.path.join(save_path, "yolov5_" + os.path.basename(yolov5_config))
        # Load your YAML file
        with open(yolov5_config, 'r') as file:
            try:
                original_config = yaml.safe_load(file)
            except yaml.YAMLError as exc:
                print(f"Error: Failed to parse YAML file. {exc}")
                exit(1)

        transformed_config = transform_config(original_config)

        # Ensure that each element in backbone and head is a list
        def ensure_list_format(config_part):
            new_config_part = []
            for item in config_part:
                if not isinstance(item, list):
                    item = [item]
                new_config_part.append(item)
            return new_config_part

        transformed_config['backbone'] = ensure_list_format(transformed_config['backbone'])
        transformed_config['head'] = ensure_list_format(transformed_config['head'])

        # Generate the formatted YAML content
        formatted_yaml_content = f"""# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# Ultralytics YOLOv5 object detection model with P3/8 - P5/32 outputs
# Model docs: https://docs.ultralytics.com/models/yolov5
# Task docs: https://docs.ultralytics.com/tasks/detect

# Parameters
nc: {transformed_config['nc']} # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov5n.yaml' will call yolov5.yaml with scale 'n'
  # [depth, width, max_channels]
  n: {transformed_config['scales']['n']}
# YOLOv5 v6.0 backbone
backbone:
"""

    for layer in transformed_config['backbone']:
        layer = format_and_filter_list(layer)
        print(layer)
        formatted_yaml_content += f"  - {layer}\n"

    formatted_yaml_content += """
# YOLOv5 v6.0 head with (P2, P3, P4, P5) outputs
head:
"""

    for layer in transformed_config['head']:

        print(layer)
        if isinstance(layer, list) and layer[2] == 'Conv':
            formatted_yaml_content += '\n'

        layer = format_and_filter_list(layer)
        print(layer)
        formatted_yaml_content += f"  - {layer}\n"

    # Save the transformed configuration to a new YAML file
    with open(new_yaml_name_path, 'w') as file:
        file.write(formatted_yaml_content)

    print(f"Configuration has been transformed and saved to '{new_yaml_name_path}'.")


input_path = "/media/lindsay/data/ultralytics-main/ultralytics/cfg/models/v5/yolov5"
input_path_list = [os.path.join(input_path, i) for i in os.listdir(input_path)]
for i in input_path_list:
    change_yaml(i)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制造行业CRM选哪家?中大型企业CRM选型方案

在当今竞争激烈的制造行业中,企业对于客户关系管理(CRM)系统的需求日益增强,高效、智能的CRM系统已成为推动企业业务增长、优化客户体验的关键。在制造业 CRM 市场中,纷享销客和销售易都备受关注,且各自有着…

R 语言科研绘图 --- 散点图-汇总

在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…

从零开始的网站搭建(以照片/文本/视频信息通信网站为例)

本文面向已经有一些编程基础(会至少一门编程语言,比如python),但是没有搭建过web应用的人群,会写得尽量细致。重点介绍流程和部署云端的步骤,具体javascript代码怎么写之类的,这里不会涉及。 搭…

Elasticsearch Open Inference API 增加了对 Jina AI 嵌入和 Rerank 模型的支持

作者:Hemant Malik 及 Joan Fontanals Martnez 探索如何使用 Elasticsearch Open Inference API 访问 Jina AI 模型。 我们在 Jina AI 的朋友们将 Jina AI 的嵌入模型和重新排名产品的原生集成添加到 Elasticsearch 开放推理 API 中。这包括对行业领先的多语言文本嵌…

Unity学习part4

1、ui界面的基础使用 ui可以在2d和矩形工具界面下操作,更方便,画布与游戏窗口的比例一般默认相同 如图所示,图片在画布上显示的位置和在游戏窗口上显示的位置是相同的 渲染模式:屏幕空间--覆盖,指画布覆盖在游戏物体渲…

进程概念、PCB及进程查看

文章目录 一.进程的概念进程控制块(PCB) 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序,而程序是存放在磁盘的,cpu要想执行程序的指…

php session数据存储位置选择

PHP session 数据的存储位置可以通过配置文件或者代码来进行设置。默认情况下,session 数据是存储在服务器的文件系统中的。你可以将 session 数据存储在其他地方,例如数据库、缓存等。 基础概念 PHP session默认情况下将数据存储在服务器端的临时文件中…

计算机网络————(一)HTTP讲解

基础内容分类 从TCP/IP协议栈为依托,由上至下、从应用层到基础设施介绍协议。 1.应用层: HTTP/1.1 Websocket HTTP/2.0 2.应用层的安全基础设施 LTS/SSL 3.传输层 TCP 4.网络层及数据链路层 IP层和以太网 HTTP协议 网络页面形成基本 流程&#xff1a…

【Viewer.js】vue3封装图片查看器

效果图 需求 点击图片放大可关闭放大的 图片 下载 cnpm in viewerjs状态管理方法 stores/imgSeeStore.js import { defineStore } from pinia export const imgSeeStore defineStore(imgSeeStore, {state: () > ({showImgSee: false,ImgUrl: ,}),getters: {},actions: {…

数据结构之二叉树的定义及实现

1. 树的概念 主要的定义: 节点的度:一个节点含有的子树的个数称为该节点的度;如上图:A的为6 叶节点或终端节点:度为0的节点称为叶节点;如上图:B,C,H,I等节点…

Rust语言基础知识详解【一】

1.在windows上安装Rust Windows 上安装 Rust 需要有 C 环境,以下为安装的两种方式: 1. x86_64-pc-windows-msvc(官方推荐) 先安装 Microsoft C Build Tools,勾选安装 C 环境即可。安装时可自行修改缓存路径与安装路…

SQLMesh 系列教程9- 宏变量及内置宏变量

SQLMesh 的宏变量是一个强大的工具,能够显著提高 SQL 模型的动态化能力和可维护性。通过合理使用宏变量,可以实现动态时间范围、多环境配置、参数化查询等功能,从而简化数据模型的开发和维护流程。随着数据团队的规模扩大和业务复杂度的增加&…

【Deepseek】Linux 本地部署 Deepseek

前言 本文介绍在 Linux 系统上部署 Deepseek AI。本文教程是面向所有想体验 AI 玩家的一个简易教程,因此即使是小白也可以轻松完成体验,话不多说立马着手去干。 [注]:笔者使用的系统为 Ubuntu 24.10 1. 关于 ollama Ollama 是一款开源应用…

git,bash - 从一个远端git库只下载一个文件的方法

文章目录 git,bash - 从一个远端git库只下载一个文件的方法概述笔记写一个bash脚本来自动下载get_github_raw_file_from_url.shreanme_file.shfind_key_value.sh执行命令 END git,bash - 从一个远端git库只下载一个文件的方法 概述 github上有很多大佬上传了电子书库&#xf…

臻识相机,华夏相机,芊熠车牌识别相机加密解密

臻识,华夏,芊熠这三种车牌识别相机解密我都试过了,可以正常解密成功,其它品牌我暂时没有测试。超级简单,免费的,白嫖无敌! 流程: ①:先导出配置文件,例如我以…

网络安全与措施

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 # 网络安全问题概述 1) 数据安全 访问(授权访问);存储(容灾、备份或异地备份等) 2) 应用程序 不能…

前后端分离系统架构:基于Spring Boot的最佳实践

前后端分离系统架构图描绘了一个基于Springboot的前端后台分离的系统架构。它强调了前端(客户端)与远程(服务器)的解耦,通过API接口进行交互,分别独立开发和部署。 前后端分离系统架构图 从上到下&#xff…

内外网文件传输 安全、可控、便捷的跨网数据传输方案

一、背景与痛点 在内外网隔离的企业网络环境中,员工与外部协作伙伴(如钉钉用户)的文件传输面临以下挑战: 安全性风险:内外网直连可能导致病毒传播、数据泄露。 操作繁琐:传统方式需频繁切换网络环境&…

抖音试水AI分身;腾讯 AI 战略调整架构;百度旗下小度官宣接入DeepSeek...|网易数智日报

抖音试水AI分身,字节旗下AI智能体平台扣子已与抖音打通,相关功能内测中 2月19日消息,钛媒体App独家获悉,字节旗下AI智能体开发平台扣子(Coze)已与抖音打通,抖音创作者可在扣子智能体平台打造AI分…

红帽7基于kickstart搭建PXE环境

Kickstart 文件是一种配置文件,用于定义 Linux 系统安装过程中的各种参数,如分区、网络配置、软件包选择等。system-config-kickstart 提供了一个图形界面,方便用户快速生成这些配置文件。 用户可以通过图形界面进行系统安装的详细配置&…