出门散步15分钟,我让笔记本上的本地AI先猜我会遇到什么,回来再对答案。模型没输,我输了——输给了自己住了很久却没走透的小区。
这是Hacktoberfest开源AI挑战第一周的作品,主题叫"Touch Grass"。我的日常是健身房加书桌,久到连自己所在的街区都只是路过,从没真正看过。于是我给散步找了个理由:每次出门前,我和本地模型Gemma 3 4B各自预测这趟会遇到什么,走完回来比谁更接近现实。(我没有每次都严格遵守这个顺序,下面会讲。)
项目叫Ground Truth Walks。"Ground truth"是机器学习里"真实答案"的意思,我走到地面上,去拿属于我的那份真实答案。
六项固定,惊喜不算分
每次预测只覆盖六件事:路过的摩托车、看到的狗、听到的不同鸟叫、遇到在卖东西的人、跟我打招呼的人、有没有听到发电机。
工具是个小巧的Rust命令行程序。它先存下我的预测,再向Gemma提问,走完才揭晓模型的数字,最后给所有人打分。
为了让实验站得住,我提前定了几条规矩:
- 六项内容每次都不变,意外情况(山羊、母鸡)只写进备注,永远不计分
- 我的预测在模型运行前就已存盘
- 命令行在打分前不显示模型的预测结果
- 三份模型预测全部生成前,不能录入现实结果
- 每次模型调用都是独立请求,温度0,随机种子42
模型跑在CPU上,没有GPU,不联网。提问分三个上下文层级:L1是通用提问,L2加上城市,L3再描述地点、日期和时间。回答的JSON结构每次都一样,也不告诉模型自己在参与实验。
在我的机器上,相同的L1和L2提问,在每次记录的散步里返回了完全相同的输出。CPU上跑得慢,因为三次预测要依次进行。
我把自己定的规矩破了个遍
一个关于离开屏幕的实验,最后变成了我能用多少种方式打破自己规矩的实验。
试走那次就不干净。我在已经知道看到了什么之后才跑Gemma,还用了默认的随机性。更早测试想法时,我重复同一个提问,它先说15辆摩托车,又说20辆,再说18辆。之后我固定了设置,试走的数据被排除在结果之外。
鸟叫这一项我数错了东西。字段要求的是"不同的鸟叫声",但001次散步我数的是看到的每一只鸟:20。我能听到很多种不同的鸟叫,却没数出确切数量。填20等于悄悄改了定义,所以那次散步我把这一项排除在计分之外。工具现在允许我跳过任何数不准的项。此后我只用真实计数来打分:002次是10,003次是14。
我粘贴了一串命令,工具当场拆穿了我。record命令紧跟在new后面就开始执行,那时我还没出门。它发现中间没经过任何时间,现在它要求我先输入WALKED,才接受这么早录入的结果。
002次散步我忘了在出门前运行工具。我的预测是凌晨4点写下的,确实在散步之前,但Gemma的预测是回来之后才生成的。模型看不到现实,它的L1和L2答案和001次完全一致,所以我把这次算进了结果。但协议的意义正是证明事件顺序,这一次工具证明不了。
总分也误导了我。摩托车以几十计,其他项都是个位数,平均值几乎就是摩托车得分。现在我把每一项分开报告。
三次散步,都在工作日下午5点左右
001和003次完整执行了协议:我的预测和三份Gemma预测都在出门前存好。002次我提前写下了自己的预测,但Gemma是回来后才跑的。所以我把结果按两种方式呈现。
严格对比只取001和003次,按每项平均绝对误差计算,越低越好。鸟叫在001次被跳过,那一行只靠一次散步支撑。探索性敏感度检查则纳入全部三次,包括002次。
我原本想知道的,是一个小模型能把我这条街想象得多准。没想到的是,我自己有多少地方从没走过。每一次散步,包括试走,都把我带进了从没去过的角落。有些街道拐弯多到让我意识到,一个初来的人稍不留神就会迷路。
散步数据都留在我自己的机器上,仓库里附了一份示例散步,方便别人自己试打分。
热门跟贴