Text-to-SQL将自然语言转换为数据库查询语句

news2025/3/18 19:48:49

有关Text-To-SQL方法,可以查阅我的另一篇文章,Text-to-SQL方法研究

直接与数据库对话-text2sql

Text2sql就是把文本转换为sql语言,这段时间公司有这方面的需求,调研了一下市面上text2sql的方法,比如阿里的Chat2DB,麻省理工开源的Vanna。试验了一下,最终还是决定自研,基于Vanna的思想,RAG+大模型。

    使用开源的Vanna实现text2sql比较方便,Vanna可以直接连接数据库,但是当用户权限能访问多个数据库的时候,就比较麻烦了,而且Vanna向量化存储之后,新的question作对比时没有区分数据库。因此自己实现了一下text2sq,仍然采用Vanna的思想,提前训练DDL,Sqlques,和数据库document。

这里简单做一下记录,以供后续学习使用。

基本思路

1、数据库DDL语句,SQL-Question,Dcoument信息获取

2、基于用户提问question和数据库Document锁定要分析的数据库

3、模型训练:借助数据库的DDL语句、元数据(描述数据库自身数据的信息)、相关文档说明、参考样例SQL等,训练一个RAG“模型”。

这一模型结合了embedding技术和向量数据库,使得数据库的结构和内容能够被高效地索引和检索。

4、语义检索: 当用户输入自然语言描述的问题时,①会从向量库里面检索,迅速找出与问题相关的内容;②进行BM25算法文本召回,找到与问题 最相关的内容;③分别使用RRF算法和Re-ranking重排序算法,锁定最相关内容

语义匹配:使用算法(如BERT等)来理解查询和文档的语义相似性

文本召回匹配:BM25算法文本召回,找到与问题最相关的内容

rerank结果重排序:对搜索结果进行排序。

5、Prompt构建: 检索到的相关信息会被组装进Prompt中,形成一个结构化的查询描述。这一Prompt随后会被传递给LLM(大型语言模型)用于生成准确的SQL查询。

实现逻辑图

实现架构图:

具体实现方式如下所示:

1.数据库的选择

class DataBaseSearch(object):
    def __init__(self, _model):
        self.name = 'DataBaseSearch'
        self.model = _model
        self.instruction = "为这段内容生成表示以用于匹配文本描述:"
        self.SIZE = 1024
        self.index = faiss.IndexFlatL2(self.SIZE)

        self.textdata = []
        self.subdata = {}
        self.i2key = {}
        self.id2ddls = {}
        self.id2sqlques = {}
        self.id2docs = {}
        self.strtexts = {}

        # self.ddldata = []
        # self.sqlques_data = []
        # self.document_data = []
        self.load_textdata()         # 加载text数据
        self.load_textdata_vec()     # text数据向量化

    def load_textdata(self):
        try:
            response = requests.post(
                url="xxx",
                verify=False)
            print(response.text)
            jsonobj = json.loads(response.text)

            textdatas = jsonobj["data"]

            for textdata in textdatas:                                 # 提取每一个数据库内容
                cid = textdata["dataSetID"]
                cddls = textdata["ddl"]
                csql_ques = textdata["exp"]
                cdocuments = textdata["Intro"]

                self.textdata.append((cid, cddls, csql_ques, cdocuments))   # 整合所有数据
        except Exception as e:
            print(e)
        # print("load textdata ", self.textdata)


    def load_textdata_vec(self):
        num0 = 0
        for recode in self.textdata:
            _id = recode[0]
            _ddls = recode[1]
            _sql_ques = recode[2]
            _documents = recode[3]

            # _strtexts = str(_ddls) + str(_sql_ques) + str(_documents)
            _strtexts = str(_sql_ques) + str(_documents)
            text_embeddings = self.model.encode([_strtexts], normalize_embeddings=True)
            self.index.add(text_embeddings)

            self.i2key[num0] = _id
            self.strtexts[_id] = _strtexts
            self.id2ddls[_id] = _ddls
            self.id2sqlques[_id] = _sql_ques
            self.id2docs[_id] = _documents


            num0 += 1
        # print("init instruction vec", num0)

    def calculate_score(self, score, question, kws):
        pass

    def find_vec_database(self, question, k, theata):
        # print(question)
        q_embeddings = self.model.encode([self.instruction + question], normalize_embeddings=True)

        D, I = self.index.search(q_embeddings, k)

        result = []
        for i in range(k):
            sim_i = I[0][i]
            uuid = self.i2key.get(sim_i, "none")
            sim_v = D[0][i]
            database_texts = self.strtexts.get(uuid, "none")
            # score = self.calculate_score(sim_v, question, database_texts) # wait implement
            score = int(sim_v*1000)
            if score < theata:
                doc = {}
                doc["score"] = score
                doc["dataSetID"] = uuid
                result.append(doc)
        # print(result)
        return result

