yolo-world 源码解析(六)(2)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: yolo-world 源码解析(六)

yolo-world 源码解析(六)(1)https://developer.aliyun.com/article/1484140

.\YOLO-World\yolo_world\models\layers\__init__.py

# 版权声明,版权归腾讯公司所有
# 基于 CSPLayers 的 PAFPN 的基本模块
# 导入 yolo_bricks 模块中的相关类
from .yolo_bricks import (
    CSPLayerWithTwoConv,
    MaxSigmoidAttnBlock,
    MaxSigmoidCSPLayerWithTwoConv,
    ImagePoolingAttentionModule,
    )
# 导出给外部使用的类列表
__all__ = ['CSPLayerWithTwoConv',
           'MaxSigmoidAttnBlock',
           'MaxSigmoidCSPLayerWithTwoConv',
           'ImagePoolingAttentionModule']

.\YOLO-World\yolo_world\models\losses\dynamic_loss.py

# 导入必要的库
from typing import Optional
import torch
import torch.nn as nn
from torch import Tensor
from mmdet.models.losses.mse_loss import mse_loss
from mmyolo.registry import MODELS
# 注册模型类为CoVMSELoss
@MODELS.register_module()
class CoVMSELoss(nn.Module):
    def __init__(self,
                 dim: int = 0,
                 reduction: str = 'mean',
                 loss_weight: float = 1.0,
                 eps: float = 1e-6) -> None:
        super().__init__()
        # 初始化参数
        self.dim = dim
        self.reduction = reduction
        self.loss_weight = loss_weight
        self.eps = eps
    def forward(self,
                pred: Tensor,
                weight: Optional[Tensor] = None,
                avg_factor: Optional[int] = None,
                reduction_override: Optional[str] = None) -> Tensor:
        """Forward function of loss."""
        # 确保重写的减少参数在合法范围内
        assert reduction_override in (None, 'none', 'mean', 'sum')
        # 根据重写的减少参数或者默认减少参数来确定减少方式
        reduction = (
            reduction_override if reduction_override else self.reduction)
        # 计算协方差
        cov = pred.std(self.dim) / pred.mean(self.dim).clamp(min=self.eps)
        # 创建目标张量
        target = torch.zeros_like(cov)
        # 计算损失
        loss = self.loss_weight * mse_loss(
            cov, target, weight, reduction=reduction, avg_factor=avg_factor)
        return loss

.\YOLO-World\yolo_world\models\losses\__init__.py

# 版权声明,版权归腾讯公司所有
# 导入动态损失模块中的CoVMSELoss类
from .dynamic_loss import CoVMSELoss
# 导出CoVMSELoss类,供外部使用
__all__ = ['CoVMSELoss']

.\YOLO-World\yolo_world\models\necks\yolo_world_pafpn.py

