注意:本文包含 AI 创作

我平时用 chatGPT 干什么

  • 聊天:几乎是漫无目的聊天。也没有太多有意义的记录
  • 写作润色:有时候会用来润色英文句子,但是担心自己本来就不好的英语写作水平继续退化
  • 搜索:经常用的是 NewBing,但是中文搜索的质量非常差,NewBing早些时候的情绪有些不稳定。
  • 写材料:学校的各种材料,我往往会先让GPT(文心一言在这方面的效果也不错)生成一个大概,再自己去修改。虽然也可以指挥 GPT 自己一步一步修改,但是自己修改会更好一些。
  • 写代码:让GPT写一些简单的脚本和小的程序,GPT基本上都能完成完成得很好。比如 python 中的绘图库 Matplotlib,接口有些混乱,想要绘制出自己满意的图非常耗时间。指挥 GPT 绘制+自己可以节省查询 API 的时间,比如指定深度学习模型的输入输出,GPT写出一段直接就能用的代码也是绰绰有余的。

关于写代码,有时候找到开源的代码并不是自己习惯的语言,经常要把一种语言转换成另外一种语言,以便嵌入自己的程序。据我了解,不少企业的算法人员一般用的都是 MATLAB 和 Python 这些方便构建 demo 的脚本语言,进行算法的验证,随后有专门的人员用适合软件开发,或者是嵌入硬件的语言重新编写。(尽管看上去是低效的东西,确实不少地方是这么干的)。

这种相对机械性的工作,个人认为尤其适合 GPT 去完成。将一种语言转换成另外一种语言,嵌入到程序当中花费相当多的时间,却没有太多收益。本文记录几个这样的例子和个人的使用体验。

GPT3.5:MATLAB -> Python

年初的时候,GPT4.0 还没有发布,我想实现的程序是以下这个公式,其作用是对一个相位进行解包裹感兴趣的(详细可以原论文,这里不多赘述)

φUW=IFT[1f2FT(Im[eiϕWIFΓ(f2FT(eiϕW))])].\varphi_{UW}=\mathrm{IFT}\bigg[\frac{1}{|f|^{2}}FT(\mathrm{Im}[e^{-i\phi_{W}}\mathrm{IF}\Gamma(|f|^{2}FT(e^{i\phi_{W}}))])\bigg].

