共计 2014 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点:为什么需要自建数据集?
现有公开数据集(如 Rico、ReDroid)普遍存在三个问题:

- 场景单一性:多数仅包含基础操作(点击、滑动),缺乏支付验证、多应用跳转等复杂链路
- 设备指纹缺失:未记录屏幕分辨率、ROM 版本等关键元数据,导致模型在真机部署时适配失败
- 时序离散化:人工标注的动作间隔与实际操作存在差异,影响长序列任务的预测精度
通过自建数据集,我们可以捕获真实用户操作流(包括误操作和修正行为),这对训练鲁棒的自动化模型至关重要。
技术方案设计
数据采集架构
flowchart TD
A[设备连接层] -->|ADB/WiFi 调试 | B(行为捕获层)
B --> C{数据持久化层}
C --> D[(MongoDB)]
C --> E[Parquet 文件]
- 设备连接层:通过 ADB over TCP 实现无线连接(避免 USB 线缆干扰操作)
- 行为捕获层 :监听
getevent原始输入流,并关联dumpsys window获取 Activity 上下文 - 持久化层:采用增量写入模式,每 1000 条操作记录为一个 Parquet 分片
关键代码实现
from retrying import retry
import subprocess
@retry(stop_max_attempt_number=3, wait_fixed=2000)
def capture_touch_event(device_id: str) -> dict:
""" 捕获单次触摸事件(包含压力值和接触面积)Args:
device_id: 通过 `adb devices` 获取的设备标识
Returns:
{'x': 720, 'y': 1280, 'pressure': 56, 'area': 12}
"""
raw_event = subprocess.check_output(f'adb -s {device_id} shell getevent -lt /dev/input/event2',
timeout=0.5
).decode()
# 解析十六进制原始数据(示例代码需补充校验逻辑)return parse_event(raw_event)
核心实现细节
数据清洗流水线
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
def preprocess_sequence(df: pd.DataFrame) -> pd.DataFrame:
""" 将操作序列转化为模型可处理的向量
关键步骤:1. 计算操作之间的时间差(delta_t)2. 对坐标进行屏幕分辨率归一化
3. 生成滑动窗口特征(窗口大小 =5)"""
scaler = MinMaxScaler()
df[['norm_x', 'norm_y']] = scaler.fit_transform(df[['x', 'y']])
# 生成序列特征
df['delta_t'] = df['timestamp'].diff().fillna(0)
return df.rolling(window=5).mean().dropna()
模型适配技巧
Prompt 模板设计:
指令:完成美团外卖下单
上下文:当前位于购物车页,已选 2 份黄焖鸡米饭
动作序列:1. [tap] x=720 y=1800 # 点击去结算
2. [wait] 2000ms # 等待页面加载
3. [swipe] from (300,1600) to (300,1000) # 滑动查看优惠
Loss 调整:在标准交叉熵损失中加入时序连续性惩罚项
import torch
def custom_loss(y_pred, y_true, time_penalty=0.3):
ce_loss = F.cross_entropy(y_pred, y_true)
# 惩罚相邻动作预测结果突变
time_loss = torch.mean(torch.abs(y_pred[1:] - y_pred[:-1]))
return ce_loss + time_penalty * time_loss
生产环境验证
| 指标 | 微调前 | 微调后 |
|---|---|---|
| OPPO 任务完成率 | 62% | 89% |
| 小米冷启动时间 | 1.8s | 1.2s |
| 内存占用峰值 | 1.4GB | 980MB |
优化手段:
1. 使用 TensorRT 转换模型,优化 GPU 内存管理
2. 预加载常用动作的 embedding 向量
3. 实现动作预测缓存机制
避坑指南
跨厂商 ROM 兼容性
- 问题现象:相同坐标在不同厂商设备上触发不同控件
- 解决方案:
- 在数据采集阶段记录
android_id和 ROM 版本 - 训练时添加设备类型作为额外特征
预防过拟合
- 轨迹扰动:对操作坐标添加±5 像素的随机偏移
- 时序抖动:在动作间隔中插入±10% 的时间噪声
- 屏幕翻转:对横向滑动操作生成镜像样本
开放性问题
- 当业务场景频繁变动时,如何设计持续数据收集机制?
- 在有限标注资源下,哪些动作应该优先保证标注质量?
- 是否需要为不同价位的手机训练独立模型?
通过这套方法,我们成功将外卖 App 自动下单任务的调试周期从 3 天缩短到 4 小时。关键在于:真实数据比完美数据更重要,快速迭代胜过一次性的复杂设计。
正文完