# 导入必要的库
import copy
from typing import List, Union
import torch
import torch.nn as nn
from torch import Tensor
from mmdet.utils import ConfigType, OptMultiConfig
# 导入自定义的模型注册器和工具函数
from mmyolo.registry import MODELS
from mmyolo.models.utils import make_divisible, make_round
from mmyolo.models.necks.yolov8_pafpn import YOLOv8PAFPN
# 注册YOLOWorldPAFPN类为模型
@MODELS.register_module()
class YOLOWorldPAFPN(YOLOv8PAFPN):
    """Path Aggregation Network used in YOLO World
    Following YOLOv8 PAFPN, including text to image fusion
    """
    # 初始化函数,定义模型结构和参数
    def __init__(self,
                 in_channels: List[int],
                 out_channels: Union[List[int], int],
                 guide_channels: int,
                 embed_channels: List[int],
                 num_heads: List[int],
                 deepen_factor: float = 1.0,
                 widen_factor: float = 1.0,
                 num_csp_blocks: int = 3,
                 freeze_all: bool = False,
                 block_cfg: ConfigType = dict(type='CSPLayerWithTwoConv'),
                 norm_cfg: ConfigType = dict(type='BN',
                                             momentum=0.03,
                                             eps=0.001),
                 act_cfg: ConfigType = dict(type='SiLU', inplace=True),
                 init_cfg: OptMultiConfig = None) -> None:
        # 设置引导通道数、嵌入通道数和头数
        self.guide_channels = guide_channels
        self.embed_channels = embed_channels
        self.num_heads = num_heads
        self.block_cfg = block_cfg
        # 调用父类的初始化函数,传入参数
        super().__init__(in_channels=in_channels,
                         out_channels=out_channels,
                         deepen_factor=deepen_factor,
                         widen_factor=widen_factor,
                         num_csp_blocks=num_csp_blocks,
                         freeze_all=freeze_all,
                         norm_cfg=norm_cfg,
                         act_cfg=act_cfg,
                         init_cfg=init_cfg)
    # 构建自顶向下的层
    def build_top_down_layer(self, idx: int) -> nn.Module:
        """build top down layer.
        Args:
            idx (int): layer idx.
        Returns:
            nn.Module: The top down layer.
        """
        # 深拷贝块配置
        block_cfg = copy.deepcopy(self.block_cfg)
        # 更新块配置参数
        block_cfg.update(
            dict(in_channels=make_divisible(
                (self.in_channels[idx - 1] + self.in_channels[idx]),
                self.widen_factor),
                 out_channels=make_divisible(self.out_channels[idx - 1],
                                             self.widen_factor),
                 guide_channels=self.guide_channels,
                 embed_channels=make_round(self.embed_channels[idx - 1],
                                           self.widen_factor),
                 num_heads=make_round(self.num_heads[idx - 1],
                                      self.widen_factor),
                 num_blocks=make_round(self.num_csp_blocks,
                                       self.deepen_factor),
                 add_identity=False,
                 norm_cfg=self.norm_cfg,
                 act_cfg=self.act_cfg))
        # 构建模型
        return MODELS.build(block_cfg)
    # 构建底部向上的层
    def build_bottom_up_layer(self, idx: int) -> nn.Module:
        """build bottom up layer.
        Args:
            idx (int): layer idx.
        Returns:
            nn.Module: The bottom up layer.
        """
        # 深拷贝块配置
        block_cfg = copy.deepcopy(self.block_cfg)
        # 更新块配置
        block_cfg.update(
            dict(in_channels=make_divisible(
                (self.out_channels[idx] + self.out_channels[idx + 1]),
                self.widen_factor),
                 out_channels=make_divisible(self.out_channels[idx + 1],
                                             self.widen_factor),
                 guide_channels=self.guide_channels,
                 embed_channels=make_round(self.embed_channels[idx + 1],
                                           self.widen_factor),
                 num_heads=make_round(self.num_heads[idx + 1],
                                      self.widen_factor),
                 num_blocks=make_round(self.num_csp_blocks,
                                       self.deepen_factor),
                 add_identity=False,
                 norm_cfg=self.norm_cfg,
                 act_cfg=self.act_cfg))
        # 构建模型
        return MODELS.build(block_cfg)
    # 定义前向传播函数,接受多层级的图像特征和文本特征作为输入,返回元组
    def forward(self, img_feats: List[Tensor], txt_feats: Tensor) -> tuple:
        """Forward function.
        including multi-level image features, text features: BxLxD
        """
        # 断言图像特征的数量与输入通道数相同
        assert len(img_feats) == len(self.in_channels)
        
        # 减少层级
        reduce_outs = []
        for idx in range(len(self.in_channels)):
            reduce_outs.append(self.reduce_layers[idx](img_feats[idx]))
        # 自顶向下路径
        inner_outs = [reduce_outs[-1]]
        for idx in range(len(self.in_channels) - 1, 0, -1):
            feat_high = inner_outs[0]
            feat_low = reduce_outs[idx - 1]
            upsample_feat = self.upsample_layers[len(self.in_channels) - 1 - idx](feat_high)
            if self.upsample_feats_cat_first:
                top_down_layer_inputs = torch.cat([upsample_feat, feat_low], 1)
            else:
                top_down_layer_inputs = torch.cat([feat_low, upsample_feat], 1)
            inner_out = self.top_down_layers[len(self.in_channels) - 1 - idx](top_down_layer_inputs, txt_feats)
            inner_outs.insert(0, inner_out)
        # 自底向上路径
        outs = [inner_outs[0]]
        for idx in range(len(self.in_channels) - 1):
            feat_low = outs[-1]
            feat_high = inner_outs[idx + 1]
            downsample_feat = self.downsample_layers[idx](feat_low)
            out = self.bottom_up_layers[idx](torch.cat([downsample_feat, feat_high], 1), txt_feats)
            outs.append(out)
        # 输出层
        results = []
        for idx in range(len(self.in_channels)):
            results.append(self.out_layers[idx](outs[idx]))
        return tuple(results)
