ITPub博客

首页 > 人工智能 > 人工智能 > 智能体的感知与理解

智能体的感知与理解

原创 人工智能 作者:brucexia 时间:2025-12-16 15:46:35 0 删除 编辑

AI 智能体的感知技术是其与外部世界交互的“感官系统”,旨在将物理世界的信号转换为机器可以处理的数字信息。理解技术是AI 智能体的“大脑”,负责将感知到的信息转换为语义理解和逻辑推理能力。

多模态感知

多模态感知是指AI 系统能够同时处理和整合来自多种不同来源(模态)的输入数据,如文本、图像、音频、视频等。这种能力使AI 智能体能够更全面地理解环境,作出更准确的决策。

1. 多模态感知架构层次

(1 )感知层:负责收集原始数据,例如摄像头捕捉图像、麦克风录制声音等。

(2 )表示层:将不同类型的原始数据转换为统一的特征向量或其他形式的内部表示。

(3 )融合层:对来自不同模态的数据进行融合,生成一个综合的理解或决策。

(4 )决策层:根据融合后的结果制定行动策略或输出最终答案。

(5 )反馈机制:评估系统的性能,调整参数以优化未来的表现。

2. 多模态感知的关键技术

(1 )数据预处理:不同模态的数据需要进行相应的预处理操作,如图像缩放、文本分词等,以确保数据格式的统一性和模型的输入要求。

(2 )特征提取:针对每种模态的数据,选择合适的特征提取方法。例如,卷积神经网络(CNN )用于图像特征提取,循环神经网络(RNN )用于文本特征提取。

(3 )模态融合:模态融合是多模态模型的核心环节,常见的方法包括特征拼接、加权融合、注意力机制等。

(4 )模型训练与优化:在训练过程中,需要选择合适的损失函数和优化算法,以及调整模型的超参数,以达到最佳的分类效果。

【示例 3.13 】 以下是一个简化的多模态感知系统实现,融合图像、文本和传感器数据。

import numpy as np

import torch

import torch.nn as nn

import torchvision.models as models

from transformers import BertModel, BertTokenizer

 

class MultiModalPerception(nn.Module):

    def __ init __ (self):

        super(MultiModalPerception, self). __ init __ ()

 

        # 图像特征提取 ( 使用预训练的 ResNet)

        self.image _ encoder = models.resnet50(weights=models.ResNet50 _ Weights.IMAGENET1K _ V1)

        self.image _ encoder = nn.Sequential(*list(self.image _ encoder.children())[:-1])

 

        # 文本特征提取 ( 使用预训练的 BERT) —— 改为在线加载

        self.text _ encoder = BertModel.from _ pretrained('bert-base-uncased')

        self.tokenizer = BertTokenizer.from _ pretrained('bert-base-uncased')

 

        # 冻结预训练模型的参数(可选)

        for param in self.image _ encoder.parameters():

            param.requires _ grad = False

        for param in self.text _ encoder.parameters():

            param.requires _ grad = False

 

        # 传感器特征提取 (LiDAR 和 IMU)

        self.sensor _ encoder = nn.Sequential(

            nn.Linear(10, 128),  # 假设传感器数据维度为 10

            nn.ReLU(),

            nn.Linear(128, 256)

        )

 

        # 模态融合层

        self.fusion _ layer = nn.Sequential(

            nn.Linear(2048 + 768 + 256, 1024),  # ResNet50(2048) + BERT(768) + 传感器 (256)

            nn.ReLU(),

            nn.Linear(1024, 512),

            nn.ReLU()

        )

 

        # 分类头

        self.classifier = nn.Linear(512, 10)  # 假设有 10 个类别

 

    def forward(self, image, text _ inputs, sensor):

        # 图像特征提取

        image _ features = self.image _ encoder(image)

        image _ features = image _ features.view(image _ features.size(0), -1)

 

        # 文本特征提取 - 使用预先处理好的输入

        text _ outputs = self.text _ encoder(**text _ inputs)

        text _ features = text _ outputs.last _ hidden _ state[:, 0, :]  # 取 [CLS] token

 

        # 传感器特征提取

        sensor _ features = self.sensor _ encoder(sensor)

 

        # 特征融合

        fused _ features = torch.cat([image _ features, text _ features, sensor _ features], dim=1)

        fused _ features = self.fusion _ layer(fused _ features)

 

        # 分类

        output = self.classifier(fused _ features)

 

        return output

 

# 示例使用

