FreeSOLO: Learning to Segment Objects without Annotations* (CVPR. 2022)

FreeSOLO是一种创新的无监督学习方法,无需任何标注即可实现类无关实例分割。通过Free Mask和Self-supervised SOLO两个主要组件,该框架能有效提取粗略对象掩模和语义嵌入。实验表明,FreeSOLO在无监督实例分割和对象检测任务上超越现有方法,且在有监督微调后表现出色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

1. Motivation

  • Instance segmentation requires costly annotations such as bounding boxes and segmentation masks for learning.

  • We propose a fully unsupervised learning method that learns class-agnostic instance segmentation without any annotations.

  • a novel localization-aware pre-training framework

  • FreeSOLO, contains two major pillars: Free Mask and Self-supervised SOLO,

2. Contribution

  • We propose the Free Mask approach, which leverages the specific design of SOLO to effectively extract coarse ob- ject masks and semantic embeddings in an unsupervised manner.
  • We further propose Self-Supervised SOLO, which takes the coarse masks and semantic embeddings from Free Mask and trains the SOLO instance segmentation model, with several novel design elements to overcome label noise in the coarse masks.
  • With the above methods, FreeSOLO presents a simple and effective framework that demonstrates unsupervised instance segmentation successfully for the first time. Notably, it outperforms some proposal generation methods that use manual annotations. FreeSOLO also outperforms state-of-the-art methods for unsupervised object detection/discovery by a significant margin (relative +100% in COCO AP).
  • In addition, FreeSOLO serves as a strong self-supervised pretext task for representation learning for instance segmentation. For example, when fine-tuning on COCO dataset with 5% labeled masks, FreeSOLO outperforms DenseCL [14] by +9.8% AP

在这里插入图片描述

3. Method

3.1 background

在这里插入图片描述

简要回顾一下SOLO

  • 2个分支 category-branch and mask branch
  • mask branch: H x W X S^2
  • category-branch: S x S x C