# 使用 @MODELS 注册 YOLOWorldDualPAFPN 类
@MODELS.register_module()
# 定义 YOLOWorldDualPAFPN 类,继承自 YOLOWorldPAFPN 类
class YOLOWorldDualPAFPN(YOLOWorldPAFPN):
    """Path Aggregation Network used in YOLO World v8."""
    # 初始化函数,接受多个参数
    def __init__(self,
                 in_channels: List[int],  # 输入通道列表
                 out_channels: Union[List[int], int],  # 输出通道列表或整数
                 guide_channels: int,  # 引导通道数
                 embed_channels: List[int],  # 嵌入通道列表
                 num_heads: List[int],  # 多头注意力机制的头数列表
                 deepen_factor: float = 1.0,  # 加深因子,默认为1.0
                 widen_factor: float = 1.0,  # 扩宽因子,默认为1.0
                 num_csp_blocks: int = 3,  # CSP块的数量,默认为3
                 freeze_all: bool = False,  # 是否冻结所有层,默认为False
                 text_enhancder: ConfigType = dict(  # 文本增强器配置
                     type='ImagePoolingAttentionModule',  # 类型为图像池化注意力模块
                     embed_channels=256,  # 嵌入通道数为256
                     num_heads=8,  # 多头注意力机制的头数为8
                     pool_size=3),  # 池化大小为3
                 block_cfg: ConfigType = dict(type='CSPLayerWithTwoConv'),  # 块配置,默认为CSPLayerWithTwoConv
                 norm_cfg: ConfigType = dict(type='BN',  # 归一化配置,默认为BN
                                             momentum=0.03,  # 动量为0.03
                                             eps=0.001),  # epsilon为0.001
                 act_cfg: ConfigType = dict(type='SiLU', inplace=True),  # 激活函数配置,默认为SiLU
                 init_cfg: OptMultiConfig = None) -> None:  # 初始化配置,默认为None,返回None
        # 调用父类的初始化函数
        super().__init__(in_channels=in_channels,
                         out_channels=out_channels,
                         guide_channels=guide_channels,
                         embed_channels=embed_channels,
                         num_heads=num_heads,
                         deepen_factor=deepen_factor,
                         widen_factor=widen_factor,
                         num_csp_blocks=num_csp_blocks,
                         freeze_all=freeze_all,
                         block_cfg=block_cfg,
                         norm_cfg=norm_cfg,
                         act_cfg=act_cfg,
                         init_cfg=init_cfg)
        # 更新文本增强器配置
        text_enhancder.update(
            dict(
                image_channels=[int(x * widen_factor) for x in out_channels],  # 图像通道数根据输出通道和扩宽因子计算
                text_channels=guide_channels,  # 文本通道数为引导通道数
                num_feats=len(out_channels),  # 特征数量为输出通道数的长度
            ))
        # 打印文本增强器配置
        print(text_enhancder)
        # 构建文本增强器模型
        self.text_enhancer = MODELS.build(text_enhancder)
    # 定义前向传播函数,接受图像特征列表和文本特征作为输入,返回元组
    def forward(self, img_feats: List[Tensor], txt_feats: Tensor) -> tuple:
        """Forward function."""
        # 断言图像特征列表的长度与输入通道数相同
        assert len(img_feats) == len(self.in_channels)
        
        # 减少层
        reduce_outs = []
        for idx in range(len(self.in_channels)):
            reduce_outs.append(self.reduce_layers[idx](img_feats[idx]))
        # 自顶向下路径
        inner_outs = [reduce_outs[-1]]
        for idx in range(len(self.in_channels) - 1, 0, -1):
            feat_high = inner_outs[0]
            feat_low = reduce_outs[idx - 1]
            upsample_feat = self.upsample_layers[len(self.in_channels) - 1 - idx](feat_high)
            if self.upsample_feats_cat_first:
                top_down_layer_inputs = torch.cat([upsample_feat, feat_low], 1)
            else:
                top_down_layer_inputs = torch.cat([feat_low, upsample_feat], 1)
            inner_out = self.top_down_layers[len(self.in_channels) - 1 - idx](top_down_layer_inputs, txt_feats)
            inner_outs.insert(0, inner_out)
        # 对文本特征进行增强
        txt_feats = self.text_enhancer(txt_feats, inner_outs)
        
        # 自底向上路径
        outs = [inner_outs[0]]
        for idx in range(len(self.in_channels) - 1):
            feat_low = outs[-1]
            feat_high = inner_outs[idx + 1]
            downsample_feat = self.downsample_layers[idx](feat_low)
            out = self.bottom_up_layers[idx](torch.cat([downsample_feat, feat_high], 1), txt_feats)
            outs.append(out)
        # 输出层
        results = []
        for idx in range(len(self.in_channels)):
            results.append(self.out_layers[idx](outs[idx]))
        return tuple(results)