首先我尝试的是LaTeX\LaTeX -> Python,结果并不理想。所幸作者给出了Matlab 的源码,只有简短的几行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function U=tiepu(W)                 %TIE unwrapper after reference [1]
[Ny,Nx]=size(W);
W=[W fliplr(W)];
W=[W;flipud(W)];
fsqr=repmat(0.5/Nx*(-Nx:Nx-1),2*Ny,1).^2+repmat(0.5/Ny*(-Ny:Ny-1)',1,2*Nx).^2;

W=ifft2(ifftshift(nan2zero(1./fsqr).*fftshift(fft2(imag(exp(-1i*W).*ifft2(ifftshift(fsqr.*fftshift(fft2(exp(1i*W))))))))));
U=W(1:Ny,1:Nx);
end


function M=nan2zero(M) %self-explanatory
M(~isfinite(M))=0;
end

MATLAB 语言本身就足够丑陋,这段代码就更加难看了,像是某种程序生成的,程序的第7行括号都叠了8层。不过不太可能是 GPT 生成的,GPT 的代码风格还是相当优雅。

初版

我当时没有加任何prompt,直接用中文,很不客气的直接指挥 GPT 干活:
Alt text
其中有几个函数没有定义,这是 gpt 给出的结果

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np

def tiepu (W):
Ny, Nx = W.shape
W = np.concatenate ((W, np.fliplr (W)), axis=1)
W = np.concatenate ((W, np.flipud (W)), axis=0)
fsqr = np.tile (0.5/Nx*(-Nx:Nx-1), (2*Ny, 1))**2 + np.tile (0.5/Ny*(-Ny:Ny-1), (1, 2*Nx))**2
W = np.fft.ifft2 (np.fft.ifftshift (nan2zero (1./fsqr) * np.fft.fftshift (np.fft.fft2 (np.imag (np.exp (-1j*W) * np.fft.ifft2 (np.fft.ifftshift (fsqr * np.fft.fftshift (np.fft.fft2 (np.exp (1j*W))))))))))
U = W [:Ny, :Nx]
return U

请注意,这代码中的 nan2zero 函数需要根据具体的需求进行实现。另外,还需要导入相应的库(如 numpy)来支持代码中的函数和操作。

与GPT共同修改

写这篇文章之事,我重复了实验,对于 GPT 的错误,我有以下两种做法

  • 第一种做法是明确地告诉 GPT 代码错误的位置,以及错误的原因,结果是 GPT 可以给出正确的修改。这种做法是我之前采用的。
  • 第二做法是不告诉 GPT 代码错误的存在,只是告诉大概说明错误的地方,或者告诉 GPT 有错误,让他自己检查,看看 GPT 是否能够改正

第一次修改

代码并没有一次性就能通过编译。首先报错的地方是GPT 使用了MATLAB里支持的语法而并非 -Nx:Nx-1 Python支持的特性。

1
fsqr = np.tile (0.5/Nx*(-Nx:Nx-1), (2*Ny, 1))**2 + np.tile (0.5/Ny*(-Ny:Ny-1), (1, 2*Nx))**2

这一次,我只是告诉 GPT代码里有py不支持的语法,没有指出代码错误的位置,GPT 能够识别错误的位置并修改

1
fsqr = np.tile (0.5/Nx * np.arange (-Nx, Nx), (2*Ny, 1))**2 + np.tile (0.5/Ny * np.arange (-Ny, Ny), (1, 2*Nx))**2

第二次修改

修改后没有存在语法上面的问题,但加过并不如意,fsqr 和 W 的维度不匹配,无法运算。这一次我也没有指出错误的位置,只是告诉GPT存在维度不匹配的问题。

1
fsqr = np.tile (0.5/Nx * np.arange (-Nx, Nx), (2*Ny, 1))**2 + np.tile (0.5/Ny * np.arange (-Ny, Ny).reshape (-1, 1), (1, 2*Nx))**2

GPT 给出了正确的reshape的结果。

第三次修改

代码存在把 0 作为除数的错误。依旧只是只是模糊地告诉 GPT 错误方向,依旧可以获得正确的地修改。

第四次修改

经过三次修改依然没能得到正确的结果,MATLAB 的数值运算更为准确,复数的运算比如(a+bi)*(a-bi)的运算是可以得到实数的,而Python中复数的运算依旧是复。所以这个函数需要的是实数输出,MATLAB 中没有体现体验这一点,GPT 也没有意识到。意识到这个问题之后,这里的问题自行修改比找 GPT 修改更方便一些。

结果

经过多次修改,基本上得到满意的结果。在 GPT 的辅助下写了一点小段验证的代码,效果和MATLAB以及论文给的结果相同。

Alt text

GPT-4

同样是没有 Prompt 情况下的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
以下是将你的 MATLAB 代码转换为 Python 代码的尝试。请注意,Python 的索引是从 0 开始的,而 MATLAB 的索引是从 1 开始的。此外,Python 中的一些函数可能需要额外的库,如 numpy 和 scipy。
python
import numpy as np
from scipy.fftpack import fft2, ifft2, fftshift, ifftshift

def tiepu (W):
Ny, Nx = W.shape
W = np.concatenate ((W, np.fliplr (W)), axis=1)
W = np.concatenate ((W, np.flipud (W)), axis=0)
fsqr = np.tile (0.5/Nx*np.arange (-Nx,Nx).reshape (1,-1), (2*Ny,1))**2 + np.tile ((0.5/Ny*np.arange (-Ny,Ny).reshape (-1,1))**2, (1,2*Nx))
W = np.exp (-1j*W)*ifft2 (ifftshift (fsqr*fftshift (fft2 (np.exp (1j*W)))))
W = np.imag (fftshift (fft2 (1./fsqr*fftshift (ifft2 (W)))))
W = ifft2 (ifftshift (W))
U = W [:Ny, :Nx]
return U

这段代码使用了 numpy 和 scipy 库来实现 MATLAB 中的一些函数,如 `fliplr`, `flipud`, `repmat`, `fft2`, `ifft2`, `fftshift`, `ifftshift`。请确保你已经安装了这些库。

GPT 4.0 在没有 Prompt 的情况下能够给出基本不存在前面错误的代码,但是输出还是复数,这段代码自己稍作修改就可以用了

GPT 写的其他几个代码和 Prompt

在加了 Prompt 和 用 GPT 4.0 之后,在写代码和翻译代码方面效率高了很多。

后续我还让 GPT 4.0 改了一些代码,比较长的包括一个用 FISTA 求解 TV 正则化问题的 MATLAB,Prompt 大概是告诉 GPT 他是一个数值计算的专家,常用的语言是 MATLAB 和 Python,虽然会出现一些错误,但是让 GPT 稍作修改基本就没有太多问题。

另外是让 GPT 写了一个泽尼克多项式计算的程序, GPT 自己写的情况反而比翻译现成的代码的效率高。

结论

  • GPT 3.5 还是 GPT 4.0 在翻译代码的过程中还有可能会犯一些很明显很低级的错误,甚至他自身检查就能发现,GPT 似乎也有偷懒的倾向。
  • GPT 是基于语义的翻译,虽然 MATLAB 库众多且复杂,GPT 都能理解这些库函数的含义,并且在Python中找到对应的函数或者自己重新编写可以实现功能的辅助函数,目前没有遇到无中生有的情况(可能是训练语料离包含了文档)。
  • GPT 4.0 的表现要远好于 GPT 3.5

其他代码翻译器/项目

Copilot

Github Copilot 的学生认证一直没通过,所以也没有能验证 Copilot 这方面的能力。 GPT 在写一些通用的代码,比如卷积神经网络模型的表现非常好,而翻译代码似乎还差一点。Copilot 应该是能够获取报错的信息,猜测凭借报错信息 Copilot 的能力应该远好于各种 Prompt 情况下的原生 GPT。

Ai Code Translator

Ai Code Translator 也是基于 GPT 搭建的,支持 GPT 3.5 和 GPT 4.0,支持的语言非常多,不知道和原生 GPT 相比是否会犯更少的错误。

ide onelang

ide onelang 不是基于 LLM 的代码转译,它的 Github 仓库 也列出了很多类似的项目。