if __name__ == '__main__':

    modelpath = "E:\\module\\bge-large-zh-v1.5"
    model = SentenceTransformer(modelpath)

    vs = DataBaseSearch(model)

    result = vs.find_vec_database("查询济南市第三幼儿园所有小班班级?", 1, 2000)
    print(result)

2.sql_ques:sql问题训练

class SqlQuesSearch(object):
    def __init__(self, _model):
        self.name = "SqlQuesSearch"
        self.model = _model
        self.instruction = "为这段内容生成表示以用于匹配文本描述:"
        self.SIZE = 1024
        self.index = faiss.IndexFlatL2(self.SIZE)

        self.sqlquedata = []

        self.i2dbid = {}
        self.i2sqlid = {}
        self.id2sqlque = {}
        self.id2que = {}
        self.id2sql = {}
        self.dbid2sqlques = {}
        #
        # self.sqlques = {}
        #
        # self.i2key = {}
        #
        # self.id2sqlques = {}
        #
        # self.num2sqlque = {}



        # self.ddldata = []
        # self.sqlques_data = []
        # self.document_data = []

        self.load_textdata()  # 加载text数据

        self.load_textdata_vec()  # text数据向量化

    def load_textdata(self):
        try:
            response = requests.post(
                url="xxx",
                verify=False)
            print(response.text)
            jsonobj = json.loads(response.text)
           
            textdatas = jsonobj["data"]

datadatas = jsonobj["data"]

            for datadata in datadatas:  # 提取每一个数据库sql-ques内容
                dbid = datadata["dataSetID"]
                sql_ques = datadata["exp"]

                self.sqlquedata.append((dbid, sql_ques))  # 整合sql数据


        except Exception as e:
            print(e)
        # print("load textdata ", self.sqlquedata)

    def load_textdata_vec(self):

        num0 = 0
        for recode in self.sqlquedata:
            db_id = recode[0]
            sql_ques = recode[1]

            for sql_que in sql_ques:
                sql_id = sql_que["sql_id"]
                question = sql_que["question"]
                sql = sql_que["sql"]

                ddl_embeddings = self.model.encode([question], normalize_embeddings=True)
                self.index.add(ddl_embeddings)

                self.i2dbid[num0] = db_id
                self.i2sqlid[num0] = sql_id
                self.id2que[sql_id] = question
                self.id2sql[sql_id] = sql

                num0 += 1
        print("init sql-que vec", num0)

    def calculate_score(sim_v, question, sql_ques):
        pass

    def find_vec_sqlque(self, question, k, theta, dataSetID, number):
        q_embeddings = self.model.encode([self.instruction + question], normalize_embeddings=True)
        D, I = self.index.search(q_embeddings, k)

        result = []
        for i in range(k):
            sim_i = I[0][i]
            dbid = self.i2dbid.get(sim_i, "none")  # 获取数据库id
            sqlid = self.i2sqlid.get(sim_i, "none")
            question = self.id2que.get(sqlid, "none")
            sql = self.id2sql.get(sqlid, "none")
            if dbid == dataSetID:
                sim_v = D[0][i]
                score = int(sim_v * 1000)
                if score < theta:
                    doc = {}
                    doc["score"] = score
                    doc["question"] = question
                    doc["sql"] = sql
                    result.append(doc)
                    if len(result) == number:
                        break
        return result


if __name__ == '__main__':

    modelpath = "E:\\module\\bge-large-zh-v1.5"
    model = SentenceTransformer(modelpath)

    vs = SqlQuesSearch(model)

    result = vs.find_vec_sqlque("查询7月18日所有的儿童观察记录?", 3, 2000, dataSetID=111)

    print(result)

