编辑
2025-11-18
自动化方案
00

目录

简单方案
提示词:
回复:
🧠 核心思想:模仿学习
📦 数据采集:构建“状态-动作”数据集
⚙️ 特征工程:将YOLO输出转化为固定长度特征向量
🧩 决策模型:搭建神经网络
🚀 模型训练与部署
💡 进阶思考

简单方案

提示词:

我们初期可以从规则开始,那么是否可以通过yolo输出的各个目标类型和位置预测信息,作为模型的输入,并将当前从人的角度应该进行的方式比如攻击、防御、移动作为输出标签,进行模型搭建进行训练

回复:

您提出的这个思路非常棒!这确实是实现游戏AI智能决策的一个非常经典且高效的入门方法,在学术上被称为行为克隆模仿学习。您已经抓住了从“感知”到“决策”的关键:将YOLO的检测结果作为状态特征,将人类专家的操作作为学习目标

下面,我用一个清晰的流程和代码示例,为您展示如何将这一想法落地。

🧠 核心思想:模仿学习

您的想法本质是让AI模仿人类专家的行为。整个过程可以分解为以下几个关键步骤,其核心流程如下:

flowchart TD
A[人类专家演示] --> B[数据采集<br>记录画面与对应操作]
B --> C[特征提取<br>使用YOLO解析画面生成状态特征]
C --> D[标签生成<br>将人类操作编码为动作标签]
D --> E{模型训练<br>训练决策模型拟合专家行为}
E --> F[智能体部署<br>新画面由YOLO+决策模型自动决策]
F --> G[执行动作]
G --> H[游戏环境]
H -- 新画面 --> A
H -- 新画面 --> F

下面,我们详细拆解图中的每一个环节。

📦 数据采集:构建“状态-动作”数据集

首先,我们需要记录人类高手玩游戏的数据。每一条数据都是一个 “状态-动作”对

  • 状态: 由YOLO分析游戏画面后得到的一系列结构化信息。
  • 动作: 人类玩家在当时刻所采取的操作(如按下了哪个键)。

示例代码:记录数据点

python
import cv2 from ultralytics import YOLO import keyboard # 用于监听按键 import pandas as pd from collections import deque # 初始化YOLO模型(假设已训练好) detection_model = YOLO('best.pt') # 创建一个列表来存储数据 data_buffer = [] # 假设我们关心的目标类别和按键 interest_classes = ['enemy', 'health_pack', 'boss'] # 您自定义的类别 action_keys = ['w', 'a', 's', 'd', 'j', 'k'] # 例如: 上下左右、攻击、跳跃 # 开始录制数据 print("开始录制专家数据... 按 'q' 停止录制。") cap = cv2.VideoCapture(0) # 或获取游戏窗口 while True: ret, frame = cap.read() if not ret: break # 1. 状态获取:使用YOLO分析当前帧 results = detection_model(frame)[0] current_state = [] # 提取关键信息,例如:最近敌人的位置、是否存在血包等 for box in results.boxes: class_id = int(box.cls) class_name = results.names[class_id] if class_name in interest_classes: # 获取边界框坐标(归一化) x_center, y_center, width, height = box.xywhn[0].tolist() # 将信息加入当前状态向量 current_state.extend([class_id, x_center, y_center, width, height]) # 2. 动作标签获取:监听当前时刻的按键 current_action = 0 # 默认动作为“无操作” for i, key in enumerate(action_keys): if keyboard.is_pressed(key): # 检测某个键是否被按下 current_action = i + 1 # 动作标签,例如1代表'w',2代表'a'... break # 假设同一时刻只执行一个主要动作 # 3. 将“状态-动作”对存入缓冲区 # 注意:状态可能长度不固定,需要处理 data_buffer.append({'state': current_state, 'action': current_action}) cv2.imshow('Recoding', frame) if cv2.waitKey(1) & 0xFF == ord'q'): break cap.release() cv2.destroyAllWindows() # 将数据保存到CSV文件(需要将状态列表转换为固定格式) df = pd.DataFrame(data_buffer) df.to_csv('expert_data.csv', index=False) print(f“录制完成,共保存 {len(data_buffer)} 条数据。”)

⚙️ 特征工程:将YOLO输出转化为固定长度特征向量

YOLO每帧检测到的目标数量不固定,但神经网络需要固定长度的输入。我们需要设计一个特征提取器,将YOLO的原始输出转化为有意义的、固定维度的特征向量。下表展示了几种常见的特征设计方法:

