用强化学习(PPO)训练一个 AI 智能体,让它学会 打开“记事本”并输入一段文字。 (代码未测试)
NotepadEnv。
·
阿尔伯塔大学【中英⚡强化学习|Reinforcement Learning Specialization】-misuseds-稍后再看-哔哩哔哩视频
既然视觉方面可以不用标签像是dino,那为什么强化学习不能没有价值函数呢
二、st = s
是什么?
这里的 St=sSt=s 表示“在时刻 tt,系统处于状态 ss”。这是一个条件,用来定义状态价值函数——即“当我们在状态 ss 时,未来能获得的期望回报是多少”。
这并不是一个贝叶斯公式,而是一个条件期望的表达方式。
太好了!我们来做一个最小但完整的可运行示例:
用强化学习(PPO)训练一个 AI 智能体,让它学会 打开“记事本”并输入一段文字。
🎯 任务目标
- 环境:Windows 电脑(Mac/Linux 稍后说明)
- 动作:按键操作(如
Win
键、输入文本、回车) - 状态:当前屏幕截图(用于观察是否打开记事本)
- 奖励:
- 成功打开记事本:+1
- 输入文字成功:+2
- 总奖励最大为 3
我们将使用:
pyautogui
:执行鼠标键盘操作PPO
算法(来自stable-baselines3
)- 截图作为状态输入
- CNN 编码器处理图像
📦 一、安装依赖
bash
编辑
pip install stable-baselines3[extra] pygame pyautogui opencv-python numpy
💡
stable-baselines3[extra]
包含了CnnPolicy
支持(用于图像输入)
🧩 二、自定义环境(NotepadEnv
)
python
编辑
import gym
from gym import spaces
import pyautogui
import cv2
import numpy as np
import time
import os
class NotepadEnv(gym.Env):
def __init__(self):
super(NotepadEnv, self).__init__()
# 动作空间:0=按Win, 1=输入notepad, 2=按Enter, 3=输入"Hello", 4=关闭
self.action_space = spaces.Discrete(5)
# 状态空间:截图 (128x72x3)
self.observation_space = spaces.Box(
low=0, high=255, shape=(72, 128, 3), dtype=np.uint8
)
self.step_count = 0
self.max_steps = 10
self.notepad_opened = False
self.text_entered = False
def get_obs(self):
"""获取当前屏幕截图并缩放"""
screenshot = pyautogui.screenshot()
frame = np.array(screenshot)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
frame = cv2.resize(frame, (128, 72)) # 小尺寸加快训练
return frame
def reset(self):
self.step_count = 0
self.notepad_opened = False
self.text_entered = False
return self.get_obs()
def step(self, action):
reward = 0
done = False
info = {}
# 执行动作
if action == 0:
pyautogui.press('win')
elif action == 1:
pyautogui.write('notepad')
elif action == 2:
pyautogui.press('enter')
time.sleep(1) # 等待记事本打开
if self.is_notepad_running():
self.notepad_opened = True
reward += 1.0
elif action == 3:
if self.notepad_opened:
pyautogui.write('Hello from RL!', interval=0.1)
self.text_entered = True
reward += 2.0
elif action == 4:
if self.notepad_opened:
pyautogui.hotkey('alt', 'f4')
time.sleep(0.5)
pyautogui.press('n') # 不保存
done = True
self.step_count += 1
if self.step_count >= self.max_steps:
done = True
# 最终奖励
if self.text_entered:
reward += 3.0 # 额外完成奖励
obs = self.get_obs()
return obs, reward, done, info
def is_notepad_running(self):
"""简单判断:检查是否有“记事本”标题的窗口"""
try:
import pygetwindow as gw
windows = gw.getWindowsWithTitle("记事本")
return len(windows) > 0
except:
return False
⚠️ 如果你没有
pygetwindow
,可以跳过检查,或用pip install pygetwindow
🚀 三、训练 PPO 模型
python
编辑
from stable_baselines3 import PPO
# 创建环境
env = NotepadEnv()
# 定义模型(自动使用 CNN 处理图像输入)
model = PPO(
"CnnPolicy",
env,
verbose=1,
tensorboard_log="./ppo_notepad_tensorboard/",
learning_rate=0.0003,
n_steps=2048,
batch_size=64,
n_epochs=10,
gamma=0.99,
ent_coef=0.01,
)
print("开始训练... 按 Ctrl+C 可中断")
try:
model.learn(total_timesteps=10_000) # 训练约 10 轮
model.save("ppo_notepad")
print("训练完成!模型已保存为 'ppo_notepad'")
except KeyboardInterrupt:
print("训练中断")
▶️ 四、测试模型
python
编辑
# 加载模型并测试
model = PPO.load("ppo_notepad")
obs = env.reset()
for _ in range(10):
action, _states = model.predict(obs, deterministic=True)
obs, reward, done, info = env.step(int(action))
if done:
break
print("任务执行完毕!")
🖥️ 五、Mac/Linux 用户怎么办?
Mac:
- 将
notepad
改为TextEdit
- 使用
pyautogui.hotkey('command', 'space')
打开 Spotlight - 示例动作:
python
编辑
pyautogui.write('TextEdit') pyautogui.press('enter')
Linux(Ubuntu):
- 使用
gnome-terminal -e 'gedit'
或直接运行gedit
- 或者:
python
编辑
pyautogui.write('gedit') pyautogui.press('enter')
🎮 六、运行效果预期
训练几次后,AI 会学会:
- 按
Win
键 - 输入
notepad
- 按
Enter
打开记事本 - 输入
Hello from RL!
- 关闭(可选)
最终获得高奖励。
🛡️ 安全提示
- 建议在虚拟机中运行,防止误操作关机或删除文件
- 不要在重要电脑上直接测试
- 可以加个确认框:
python
编辑
input("按回车继续训练...")
📈 七、如何改进?
方向 | 方法 |
---|---|
更快收敛 | 使用模仿学习预训练(先录一段正确操作) |
更强泛化 | 多任务:打开不同软件 |
更高抽象 | 结合 LLM:把“写日记”转为动作序列 |
更安全 | 在沙箱中运行 |
📦 下一步建议
你可以把这个项目扩展为:
- AI 办公助手:自动整理 Excel、发邮件
- 游戏脚本:自动完成重复任务
- 测试自动化:UI 自动化测试
如果你想要:
- 添加 GUI 界面(用
pygame
显示状态) - 支持鼠标点击坐标
- 使用 LLM 生成动作建议
- 训练一个“通用电脑操作 Agent”
我可以继续帮你构建!
现在就可以试试运行上面的代码,有任何报错或问题,欢迎贴出来,我来帮你调试 💻
更多推荐
所有评论(0)