3.数据库DDL训练

class DdlQuesSearch(object):
    def __init__(self, _model):
        self.name = "DdlQuesSearch"
        self.model = _model
        self.instruction = "为这段内容生成表示以用于匹配文本描述:"
        self.SIZE = 1024
        self.index = faiss.IndexFlatL2(self.SIZE)

        self.ddldata = []

        self.sqlques = {}

        self.i2dbid = {}
        self.i2ddlid = {}


        self.dbid2ddls = {}
        self.id2ddl = {}
        self.ddlid2dbid = {}

        # self.ddldata = []
        # self.sqlques_data = []
        # self.document_data = []

        self.load_ddldata()  # 加载text数据

        self.load_ddl_vec()  # text数据向量化

    def load_ddldata(self):
        try:
            response = requests.post(
                url="xxx",
                verify=False)
            print(response.text)
            jsonobj = json.loads(response.text)

            for database in databases:
                db_id = database["dataSetID"]
                ddls = database["ddl"]

                self.ddldata.append((db_id, ddls))
                # print(db_id)

                # for ddl in database["ddl"]:
                #     ddl_id = ddl["ddl_id"]
                #     ddl = ddl['ddl']
                #
                #     self.id2ddl[ddl_id] = ddl
                # self.dbid2ddls[db_id] = self.id2ddl
        except Exception as e:
            print(e)
        # print("load textdata ", self.ddldata)

    def load_ddl_vec(self):

        num0 = 0
        for recode in self.ddldata:
            db_id = recode[0]
            ddls = recode[1]

            for ddl in ddls:
                ddl_id = ddl["ddl_id"]
                ddl_name = ddl["TABLE"]
                ddl = ddl['ddl']
                ddl_embeddings = self.model.encode([ddl], normalize_embeddings=True)
                self.index.add(ddl_embeddings)

                self.i2dbid[num0] = db_id
                self.i2ddlid[num0] = ddl_id
                self.id2ddl[ddl_id] = ddl
                self.ddlid2dbid[ddl_id] = db_id

                num0 += 1


            self.dbid2ddls[db_id] = self.id2ddl
        print("init ddl vec", num0)

    def find_vec_ddl(self, question, k, theata, dataSetID, number):       # dataSetID:数据库id
        # self.id2ddls.get(action_id)
        q_embeddings = self.model.encode([self.instruction + question], normalize_embeddings=True)
        D, I = self.index.search(q_embeddings, k)

        result = []
        for i in range(k):
            sim_i = I[0][i]
            dbid = self.i2dbid.get(sim_i, "none")         # 获取数据库id
            ddlid = self.i2ddlid.get(sim_i, "none")
            if dbid == dataSetID:
                sim_v = D[0][i]
                score = int(sim_v * 1000)

                if score < theata:
                    doc = {}
                    doc["score"] = score
                    doc["ddl"] = self.id2ddl.get(ddlid, "none")
                    result.append(doc)
                    if len(result) == number:
                        break
        return result


if __name__ == '__main__':
    modelpath = "E:\\module\\bge-large-zh-v1.5"
    model = SentenceTransformer(modelpath)

    vs = DdlQuesSearch(model)

    ss = vs.find_vec_ddl("定时任务执行记录表", 2, 2000, 111)
    print(ss)

4.数据库document训练

class DocQuesSearch(object):
    def __init__(self):
        self.name = "TestDataSearch"
        self.docdata = []

        self.load_doc_data()

    def load_doc_data(self):
        try:
            response = requests.post(
                url="xxx",
                verify=False)
            print(response.text)
            jsonobj = json.loads(response.text)

databases = jsonobj["data"]

            for database in databases:
                db_id = database["dataSetID"]
                doc = database["Intro"]
                self.docdata.append((db_id, doc))
        except Exception as e:
            print(e)
        # print("load ddldata ", self.docdata)

    def find_similar_doc(self, dataSetID):
        result = []
        for recode in self.docdata:
            dbid = recode[0]
            doc = recode[1]
            if dbid == dataSetID:
                result.append(doc)
        return result