if __ name __ == " __ main __ ":

    # 设置设备

    device = torch.device("cuda" if torch.cuda.is _ available() else "cpu")

    print(f"Using device: {device}")

 

    # 模拟输入数据

    batch _ size = 2

    image _ data = torch.randn(batch _ size, 3, 224, 224).to(device)  # 图像数据

 

    # 文本数据需要先进行 tokenize

    text _ data = ["This is a sample text.", "Another example sentence."]  # 文本数据

    # ✅ 使用在线加载 tokenizer

    tokenizer = BertTokenizer.from _ pretrained('bert-base-uncased')

    text _ inputs = tokenizer(

        text _ data,

        return _ tensors='pt',

        padding=True,

        truncation=True,

        max _ length=128  # 设置最大长度

    ).to(device)

 

    sensor _ data = torch.randn(batch _ size, 10).to(device)  # 传感器数据

 

    # 初始化模型

    model = MultiModalPerception().to(device)

 

    # 前向传播

    output = model(image _ data, text _ inputs, sensor _ data)

    print("Output shape:", output.shape)

    print("Output:", output)

上面代码定义了一个多模态感知模型MultiModalPerception ,该模型结合了图像、文本和传感器数据来进行分类。代码中包含示例使用部分,初始化了模型并传入了模拟的数据进行前向传播。

根据代码逻辑,模型的分类头输出一个形状为(batch_size, num_classes) 的张量,batch_size 被设置为2 ,num_classes 为10 (因为有10 个类别)。因此,运行结果的形状应该是(2, 10) ,表示两个样本对于10 个类别的预测得分。

运行代码,输出如下:

Using device: cuda

Output shape: torch.Size([2, 10])

Output: tensor([[-0.1234,  0.5678, ..., 0.9012],

                [ 0.2345, -0.6789, ..., 0.3456]], device='cuda:0', grad _ fn=<AddmmBackward0>)

这表示模型为两个输入样本生成了10 个类别的预测得分。

代码运行说明:

l   首=次运行会自动下载bert-base-uncased 模型和tokenizer (约400MB ),需连网。

l   如果你想离线运行,请先在有网环境下运行一次,Hugging Face 会缓存模型到本地(通常在 ~/.cache/huggingface/transformers/ ),之后可用local_files_only=True 离线加载。

l   若你确实想使用本地模型,请先下载(base 环境下):

wget https://huggingface.co/bert-base-uncased  # 不推荐,应使用 git clone

更推荐(base 环境下):

git lfs install

git clone https://huggingface.co/bert-base-uncased

然后确保路径./bert-base-uncased 存在且包含config.json, pytorch_model.bin, vocab.txt 等文件。

环境建模

AI 智能体环境建模是指AI 智能体通过感知、融合多源信息,构建对周围物理或虚拟环境的结构化、可理解模型的过程,其核心目标是让智能体“理解”环境的几何结构、语义信息及动态变化规律,从而支持决策与交互。本小节将从核心技术(SLAM 与知识图谱)及典型应用(自动驾驶高精地图更新、虚拟环境动态建模)展开说明。

1. SLAM (实时环境几何建模)

1 )基本原理

SLAM 是一种让机器人在未知环境中移动时,一边估计自身位置和姿态,一边构建环境地图的技术。它主要依赖于传感器数据,如激光雷达(LiDAR )、摄像头、IMU (惯性测量单元)等。例如,激光雷达可以发射激光束并测量反射光的时间来获取周围物体的距离信息。通过这些传感器数据,机器人可以逐步构建出环境的几何地图。

SLAM 算法的核心是解决数据关联问题和状态估计问题。数据关联是指将传感器观测到的特征点与地图中已存在的特征点进行匹配,以确定机器人是否回到了之前访问过的位置。状态估计则是根据传感器数据和运动模型,计算机器人当前的位置和地图的更新。

2 )主要算法类型

(1 )基于滤波器的SLAM 算法:如扩展卡尔曼滤波器(EKF-SLAM )。它通过递归估计机器人状态和地图特征点的位置。EKF-SLAM 将机器人位置和地图特征点作为状态向量,利用卡尔曼滤波器的更新步骤来处理传感器观测和运动模型预测。不过,这种算法在处理大量特征点时计算复杂度较高,且假设误差服从高斯分布,有一定的局限性。

