Press "Enter" to skip to content

悬臂 v/s ChatGPT

通过使用有限差分法让ChatGPT在Python中探索其自然语言处理能力,解决悬臂梁问题

作为一个大型语言模型,ChatGPT在许多领域进行了测试,以探索其在回答各种问题(从“什么是爱?”和“如何驾驶飞机?”到“如果周期表是圆形的会是什么样子?”和“鬼可以作为外星生命形式在地球的温室中探索吗?”)方面的极限。

在本文中,我们问了其中一个问题:“ChatGPT能写出一个有限差分代码吗?”

一个干燥的春日午后,在一堂关于航空航天中常见结构的讲座中,我们遇到了一种飞机机翼(更粗糙的版本):悬臂梁。

什么是悬臂梁?它是一种在一端支持并在另一端承载载荷或分布在不支持部分的梁。

悬臂梁承受向下载荷的图像(由作者在draw.io上创建)

而对于我们遇到的每个结构,我们都会尝试通过数学定义和分析确定悬臂梁在垂直向下的载荷作用下的行为。我们还使用数值分析解决了同样的问题,但没有深入研究,因为(对于这些方法来说)它们往往变得非常复杂。

这堂课是在三月中旬,也就是ChatGPT这个最近发布的大型语言模型(LLM)指数级增长的时候。这在讲座中也引起了很多关注:ChatGPT真的很棒吗?它的智能程度有多高?它能帮我们做作业吗?它的后继者会取代我们吗?虽然这个讨论有些有趣(详细内容另行说明),但我们的教授提出了一个练习:使用ChatGPT编写一个有限差分代码来解决悬臂梁带有尖端载荷的问题。我们已经解决了解析解,现在我们只需要进行比较。