if __name__ == '__main__':
    docques_search = DocQuesSearch()
    result = docques_search.find_similar_doc(222)
    print(result)

5.生成sql语句,这里使用的qwen-max模型

import re
import random
import os, json
import dashscope
from dashscope.api_entities.dashscope_response import Message
from ddl_engine import DdlQuesSearch
from dashscope import Generation
from sqlques_engine import SqlQuesSearch
from sentence_transformers import SentenceTransformer

class Genarate(object):
    def __init__(self):
        self.api_key = os.environ.get('api_key')
        self.model_name = os.environ.get('model')

    def system_message(self, message):
        return {'role': 'system', 'content': message}

    def user_message(self, message):
        return {'role': 'user', 'content': message}

    def assistant_message(self, message):
        return {'role': 'assistant', 'content': message}

    def submit_prompt(self, prompt):
        resp = Generation.call(
            model=self.model_name,
            messages=prompt,
            seed=random.randint(1, 10000),
            result_format='message',
            api_key=self.api_key)

        if resp["status_code"] == 200:
            answer = resp.output.choices[0].message.content
            global DEBUG_INFO
            DEBUG_INFO = (prompt, answer)
            return answer
        else:
            answer = None
            return answer


    def generate_sql(self, question, sql_result, ddl_result, doc_result):
        prompt = self.get_sql_prompt(
            question = question,
            sql_result = sql_result,
            ddl_result = ddl_result,
            doc_result = doc_result)

        print("SQL Prompt:",prompt)
        llm_response = self.submit_prompt(prompt)

        sql = self.extrat_sql(llm_response)

        return sql

    def extrat_sql(self, llm_response):
        sqls = re.findall(r"WITH.*?;", llm_response, re.DOTALL)
        if sqls:
            sql = sqls[-1]
            return sql

        sqls = re.findall(r"SELECT.*?;", llm_response, re.DOTALL)
        if sqls:
            sql = sqls[-1]
            return sql

        sqls = re.findall(r"```sql\n(.*)```", llm_response, re.DOTALL)
        if sqls:
            sql = sqls[-1]
            return sql

        sqls = re.findall(r"```(.*)```", llm_response, re.DOTALL)
        if sqls:
            sql = sqls[-1]
            return sql

        return llm_response

    def get_sql_prompt(self, question, sql_result, ddl_result, doc_result):

        initial_prompt = "You are a SQL expert. " + \
                              "Please help to generate a SQL query to answer the question. Your response should ONLY be based on the given context and follow the response guidelines and format instructions. "

        initial_prompt = self.add_ddl_to_prompt( initial_prompt, ddl_result)
        initial_prompt = self.add_documentation_to_prompt(initial_prompt, doc_result)
        initial_prompt += (
            "===Response Guidelines \n"
            "1. If the provided context is sufficient, please generate a valid SQL query without any explanations for the question. \n"
            "2. If the provided context is almost sufficient but requires knowledge of a specific string in a particular column, please generate an intermediate SQL query to find the distinct strings in that column. Prepend the query with a comment saying intermediate_sql \n"
            "3. If the provided context is insufficient, please explain why it can't be generated. \n"
            "4. Please use the most relevant table(s). \n"
            "5. If the question has been asked and answered before, please repeat the answer exactly as it was given before. \n"
        )
        message_log = [self.system_message(initial_prompt)]

        message_log = self.add_sqlques_to_prompt(question, sql_result, message_log)

        return message_log

    def add_ddl_to_prompt(self, initial_prompt, ddl_result):
        """
        :param initial_prompt:
        :param ddl_result:
        :return:
        """

        ddl_list = [ ddl_['ddl'] for ddl_ in ddl_result]
        if len(ddl_list) > 0:
            initial_prompt += "\n===Tables \n"
            for ddl in ddl_list:
                initial_prompt += f"{ddl}\n\n"

        return initial_prompt

    def add_sqlques_to_prompt(self, question, sql_result, message_log):
        """
        :param sql_result:
        :return:
        """
        if len(sql_result) > 0:
            for example in sql_result:
                if example is not None and "question" in example and "sql" in example:
                    message_log.append(self.user_message(example["question"]))
                    message_log.append(self.assistant_message(example["sql"]))

            message_log.append(self.user_message(question))

        return message_log

    def add_documentation_to_prompt(self, initial_prompt, doc_result):
        if len(doc_result) > 0:
            initial_prompt += "\n===Additional Context \n\n"

            for doc in doc_result:
                initial_prompt += f"{doc}\n\n"
        return initial_prompt