(2 )基于图优化的SLAM 算法:如g2o (graph optimization )。它将SLAM 问题建模为一个图优化问题。图中的节点代表机器人的位姿和地图中的路标(特征点),边代表节点之间的约束关系。通过最小化边的误差来优化整个图,从而得到最优的机器人轨迹和地图。这种算法能够很好地处理大规模数据,并且可以利用非线性优化方法来提高地图的精度。

(3 )直接法和半直接法SLAM 算法:直接法(如DSO-Direct Sparse Odometry )直接利用图像像素强度信息来估计相机运动和构建地图。它不需要提取特征点,而是通过比较图像块的光度误差来优化相机位姿。半直接法(如LSD-SLAM )则结合了特征点法和直接法的优点,既利用特征点进行粗略定位,又利用像素强度信息进行精细优化。

3 )优势与局限性

其优势在于能够实时构建地图并定位机器人,适用于动态环境和未知环境。例如,在自动驾驶场景中,车辆可以利用SLAM 技术在没有高精地图的情况下,实时感知周围道路环境并确定自身位置。然而,SLAM 也有局限性。例如,当环境中存在动态物体(如行人、车辆)或者传感器受到干扰(如强光、浓雾等恶劣天气条件)时,SLAM 算法的性能可能会下降。另外,SLAM 构建的地图主要是几何地图,缺乏对环境语义信息的描述。

【示例 3.14 】SLAM 基础模块。

import numpy as np

from typing import Tuple, List

 

class SLAMCore:

    def __ init __ (self, sensor _ range: float = 10.0):

        self.landmarks = {}  # 地标点集合 {id: (x, y)}

        self.robot _ pose = np.zeros(3)  # [x, y, theta]

        self.sensor _ range = sensor _ range

       

    def update _ pose(self, odometry: np.ndarray) -> None:

        """ 根据里程计更新机器人位姿 """

        self.robot _ pose += odometry

       

    def observe _ landmarks(self, observations: List[Tuple[int, float, float]]) -> None:

        """ 处理传感器观测数据并更新地图 """

        for landmark _ id, distance, angle in observations:

            # 计算地标全局坐标

            global _ angle = self.robot _ pose[2] + angle

            landmark _ pos = (

                self.robot _ pose[0] + distance * np.cos(global _ angle),

                self.robot _ pose[1] + distance * np.sin(global _ angle)

            )

           

            # 更新或添加地标

            if landmark _ id in self.landmarks:

                # 简单平均更新(实际 SLAM 会使用更复杂的优化算法)

                old _ pos = self.landmarks[landmark _ id]

                self.landmarks[landmark _ id] = (

                    (old _ pos[0] + landmark _ pos[0]) / 2,

                    (old _ pos[1] + landmark _ pos[1]) / 2

                )

            else:

                self.landmarks[landmark _ id] = landmark _ pos

               

    def get _ current _ map(self) -> dict:

        """ 获取当前地图和机器人位姿 """

        return {

            'robot _ pose': self.robot _ pose.tolist(),

            'landmarks': self.landmarks

        }

 

# 测试用例

if __ name __ == " __ main __ ":

    slam = SLAMCore()

   

    # 模拟机器人移动和观测

    slam.update _ pose(np.array([1.0, 0.5, np.pi/6]))  # 移动并转向

    slam.observe _ landmarks([

        (1, 5.0, 0.1),  # 地标 1: 距离 5m ,角度 0.1 弧度

        (2, 3.0, -0.2)  # 地标 2: 距离 3m ,角度 -0.2 弧度

    ])

   

    current _ map = slam.get _ current _ map()

    print(" 当前地图状态 :", current _ map)

运行代码,输出如下:

当前地图状态 : {'robot _ pose': [1.0, 0.5, 0.5235987755982988], 'landmarks': {1: (5.0589108

78393433, 3.419801788008811), 2: (3.8442916576243746, 1.453941804497731)}}

关键技术点:

l   SLAM 核心逻辑:同时维护机器人位姿和环境地标。

l   传感器融合:将局部观测转换为全局坐标。

l   复杂度: O( n) 观测处理, n 为观测到的地标数量。

2. 知识图谱(结构化环境知识)

1 )基本概念

知识图谱是一种结构化的语义知识库,它以图的形式表示知识,图中的节点表示实体(如物体、地点、事件等),边表示实体之间的关系。在环境建模中,知识图谱可以用来表示环境中的语义信息。例如,在一个室内环境中,节点可以是“桌子”“椅子”“门”等物体,边可以表示“桌子在椅子旁边”“门通向客厅”等关系。