SOLOV2

  • 多了mask NMS
  • 多了dynamic mask branch 分割为了 kernel branch S x S x D 以及features branch H x W x D。
  • 如果是1x1的kernel 那么D=E, 如果是3x3的kernel 那么D=9E 因为都是对于一个1x1的 grid的D维特征 作为 HxW 特征图的 kernel
  • <
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: MAIN MODULE: .\Objects\main.obj (MAIN) *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?MAIN?MAIN *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: I2CRECEIVEBYTE MODULE: .\Objects\iic.obj (IIC) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: I2CSTART MODULE: .\Objects\iic.obj (IIC) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: _I2CSENDACK MODULE: .\Objects\iic.obj (IIC) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: _I2CSENDBYTE MODULE: .\Objects\iic.obj (IIC) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: I2CWAITACK MODULE: .\Objects\iic.obj (IIC) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: I2CSTOP MODULE: .\Objects\iic.obj (IIC) *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CSTART MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EDDH *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: _I2CSENDBYTE MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EE2H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CWAITACK MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EE5H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: _I2CSENDBYTE MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EEAH *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CWAITACK MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EEDH *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CSTART MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EF0H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: _I2CSENDBYTE MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EF5H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CWAITACK MODULE: .\Objects\iic.obj (IIC) ADDRESS: 0EF8H *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2CRECEIVEBYTE MODULE: .\Objects\iic.
最新发布
04-03
<think>好的,用户遇到了I2C相关的L104多重公共定义和未解析外部符号链接错误。需要结合提供的引用资料来分析问题。 首先,L104错误通常是因为变量或函数在多个文件中重复定义。根据引用[1]、[3]、[4]和[5],这通常是由于头文件中定义了变量但没有使用extern声明,导致每个包含该头文件的.c文件都进行了定义,从而引发重复。例如,在头文件中声明变量时,应该用extern,然后在某个.c文件中定义。 然后是未解析外部符号错误,这通常是因为函数或变量声明了但没有定义,或者定义的地方没有被正确链接。比如在iic.obj中可能声明了I2C相关的函数,但实际没有实现,或者实现未被包含到项目中。 接下来需要检查代码结构。用户可能在头文件中直接定义了变量,而没有使用extern。比如在i2c.h中如果有int busy;这样的定义,每个包含i2c.h的文件都会有自己的busy变量,导致L104错误。正确的做法是在头文件中用extern声明,如extern int busy;,然后在i2c.c中定义int busy;。 此外,检查是否有多个.c文件包含main函数,这会导致重复定义,如引用[5]提到的,一个工程只能有一个main函数。如果用户不小心在多个文件中写了main,需要删除多余的。 关于未解析外部符号,可能是在使用I2C函数时,声明了但没有实现,或者函数名拼写错误,或者没有将iic.c文件添加到项目中,导致链接器找不到定义。需要确保iic.c被正确包含,并且函数实现正确。 可能还需要检查函数声明和定义是否一致,比如参数类型和返回类型是否匹配。如果有函数在头文件中声明为extern,但在实现时名称或参数不一致,会导致链接错误。 总结步骤应该是:首先处理L104错误,确保变量和函数只在头文件中用extern声明,在单一.c文件中定义;然后处理未解析符号,确保所有使用的函数和变量都有正确的定义,并且项目文件包含正确。</think>### 解决I2C相关的L104多重定义及未解析符号问题 #### 1. **L104多重公共定义错误分析** 此错误表示**变量或函数在多个模块中被重复定义**,常见于以下场景: - **头文件直接定义变量**:若在头文件中直接定义全局变量(例如`int busy;`),每个包含该头文件的`.c`文件都会生成独立定义,导致重复[^1][^3][^4]。 - **多个源文件包含相同函数定义**:例如多个`.c`文件中定义了同名函数或`main`函数[^5]。 - **模块间变量共享方式错误**:未正确使用`extern`关键字声明外部变量[^1]。 #### 2. **未解析外部符号错误分析** 此错误表示**符号声明存在但未找到实际定义**,可能原因包括: - **函数未实现**:在头文件声明了函数(例如`void I2C_Init();`),但未在`.c`文件中实现。 - **文件未加入工程**:包含函数定义的源文件(如`iic.c`)未添加到编译链。 - **作用域限制**:函数或变量定义被`static`修饰,导致无法跨文件访问。 --- ### 解决方案步骤 #### 1. **解决L104多重定义问题** - **头文件变量声明方式**: ```c // i2c.h extern int busy; // 声明为外部变量 ``` ```c // i2c.c int busy = 0; // 实际定义 ``` 确保全局变量**仅在单一源文件中定义**,其他文件通过`extern`引用。 - **检查重复定义的函数**: - 确认所有模块中**只有一个`main`函数**(删除多余的`main`函数)。 - 检查I2C相关函数(如`I2C_Start()`)是否在多个`.c`文件中重复实现。 #### 2. **解决未解析外部符号问题** - **验证函数实现**: ```c // i2c.h void I2C_Init(void); // 函数声明 ``` ```c // i2c.c void I2C_Init(void) { // 实际实现 // 初始化代码 } ``` 确保函数声明与实现**名称、参数、返回值完全一致**。 - **检查工程文件包含**: - 在Keil中右键点击工程目录 -> "Add Existing Files",确认`iic.c`已加入工程。 - 移除未使用的旧版本文件(避免残留定义干扰)。 - **链接器配置检查**: - 确认编译选项中未排除`iic.c`。 - 检查文件路径是否包含`iic.c`所在目录。 #### 3. **其他调试建议** - **使用`#pragma once`**:在头文件顶部添加`#pragma once`,防止重复包含。 - **模块化设计**:将I2C驱动代码独立为`i2c.h`和`i2c.c`,通过接口调用。 - **符号表检查**:通过Keil的`Map File`查看符号定义位置,定位冲突或缺失的符号。 --- ### 示例代码结构 ```c // i2c.h #pragma once extern int busy; // 外部变量声明 void I2C_Init(void); ``` ```c // i2c.c #include "i2c.h" int busy = 0; // 实际定义 void I2C_Init(void) { // 初始化代码 } ``` ```c // main.c #include "i2c.h" int main() { I2C_Init(); while(busy == 0); // 使用外部变量 return 0; } ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值