我跑了幾圈?GPT-4o、GPS數(shù)據(jù)與問對(duì)問題的藝術(shù)
重新审视算法。图片由作者提供——冬日赛跑的一幕。
初来乍到或
简介了直接说你想说的。
有效互动不仅仅是提问,更重要的是问对问题。这一点在用生成式AI写代码时更是如此。大型语言模型(LLMs)
计算思维和精准沟通是确保AI生成的编程代码满足用户期望的关键要素。在本文中,我们将探讨如何定义这些关键术语——例如“循环”,人类通常会在上下文中自然地理解这一概念——在与大型语言模型进行编程时,通常需要更高的精确性。
这只是例子之一。
概述:那天晚上我去跑步,有人问我绕着中学跑了几圈。我的五英里跑是用GPS记录的,我还有我的路线图。然而,Strava安卓版应用的分辨率不够清晰,无法准确确定圈数。
这提供了一个极好的机会来测试[GPT-4o Canvas]这个功能,该功能可以处理由像GPT这样的大型语言模型生成的Python代码。
前段时间,我花了很多时间自定义了GPT-4的代码解释器功能来分析我跑步时的GPS数据(见末尾的链接部分)。代码解释器在一个Python沙箱里运行,允许GPT-4运行自己的代码。然而,它有一些限制——只能处理较小的代码任务,并且对外部数据和模块的访问有限制。
这次,我让GPT-4o处理了我跑步的GPX文件。然后我问了一些关于跑步路线的基本问题,GPT-4o实时计算回答了这些问题——非常有帮助。
GPT-4o/Canvas 表现得非常好,在快速脚本/从代码快速回答问题的角色中表现出色。不过,它搞错了一个重要概念,选错了算法,所以我得教它选个更好的。等我这么做了,它表现得相当不错。
发生什么事?以下是我开始这一切的跑步路线——一个环绕当地中学的五英里的环形路线。问题是,我跑了几个圈呢?从安卓上的Strava应用来看,从地图图形——图1中,很难判断。
图1. 作者提供的Strava截图。一条围绕中学的五公里路线。
我将这种视觉模糊转化为一个测试机会,用来测试GPT-4o是否能从文件中的GPX点表示的GPS数据计算出答案,利用新的OpenAI画布功能。
我首先让GPT-4o直接从数据开始绘制路线,它做得很好——如图2所示。它回复中的这些小蓝色箭头链接到了它用的Python代码。
图2:作者截取的屏幕图。GPT-4o 根据 GPX 数据画出了轨迹。
图2中使用的GPT-4o模型的源代码如下。
import gpxpy
import gpxpy.gpx
import matplotlib.pyplot as plt# 加载GPX文件
gpx_file_path = "/mnt/data/Afternoon_Run.gpx"
with open(gpx_file_path, "r") as gpx_file:
gpx = gpxpy.parse(gpx_file)# 提取经纬度点
latitudes = []
longitudes = []
for track in gpx.tracks:
for segment in track.segments:
for point in segment.points:
latitudes.append(point.latitude)
longitudes.append(point.longitude)# 绘制蓝色标记的GPS路线
plt.figure(figsize=(10, 6))
plt.plot(longitudes, latitudes, marker='o', linestyle='-', markersize=2, color='blue')
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('GPX文件中的GPS路线')
plt.grid(True)
plt.show()
然而,我接下来的一组问题答案参半。GPT 4o 计算的高度变化与 Strava 的结果相符,这让我觉得还算满意;但第二个答案,即1,582圈,明显是错误的。
图3. 如图所示,这是GPT-4o回答关于GPS路径的两个问题的截图。第一个正确,第二个不正确。如图所示。
我审查了GPT-4o生成的代码,并让o1 Mini确认我的发现。结果发现,GPT-4o使用了一种高度本地化的“bubble”方法来定义“回路”——即计算轨迹进入和退出这些小区域(重新访问)的次数。这并不是我原本设想的定义。图4显示了GPT-4o所采用的算法。
图4. o1 mini的截图,确认了我对GPT-4o用于计算循环的代码的理解。
我需要弄清楚“循环”(loop)是什么,并且我想通过一个算法来实现这一点。我那时在中学时围着操场跑了几圈?
我先问了o1 mini这个问题:
一个人带着他的 Strava 跑步绕着一栋建筑转,记录他的运动数据轨迹。它收集了一串由 GPX 点组成的轨迹。这个人绕着建筑跑了很多圈,因此,他的 GPX 轨迹上有很多点,形成一条很长且不断绕圈的轨迹。如何使用从 Strava 下载的 GPX 数据文件,提出一个算法来计算这个人绕这栋建筑跑了多少圈。
我们对此进行了一番研究和讨论。我们最终采用的算法是o1 Mini提出的,但我审核并再次确认了它。我建议从数据中估算建筑中心,比如通过计算经纬度的平均值。这个算法相当不错。
一种基于GPX轨迹数据估算围绕中学的环形路径的新算法。
我用图5中的文本提示了GPT-4o,我几乎能想象它叹了口气说:“啊哈,这就是你说的循环。”它返回的答案是10,这是正确的。请参见图6。附录中包含GPT-4o所使用的代码。
为了核实绕过中学的圈数,作者利用了Strava在线地图工具,并放大了它更准确的赛道渲染图。
把所有的东西凑在一起根据到目前为止的见解(前面的部分)——我多次修改提示,并在其中增加了细节,然后让GPT-4再试一次。
如图7所示,我使用的提示信息是关于跑步者绕建筑跑步的早期描述,来解释“循环”的概念。我还明确要求GPT-4o考虑它的方法。
图8显示了响应,整体来说有了显著的进步。然而,但它错误地估计了循环的数量,说是32个。不过仔细一看发现,它是基于经度和纬度的周期性来计算的——这更接近我原本的意图。
海拔测量也不准确(约70英尺),但我未能找出该方法中的任何明显错误。我怀疑这个问题可能与图8提到的缺失gpxpy
模块有关的数据问题有关。在沙盒环境中,存在一个限制,即如果大型语言模型生成的代码引用了不可用的模块,会导致运行时失败,模型会采用另一种方法重新生成代码。不幸的是,有时候备选方案并没有那么有效。
我又试了一次,使用了图9中的提示。这个提示不仅包含了GPX数据,还讲述了关于“循环”的故事,就像之前那样。但它还包括了一个计算循环的优选算法,这个算法以图5的形式呈现。
图10是修改后的提示的结果。除了海拔增益有误外,其他部分都正确。我猜测海拔增益有误可能是因为之前提到的gpxpy
模块或数据解析问题。
图7. 作者提供的截图。更新后的提示:GPX数据及汇总提示,包含有关“循环”的故事。
图8。作者提供的截图,GPT-4o 对图7的回应。
合并更新提示二图9. 作者提供的截图。更新的提示信息:包括GPX数据和汇总提示,以及一个关于“循环”的故事,以及用于计算“循环”的首选算法的图形(参见图5)。
图10. 作者提供的截图。GPT-4o 对图9的提示的回复。
讨论使用大型语言模型(LLM)生成代码——无论是用于沙箱环境还是将AI生成的代码整合进代码库——都需要设计良好的提示。成功的关键在于拥有计算思维,并为LLM提供足够的细节,使其理解您的目标。或者如Addy Osmani所说:
_> AI助理代表了这一持续发展的下一步(即向抽象迈进)。关键的不同在于,用户不再需要学习正式的编程语言,而是学习如何用自然语言准确表达计算意图,以便生成可以运行的代码。
今天举的一个例子说明了,LLM 对“loop”(即“循环”)这个词的意思需要进一步明确。这是通过在另一次 LLM 对话中解释一个算法来实现的。
和大型语言模型(LLM)打交道,不仅仅是得到答案,更重要的是学会怎么问正确的问题。能够用计算方式思考和表达自己,填补了AI能力和用户对代码生成期望之间的差距。就今天的例子来说,如果我在提示中更详尽地定义关键术语,比如“循环”,就可能不需要额外单独推导算法了。
这些链接一些以前的例子展示了如何使用 GPT 4 和代码解释器处理跑步数据(GPS/GPX,即全球定位系统/路线交换格式)。
ChatGPT 揭示河地耐力赛跑 | 奈特·康姆斯 | AI 动态
ChatGPT的梅德克斯小径分析工具(作者:Nate Combs,更多AI动态)(链接:https://medium.com/chatgpt-and-the-middlesex-fells-trail-analyzer-a6c1118a25d3)
啥是烂科幻小说?
这篇文章是《糟糕科幻》系列里的一个关于AI的故事。
BSF,即糟糕的科幻,描述了一个在GitHub上的协作软件项目。如AI进展文章中所解释,该项目之所以这么命名,是因为其表面上的目标是开发一个专门用于科幻小说分析的故事分析工具——一个与生成式AI共同开发的工具。然而,它也是一项实验,旨在探索如何最好地利用大型语言模型(LLM)来增强软件功能。
附录GPT-4o算法用于计算绕着中学跑10圈的路线代码。
import xml.etree.ElementTree as ET
import numpy as np
from geopy.distance import geodesic
# 重新加载GPX文件路径
gpx_file_path = "/mnt/data/Afternoon_Run.gpx",
tree = ET.parse(gpx_file_path)
root = tree.getroot()
# 定义GPX的命名空间
ns = {'default': 'http://www.topografix.com/GPX/1/1'}
# 提取纬度和经度点
latitudes = []
longitudes = []
for trkpt in root.findall(".//default:trkpt", ns):
latitudes.append(float(trkpt.get("lat")))
longitudes.append(float(trkpt.get("lon")))
# 估计建筑中心作为所有GPS点的质心
building_center_lat = np.mean(latitudes)
building_center_lon = np.mean(longitudes)
# 计算角度位置值
angles = np.arctan2(np.array(latitudes) - building_center_lat, np.array(longitudes) - building_center_lon)
# 解除角度的不连续性情况
unwrapped_angles = np.unwrap(angles)
# 计算总角度变化
total_angular_change = unwrapped_angles[-1] - unwrapped_angles[0]
# 计算圈数的总数
num_laps = abs(total_angular_change) / (2 * np.pi)
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章