知识图谱的构建通常基于自然语言处理(NLP )技术,从文本数据(如环境描述文本、用户指令等)中抽取实体和关系。知识图谱也可以通过人工标注和机器学习相结合的方式构建。例如,通过机器学习算法从大量的室内场景图像和对应的文本描述中学习物体的类别和它们之间的空间关系。

2 )应用优势

(1 )知识图谱能够提供丰富的语义信息,有助于智能体更好地理解环境。例如,在虚拟环境中,通过知识图谱可以为虚拟角色提供对虚拟场景中物体用途和相互关系的理解,从而让虚拟角色的行为更加符合逻辑。例如,虚拟角色知道“水杯是用来喝水的,而且应该放在桌子上”。

(2 )知识图谱还可以用于环境的推理和规划。例如,如果知识图谱中表示“厨房中有冰箱,冰箱里有食物”,智能体就可以推理出在厨房可以找到食物,从而规划出前往厨房获取食物的路径。此外,知识图谱具有可扩展性,可以方便地添加新的实体和关系,以适应环境的变化。

3 )局限性

构建知识图谱需要大量的数据和复杂的处理过程。从文本或图像中准确抽取语义信息是一个挑战,尤其是当环境描述模糊或者存在歧义时。例如,对于“一个红色的物体在角落里”这样的描述,很难准确判断物体的类别和具体位置。另外,知识图谱的更新也需要考虑环境动态变化,如果环境中的物体位置或关系发生变化,知识图谱需要及时更新,否则会导致智能体的决策失误。

【示例 3.15 】 知识图谱环境建模模块。

from typing import Dict, List, Optional

 

class EnvironmentKnowledgeGraph:

    def __ init __ (self):

        self.entities = {}  # 实体字典 {id: {type: str, attributes: dict}}

        self.relations = []  # 关系列表 [(source _ id, relation _ type, target _ id)]

       

    def add _ entity(self, entity _ id: str, entity _ type: str, attributes: Optional[Dict] = None) -> None:

        """ 添加或更新环境实体 """

        if attributes is None:

            attributes = {}

        self.entities[entity _ id] = {

            'type': entity _ type,

            'attributes': attributes

        }

       

    def add _ relation(self, source _ id: str, relation _ type: str, target _ id: str) -> None:

        """ 添加实体间关系 """

        if source _ id in self.entities and target _ id in self.entities:

            self.relations.append((source _ id, relation _ type, target _ id))

           

    def query _ environment(self, entity _ type: Optional[str] = None,

                         relation _ type: Optional[str] = None) -> List[Dict]:

        """ 查询环境知识 """

        results = []

       

        # 实体查询

        if entity _ type:

            for eid, data in self.entities.items():

                if data['type'] == entity _ type:

                    results.append({'entity _ id': eid, **data})

       

        # 关系查询

        if relation _ type:

            for src, rel, tgt in self.relations:

                if rel == relation _ type:

                    results.append({

                        'source': self.entities[src],

                        'relation': rel,

                        'target': self.entities[tgt]

                    })

                   

        return results

 

# 测试用例

if __ name __ == " __ main __ ":

    kg = EnvironmentKnowledgeGraph()

   

    # 构建高精地图知识图谱

    kg.add _ entity("road _ 001", "RoadSegment", {"length": 50.0, "width": 3.5})

    kg.add _ entity("sign _ 101", "TrafficSign", {"type": "Stop", "height": 2.1})

    kg.add _ relation("sign _ 101", "located _ on", "road _ 001")

   

    # 查询测试

    print(" 所有道路段 :", kg.query _ environment(entity _ type="RoadSegment"))

    print(" 所有位置关系 :", kg.query _ environment(relation _ type="located _ on"))

运行代码,输出如下:

所有道路段 : [{'entity _ id': 'road _ 001', 'type': 'RoadSegment', 'attributes': {'length': 50.0, 'width': 3.5}}]

所有位置关系 : [{'source': {'type': 'TrafficSign', 'attributes': {'type': 'Stop', 'height': 2.1}}, 'relation': 'located _ on', 'target': {'type': 'RoadSegment', 'attributes': {'length': 50.0, 'width': 3.5}}}]

关键技术点:

l   结构化知识表示:实体− 属性− 关系的三元组存储。

l   灵活查询:支持按类型和关系检索。

l   可扩展性:易于添加新的实体类型和关系。



本文节选自《AI Agent智能体开发实践》,获出版社和作者授权发布。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/18841117/viewspace-3105363/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2022-02-14

  • 博文量
    219
  • 访问量
    196423