if __name__ == '__main__':
    modelpath = "E:\\module\\bge-large-zh-v1.5"
    model = SentenceTransformer(modelpath)

    vs = DdlQuesSearch(model)

    ss = vs.find_vec_ddl("定时任务执行记录表", 1, 2000, 111)
    print(ss)

6.执行结果显示

如图可以看到正确生成了sql,可以正常执行,因为表是拉取到,没有数据,所以查询结果为空。

需要源码的同学,可以留言。

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

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

相关文章

XSS漏洞靶场---(复现)

XSS漏洞靶场—&#xff08;复现&#xff09; 反射型 XSS 的特点是攻击者诱导用户点击包含恶意脚本的 URL&#xff0c;服务器接收到请求后将恶意脚本反射回响应页面&#xff0c;浏览器执行该脚本从而造成攻击&#xff0c;恶意脚本不会在服务器端存储。 Level 1(反射型XSS) 此漏…

基于ssm的电子病历系统(全套)

一、系统架构 前端&#xff1a;jsp | bootstrap | jquery 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql | maven | tomcat | idea 二、代码及数据库 三、功能介绍 01. 登录 02. 主页 03. 管理员-个人中心-修改密码…

Linux-数据结构-线性表-单链表

一.链表的概念 【1】线性表的链式存储 解决顺序存储的缺点&#xff0c;插入和删除&#xff0c;动态存储问题。 【2】特点&#xff1a; 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素&#xff0c;存储单元可以是连续的&#xff0c;也可以不连续。可以被存…

基于SpringBoot的Mybatis和纯MyBatis项目搭建的区别

【由于之前学习MyBatis的时候是跟着视频敲的纯MyBatis项目&#xff0c;以至于在突然看到别人在SpringBoot项目里搭建MyBatis方式的时候很懵比…特此文字形式记录一下区别&#xff08;应该还有好多种其他方式是我不知道的&#xff0c;主要应该就是要知道关键的流程步骤&#xff…

大数据学习(68)- Flink和Spark Streaming

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…

Fastdata极数:中国民宿行业发展趋势报告2025

2024年&#xff0c;中国游客出行次数大幅上涨&#xff0c;旅游相关支出也复苏强劲。2025年中国旅游业还将持续稳健的复苏及增长。同时&#xff0c;中国旅游业将见证一场深刻的变革&#xff0c;这场变革的推动力是消费者对旅游期望的转变&#xff0c;经济因素和年轻人全新价值观…

图论——广度优先搜索实现

99. 岛屿数量 题目描述 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。 输入描述 第一行包含两个整数 N, M,表示矩阵的行数和列数。 后续 N 行,每行…

鸿蒙路由 HMrouter 配置及使用一

1、学习链接 HMRouter地址 https://gitee.com/hadss/hmrouter/blob/dev/HMRouterLibrary/README.md 2、工程配置 下载安装 ohpm install hadss/hmrouter 添加编译插件配置 在工程目录下的build-profile.json5中&#xff0c;配置useNormalizedOHMUrl属性为true (我这项目创…

各省水资源平台 水资源遥测终端机都用什么协议

各个省水资源平台 水资源遥测终端机 的建设大部分从2012年开始启动&#xff0c;经过多年建设&#xff0c;基本都已经形成了稳定的通讯要求&#xff1b;河北瑾航科技 遥测终端机&#xff0c;兼容了大部分省市的通讯协议&#xff0c;如果需要&#xff0c;可以咨询和互相学习&…

需求分析、定义、验证、变更、跟踪(高软47)

系列文章目录 需求分析、定义、验证、变更、跟踪 文章目录 系列文章目录前言一、需求分析二、需求定义三、需求验证四、需求变更五、需求跟踪六、真题总结 前言 本节讲明需求分析、定义、验证、变更、跟踪相关知识。 一、需求分析 二、需求定义 三、需求验证 四、需求变更 五、…

