代码补全快餐教程(1) - 30行代码见证奇迹

代码补全快餐教程(1) - 30行代码见证奇迹

下面是我用30多行代码,包含了很多空行和注释的代码写成的代码补全模型。我们先看看效果吧。

补全效果案例

先来看个比较普通的(Python, Keras)

已知:

y_train = keras.utils.to_categorical(y_train, num_classes)\ny_test = keras.

补全之后是这样的:

y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

算法能够知道把括号中的y_train换成y_test

再看一个把我感动哭了的(Typescript, vscode)

输入如下:

text = "let disposable_begin_buffer = vscode.commands.registerCommand('extension.littleemacs.beginningOfBuffer',\nmove.beginningOfBuffer);\nlet disposable_end_buffer = vscode.commands."

输出是这样的:

let disposable_begin_buffer = vscode.commands.registerCommand('extension.littleemacs.beginningOfBuffer',move.beginningOfBuffer);
let disposable_end_buffer = vscode.commands.registerCommand('extension.littleemacs.endendOfBuffer',move.endendOfBuffer);

请注间这其中的难度,变量定义中用的是begin,而extension和move中用的都是beginning,算法能将其换成endend而保持OfBuffer不变。

函数的补全(Java)

输入如下:

public class Issue {\nprivate Long id;\nprivate String filename;\nprivate Long lineNum;\nprivate String issueString;\npublic Long getId() {

输出如下:

public class Issue {
private Long id;
private String filename;
private Long lineNum;
private String issueString;
public Long getId() { return id; }

对于IntellJ IDEA来说这不算什么,但是对于完全不懂Java语言的文本模型,隔着几行其它变量能把return id给补全出来还是很了不起的

能看懂循环(Java, Android)

题目取自Android源代码:final int N = a.getIndexCount();\nfor (int i = 0; i < N; i++) {\nint index = a.

补全结果如下:

final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getAttribute(i);

从上下文看,鬼知道a是个啥类型,但是这个模型可以根据变量attr猜出来getAttribute。

话说我的attr想用a.getIndex获取怎么办?不用重新训练了,给模型写个例子就好了:

输入如下:

int attr = a.getIndex(i);\nfor (int i = 0; i < N; i++) {\nint attr = a.

补全的结果就是这样了:

int attr = a.getIndex(i);
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);

还会给变量名做加法!(Python, Keras)

输入如下:

tower_1 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)\ntower_1 = Conv2D(

见证奇迹的时刻到了:

tower_1 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img) tower_2 = Conv2D(64

也就是补完tower_1之后,算法不过瘾开始命名了一个tower_2继续补!
这对卷积一写好多层太方便了有没有?

这个加法对于变量名管用,对于下标变量也有效。
我们再来看个例子:

x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)

不管是用y_train还是x_test做补全时,shape后面的[0]就会被加1变成[1],在这里是不适用的,补完了需要手工补一下。

多语言支持 (common lisp)

为了证明不是针对Java和Python做的特殊优化,我们来个lisp的例子看下:

text = '(progn (setq a (func1 0)) (setq b'

输出如下:

(progn (setq a (func1 0)) (setq b (func2 0)) (setq c (func3 0)) (setq d (func4 0))

不但知道func1加1变func2,setq的变量,也从b变成c,d以此类推。

30行代码创造奇迹

上面这样神奇的功能,我们借助最新的神经网络自然处理的工具,只有30多行代码就可以搞定:

import torch
from transformers import GPT2Tokenizer, GPT2LMHeadModel

# 加载词汇表
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# 输入待补全的文本
text = 'int idx = a.getIndex(i);\nfor (int i = 0; i < N; i++) {\nint attr = a.'
predicted_text = text

# 每一个只能补一个token出来,补一句话需要多次,30次是我拍脑袋的
for i in range(0,30):
    
    # 以上次预测结果作为本次的输入,所谓的自回归
    indexed_tokens = tokenizer.encode(predicted_text)

    # 将读出的索引标记转化成PyTorch向量
    tokens_tensor = torch.tensor([indexed_tokens])

    # 加载模型中预训练好的权值
    model = GPT2LMHeadModel.from_pretrained('gpt2')

    # 设置为eval模式,这样就不会执行训练模式下的Dropout过程
    model.eval()

    # 使用GPU进行加速,诚实地讲速度不太快
    tokens_tensor = tokens_tensor.to('cuda')
    model.to('cuda')

    # 进行推理
    with torch.no_grad():
        outputs = model(tokens_tensor)
        predictions = outputs[0]

    # 获取预测的下一个子词
    predicted_index = torch.argmax(predictions[0, -1, :]).item()
    # 解码成我们都读懂的文本
    predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])
    # 打印输入结果
    print(predicted_text)

用来自动写作

其实,上面所用的gpt-2模型,并不是给代码补全用的,用来自动写点的东西到时它的本业。

比如大家可以试试,给“To be or not to be"补全下,我的结果如下“To be or not to be, the only thing that matters is that you're a good person.”
再比如“I have a dream that one day”,我的结果如下“I have a dream that one day I will be able to live in a world where I can be a part of something bigger than myself.”

如果不想写代码的话,可以直接在https://transformer.huggingface.co/doc/gpt2-large中去直接试验。
如下图所示,写代码写文字都可以:

gpt2

安装环境

如果想试用上面的代码的话,只需要安装transformers库就好了。

pip install transformers

另外,transformers库依赖PyTorch或Tensorflow之一,我们上面的代码是基于PyTorch的,还需要安装一下PyTorch:

pip3 install torch torchvision

在Windows下安装命令稍有不同,需要指定版本号,例:

pip3 install torch===1.3.0 torchvision===0.4.1 -f https://download.pytorch.org/whl/torch_stable.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容