特征设计方法核心思想示例特征(假设游戏为2D射击)适用场景
关键目标统计关注对决策最重要的单一目标1. 最近敌人的相对方位(x方向差值,y方向差值)
2. 自身与敌人的距离
3. 最近敌人的类型(One-Hot编码)
动作决策强烈依赖于单一主要目标(如格斗、射击游戏)
全局统计摘要统计画面中各类目标的整体情况1. 敌人总数
2. 平均敌人距离
3. 血包是否存在(0或1)
4. 最近血包的距离和方位
需要宏观态势感知的游戏(如MOBA、RTS)
空间网格划分将屏幕划分为网格,统计每个网格内的目标将屏幕分为3x3网格,统计每个格子中是否存在敌人,生成一个9维的0/1向量。决策与目标的屏幕位置强相关(如需要绕行、占据特定地形的游戏)

示例代码:特征提取器

python
import numpy as np def extract_features(yolo_detection_results, frame_width, frame_height): """ 从YOLO结果中提取固定长度的特征向量 """ features = [] boxes = yolo_detection_results.boxes if boxes is None: # 如果没有检测到任何目标,返回零向量 return np.zeros(5) # 根据特征维度调整 # 假设我们采用“关键目标统计”法:只关心最近的敌人 enemy_boxes = [] for box in boxes: class_id = int(box.cls) if class_id == 0: # 假设 class_id=0 是 'enemy' # 获取框的中心点坐标 x_center, y_center = box.xywhn[0][0].item(), box.xywhn[0][1].item() # 计算到屏幕中心(玩家位置)的距离 distance = np.sqrt((x_center - 0.5)**2 + (y_center - 0.5)**2) enemy_boxes.append((distance, x_center, y_center)) if enemy_boxes: # 找到最近的敌人 enemy_boxes.sort(key=lambda x: x[0]) closest_dist, closest_x, closest_y = enemy_boxes[0] # 特征:最近敌人的相对位置和距离 features.extend([closest_x - 0.5, closest_y - 0.5, closest_dist]) else: # 没有敌人,用零填充 features.extend([0, 0, 999]) # 可以继续添加其他特征,如自身血量(需从游戏内存或UI识别获取) # features.append(current_health) return np.array(features)

🧩 决策模型:搭建神经网络

接下来,我们搭建一个简单的神经网络,学习从“状态特征”到“动作”的映射。这是一个典型的分类问题

示例代码:决策模型

python
import torch import torch.nn as nn import torch.optim as optim class DecisionNN(nn.Module): """ 简单的决策神经网络 输入:游戏状态特征(固定长度) 输出:执行每个动作的概率 """ def __init__(self, input_size, output_size): super(DecisionNN, self).__init__() self.network = nn.Sequential( nn.Linear(input_size, 128), nn.ReLU(), nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, output_size) ) def forward(self, x): return self.network(x) # 假设特征向量长度为3,动作空间为6(5个动作+1个“无操作”) INPUT_SIZE = 3 OUTPUT_SIZE = len(['no_op', 'up', 'left', 'down', 'right', 'attack']) # 6 policy_model = DecisionNN(INPUT_SIZE, OUTPUT_SIZE) criterion = nn.CrossEntropyLoss() # 交叉熵损失函数,用于分类 optimizer = optim.Adam(policy_model.parameters(), lr=0.001)

🚀 模型训练与部署

最后,我们将所有环节串联起来,进行模型训练和部署。

示例代码:训练与部署循环

python
# 训练循环 df = pd.read_csv('expert_data.csv') # ... (需要将之前保存的state字符串解析为特征向量) for epoch in range(100): for i, row in df.iterrows(): # 假设已经将特征向量处理好 state = torch.FloatTensor(eval(row['state'])) # 将字符串列表转为Tensor action_label = torch.LongTensor([row['action']]) # 真实动作标签 optimizer.zero_grad() action_scores = policy_model(state) # 模型预测 loss = criterion(action_scores, action_label) # 计算损失 loss.backward() # 反向传播 optimizer.step() # 更新权重 # 部署智能体 while True: frame = get_game_frame() results = detection_model(frame) state_features = extract_features(results[0], frame.width, frame.height) with torch.no_grad(): action_probs = torch.softmax(policy_model(torch.FloatTensor(state_features)), dim=0) chosen_action = torch.argmax(action_probs).item() # 执行动作 execute_action(action_keys[chosen_action])

💡 进阶思考

  1. 时序信息:当前的模型只根据单帧画面做决策,缺乏“记忆”。对于需要连续操作的游戏(如躲避子弹),可以考虑使用LSTMGRU等循环神经网络,输入连续几帧的状态序列。
  2. 模仿学习的局限:智能体的上限不会超过它所模仿的人类专家。如果要超越人类水平,可以在模仿学习的基础上,引入强化学习,让AI通过自我对弈不断进化。
  3. 奖励函数设计:如果走向强化学习,核心是设计一个合理的奖励函数,例如:击中敌人+10分,自身受伤-5分,击败Boss+100分。AI的目标就是最大化累积奖励。

您提出的路径是完全可行的,是连接计算机视觉(CV)与决策智能(AI)非常漂亮的桥梁。希望这个详细的方案能帮助您启动项目!

本文作者:君逍遥

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!