从零开始 | C语言基础刷题DAY3

❤个人主页&#xff1a;折枝寄北的博客 目录 1.打印3的倍数的数2.从大到小输出3. 打印素数4.打印闰年5.最大公约数 1.打印3的倍数的数 题目&#xff1a; 写一个代码打印1-100之间所有3的倍数的数字 代码&#xff1a; int main(){int i 0;for (i 1; i < 100; i){if (i % …

docker入门篇

使用docker可以很快部署相同的环境,这也是最快的环境构建,接下来就主要对docker中的基础内容进行讲解.Docker 是一个用于开发、交付和运行应用程序的开源平台&#xff0c;它可以让开发者将应用程序及其依赖打包到一个容器中&#xff0c;然后在任何环境中运行这个容器&#xff0…

Unity Shader - UI Sprite Shader之简单抠图效果

Sprite抠图效果&#xff1a; 前言 在PhotoShop中我们经常会用到抠图操作&#xff0c;现在就用Shader实现一个简单的抠图效果。 实现原理&#xff1a; 使用当前像素颜色与需要抠掉的颜色相减作比较&#xff0c;然后与一个指定的阈值比较以决定是否将其显示出来&#xff1b; U…

vllm-openai多服务器集群部署AI模型

服务器配置是两台ubantu系统电脑,每台电脑安装两张4090-48G显存的显卡,共计192G显存。 服务器1 服务器2 准备工作: 1.两台电脑都已经安装了docker 2.两台电脑都已经安装了nvidia驱动 参考vllm官方资料 https://docs.vllm.ai/en/latest/serving/distributed_serving.html…

在Spring Boot项目中接入DeepSeek深度求索,感觉笨笨的呢

文章目录 引言1. 什么是DeepSeek&#xff1f;2. 准备工作2.1 注册DeepSeek账号 3.实战演示3.1 application增加DS配置3.2 编写service3.3 编写controller3.4 编写前端界面chat.html3.5 测试 总结 引言 在当今快速发展的数据驱动时代&#xff0c;企业越来越重视数据的价值。为了…

STM32---FreeRTOS事件标志组

一、简介 事件标志位&#xff1a;用一个位&#xff0c;来表示事件是否发生 事件标志组&#xff1a;一组事件标志位的集合&#xff0c;可以简单的理解时间标志组&#xff0c;就是一个整体。 事件标志租的特点&#xff1a; 它的每一个位表示一个时间&#xff08;高8位不算&…

Word 小黑第40套

对应大猫43 主题 -浏览主题 -选择W样式标准文件就行 1级段落和2级段落&#xff08;用项目符号不影响原本段落文字符号 颜色修改为自动&#xff09; 整段变红的 不是把光标定位到红色字体那里 要选择几个红色字体 再创建样式 插入的空白页一定要是下一页&#xff0c;不能插空白…

【Linux我做主】浅谈Shell及其原理

浅谈Linux中的Shell及其原理 Linux中Shell的运行原理github地址前言一、Linux内核与Shell的关系1.1 操作系统核心1.2 用户与内核的隔离 二、Shell的演进与核心机制2.1 发展历程2.2 核心功能解析2.3 shell的工作流程1. 用户输入命令2. 解析器拆分指令3. 扩展器处理动态内容变量替…

数据结构篇——二叉树的存储与遍历

一、引入 书接上文&#xff0c;文于此续。上文我们学到了树的存储结构&#xff0c;那么今天&#xff0c;我们来学习下几种特殊的二叉树以及关于它的各种遍历&#xff0c;让我们一起加油吧。 二、特殊的二叉树 二叉树的特殊形式这里介绍3种&#xff0c;其中需要着重记忆的有…

分而治之:用于 RGB-T 显著目标检测的 Confluent Triple-Flow 网络(问题)

摘要 问题一&#xff1a;RGB-thermal显著对象检测这是什么&#xff1f; RGB图像是可见光的三通道图像&#xff0c;而thermal是热红外图像&#xff0c;通常为单通道&#xff0c;记录物体的热辐射信息。结合RGB和thermal两种模态的数据&#xff0c;可以利用两者的互补信息&…