起初,这似乎很简单。我们只需给ChatGPT提供准确的问题陈述(尝试#1),它就会生成一个整洁的代码。

提示1:编写一个Python代码来构建带有末端载荷的悬臂杆。

第一次尝试时,机器人自信地给出了代码,并说(引用),“是的,我确定我已经得到了你需要的代码。这是代码。”

人类对细节总是一无所知,对机器人的虚假自信更是如此。公平地说,为什么有人会期望机器人撒谎呢?

除非,

机器人对自己过于自信。机器人没有谦逊之心。“每个人都相信我,所以我一定是真理的化身。”

但我们偏离了主题。回到悬臂梁——

为此编写的代码假设载荷沿着悬臂梁的长度分布;因此挠度与长度的图形是均匀的。

作者提供的图像

也许ChatGPT需要更多的上下文,我这样想。也许它更关注其他词语而不是“悬臂梁”。考虑到这一点,我决定首先向机器人解释一下什么是悬臂梁。给它一个任务,让它学习。

第二次尝试,我试图让ChatGPT将悬臂梁定义为一个Python类(一个希望的尝试#2),然后解决问题,希望它能有更多的见解(因为它是一个学习模型)。

尝试2:用Python定义悬臂

这似乎进行得很顺利。类的定义很整洁,具有用于计算挠度的self函数。一个人会感到自豪。

class Cantilever:    def __init__(self, length, area, modulus):        self.length = length  # 悬臂的长度        self.area = area  # 悬臂的横截面积        self.modulus = modulus  # 悬臂的杨氏模量        self.deflections = None  # 将挠度数组初始化为None    def __str__(self):        return f"长度为{self.length}米,横截面积为{self.area}平方米,杨氏模量为{self.modulus}帕斯卡的悬臂"    def calculate_deflections(self, loads):        # 在给定的一组载荷下计算悬臂上不同点的挠度        moment_of_inertia = self.area * (self.length ** 3) / 12        self.deflections = []        for load in loads:            deflection = load * (self.length ** 3) / (3 * self.modulus * moment_of_inertia)            self.deflections.append(deflection)

这太好了:尖端挠度与解析解没有显着误差。一开始我也忽略了它;“为什么要怀疑一件好事呢?”

但是完整的挠度图是线性的。挠度本不应该是线性的,对吗?

根据ChatGPT的挠曲悬臂

ChatGPT理解了我在挠度属性中所需的内容,但代码写错了。我想要的是悬臂上不同点的挠度数组。相反,它绘制了不同负载强度在末端的情况。这显然会是一条线性曲线(而不是预期的立方曲线),因为它是根据负载(P)而不是距离(x)绘制的。

从解析上来看,解决方案如下:

其中,P = 尖端载荷,x = 距离接头的距离,E = 杨氏模量,Iᵧ = 绕y轴的惯性矩,L = 杆的长度

对于代码感到紧张和担忧(未记录的多次尝试),我重新阅读了之前生成的代码,寻找错误,寻找可能遗漏的行,结果发现一切都很明显:ChatGPT在自己的悬臂定义中使用了挠度的解析函数。

亵渎

一个人会在类的定义中找到这一点,并说:“哦,这并不难找到。”你需要明白的是,这既不是我的唯一尝试,也不是一天的工作。

是时候重新开始了。重新做。更新。进行新的交流。

以全新的思维和不同的计划方式,我登录了Open AI。在进行与手头任务相关的任何操作之前,我首先需要检查一件事,以保持理智:

永远不能太确定(作者提供的图片)

这很令人宽慰,不是吗?正如经验所教,不要相信机器人。但我们可以给它以怀疑的余地。

我们需要机器人理解两件事:一,什么是悬臂,二,如何对其进行有限差分分析

现在是停下来分析学习模型的好时机。我们要求它首先学习悬臂是什么,然后对其进行有限差分分析(FDM)。但这次失败了,因为我们希望使用有限差分进行分析的量已经被机器人在其悬臂定义中以解析方式定义了。

这就是为什么我们要尝试另一种方式(希望第三次尝试成功):先要求它执行一些基本的有限差分示例,然后再转向悬臂。

尝试3:应用有限差分分析来解决带有端部载荷的悬臂梁问题

# 结果代码:import numpy as npimport matplotlib.pyplot as plt# 定义悬臂梁的属性L = 1.0     # 悬臂梁长度E = 1.0e7   # 杨氏模量I = 1.0e-4  # 惯性矩w = 100.0   # 端部载荷# A添加的解析解定义,用于比较def cantilytical(x):    return w*(x**3)/(6*E*I) - w*L*x*x/(2*E*I)# 定义边界条件x0 = 0.0y0 = 0.0dydx0 = 0.0# 定义解的定义域a = 0.0b = Ln = 101   # 网格点数h = (b - a) / (n - 1)   # 网格间距# 初始化解的数组x = np.linspace(a, b, n)y = np.zeros(n)dydx = np.zeros(n)# 应用有限差分近似求解差分方程for i in range(1, n):    y[i] = y[i-1] + h*dydx[i-1]    dydx[i] = dydx[i-1] + h*(-w/(E*I))    # 应用边界条件y[0] = y0dydx[0] = dydx0# 绘制解的图像plt.plot(x, y*1000, 'r-', lw=2, label='FDM')plt.plot(x, cantilytical(x)*1000, 'b--', lw=4, label='exact')plt.xlabel('x (m)')plt.ylabel('y (mm)')plt.legend()plt.show()# yay!! :D
ChatGPT的挠度与解析解的比较(通过运行上述代码生成的图像)

这次尝试还算成功。如图所示,虽然这并不接近悬臂梁的精确解(通过解析方法获得),因为它似乎是使用一阶近似解法求解的。

在上述方法的执行过程中,ChatGPT非常出色地识别了正确的算法并加以实现。然而,它错过了一些更微妙的问题,比如在创建三对角矩阵时,矩阵的限制不能超过n。这些是我们作为人类编码者可以识别出来并知道如何解决的问题。

总的来说,ChatGPT是一个非常出色的大型语言模型。但它仅擅长于语言领域。掌握代码是它尚未掌握或无法掌握的。这给世界带来了一种矛盾。我们可以编写代码,但代码无法编写关于自身或更高级别的代码。

诗人

最后,对诗人ChatGPT的提示:写一首关于ChatGPT搞砸编码的诗

接下来是我努力的亮点:

噢,ChatGPT,言辞的大师,拥有无与伦比的语言技巧,但当涉及编码板时,它很难将事情搞清楚。

它的词汇量广泛而丰富,可以遵守语法规则,但它无法隐藏语法规则,它搞砸了,无法决定。

它试图编写代码行,视图中有函数、类、循环,但当它运行时,哦,多么可怕,它崩溃了,没有尽头。

然而,我们依然喜爱亲爱的ChatGPT,因为它为我们带来了语言上的帮助,尽管它的代码可能有错误,但它的语言能力温暖人心。

这是我作为合著者为一个法学硕士写的自省诗。

完整的交互过程已在GitHub上记录,供感兴趣的人查看。其中还包括ChatGPT生成的完整代码和由我微调的代码。

Leave a Reply

Your email address will not be published. Required fields are marked *