.\YOLO-World\yolo_world\models\necks\__init__.py

# 版权声明,版权归腾讯公司所有
# 导入yolo_world_pafpn模块中的YOLOWorldPAFPN和YOLOWorldDualPAFPN类
from .yolo_world_pafpn import YOLOWorldPAFPN, YOLOWorldDualPAFPN
# 定义__all__列表,包含YOLOWorldPAFPN和YOLOWorldDualPAFPN类,用于模块导入时指定可导入的内容
__all__ = ['YOLOWorldPAFPN', 'YOLOWorldDualPAFPN']

.\YOLO-World\yolo_world\models\__init__.py

# 导入 Tencent 公司所有权的代码库
# 从 backbones 模块中导入所有内容
from .backbones import *  # noqa
# 从 layers 模块中导入所有内容
from .layers import *  # noqa
# 从 detectors 模块中导入所有内容
from .detectors import *  # noqa
# 从 losses 模块中导入所有内容
from .losses import *  # noqa
# 从 data_preprocessors 模块中导入所有内容
from .data_preprocessors import *  # noqa
# 从 dense_heads 模块中导入所有内容
from .dense_heads import *  # noqa
# 从 necks 模块中导入所有内容
from .necks import *  # noqa

.\YOLO-World\yolo_world\version.py

# 版权声明
# 版权所有 © 腾讯公司
# 定义版本号
__version__ = '0.1.0'
# 解析版本信息的函数
def parse_version_info(version_str):
    """Parse a version string into a tuple.
    Args:
        version_str (str): The version string.
    Returns:
        tuple[int | str]: The version info, e.g., "1.3.0" is parsed into
            (1, 3, 0), and "2.0.0rc1" is parsed into (2, 0, 0, 'rc1').
    """
    # 初始化版本信息列表
    version_info = []
    # 根据 '.' 分割版本号字符串
    for x in version_str.split('.'):
        # 如果是数字,则转换为整数
        if x.isdigit():
            version_info.append(int(x))
        # 如果包含 'rc',则分割出补丁版本号
        elif x.find('rc') != -1:
            patch_version = x.split('rc')
            version_info.append(int(patch_version[0]))
            version_info.append(f'rc{patch_version[1]}')
    # 返回版本信息元组
    return tuple(version_info)
# 调用解析版本信息函数,得到版本信息元组
version_info = parse_version_info(__version__)
# 导出的变量列表
__all__ = ['__version__', 'version_info', 'parse_version_info']

.\YOLO-World\yolo_world\__init__.py

# 导入当前目录下的 models 模块中的所有内容
from .models import *  # noqa
# 导入当前目录下的 datasets 模块中的所有内容
from .datasets import *  # noqa
# 导入当前目录下的 engine 模块中的所有内容
from .engine import *  # noqa
相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
87 2
|
11天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
11天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
11天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
57 12
|
30天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
12天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
3月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
87 0
|
3月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
68 0
|
3月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
73 0

推荐镜像

更多