作者 | Yorkie
前言
为了让大家更好地学习 Pipcook 和机器学习,我们准备了实战系列教程,会分别从前端组件识别、图片风格迁移以及 AI 作诗,这几个具体示例来讲解如何在我们日常开发中使用 Pipcook,如果需要了解 Pipcook 1.0,请阅读文章 AI ❤️ JavaScript, Pipcook 1.0。
背景
我们在最新的 Pipcook 中内置了文本创作(Text Creation)的模型,那么这个模型究竟有什么使用场景呢?就像这篇文章的标题一样,最终的模型可以根据一些输入的条件,创作出对应的诗歌形式的作品,比如:
console.log(await predict('一二三四'));
// 一二三四過,橈泛澄違篁。。。
上面的例子就是会根据输入的文本为诗句的开头,以此创作后面的文本,接下来我们就从 Pipeline 开始看看如何完成这样的一个功能:
{
"plugins": {
"dataCollect": {
"package": "@pipcook/plugins-chinese-poem-data-collect",
"params": {
"url": "https://raw.githubusercontent.com/DavidCai1993/chinese-poem-generator.js/master/test/data/poet.song.91000.json"
}
},
"dataAccess": {
"package": "@pipcook/plugins-textline-data-access"
},
"modelDefine": {
"package": "@pipcook/plugins-tfjs-text-lstm-model-define"
},
"modelTrain": {
"package": "@pipcook/plugins-text-creation-tfjs-model-train",
"params": {
"epochs": 200
}
},
"modelEvaluate": {
"package": "@pipcook/plugins-text-creation-tfjs-model-evaluate"
}
}
}
通过上面的插件,我们可以看到分别使用了:
- @pipcook/plugins-chinese-poem-data-collect 用于下载诗歌的数据集,这里我们使用了 @DavidCai1993 开源的诗歌数据集;
- @pipcook/plugins-textline-data-access 文本创作所需要的数据集就是多行文本,所以我们使用这个插件将上游的诗歌处理成多行文本的格式;
- @pipcook/plugins-tfjs-text-lstm-model-define 文本创作所使用的模型,我们具体参考了英文诗歌版本的实现:https://github.com/agrawalparth08/poetry-generation-lstm
- @pipcook/plugins-text-creation-tfjs-model-train 该插件为文本创作类型的任务提供训练支持
- @pipcook/plugins-text-creation-tfjs-model-evaluate 该插件为文本创作类型的任务提供模型评估的支持
训练
由于模型本身比较大,因此在执行这个 Pipeline 之前推荐在 GPU 服务器上运行:
$ pipcook run text-creation-lstm.json --verbose
模型收敛也比较慢,所以我们需要设置 epochs 为 200,训练大概会持续4小时左右:
_________________________________________________________________
Layer (type) Output shape Param #
=================================================================
embedding_Embedding1 (Embedd [null,11,100] 478400
_________________________________________________________________
bidirectional_Bidirectional1 [null,11,300] 301200
_________________________________________________________________
dropout_Dropout1 (Dropout) [null,11,300] 0
_________________________________________________________________
lstm_LSTM2 (LSTM) [null,100] 160400
_________________________________________________________________
dense_Dense1 (Dense) [null,2392] 241592
_________________________________________________________________
dense_Dense2 (Dense) [null,4784] 11448112
=================================================================
Total params: 12629704
Trainable params: 12629704
Non-trainable params: 0
_________________________________________________________________
create a result "c7c055cd-a0af-44b5-bb57-e0ca3f9c5978" for plugin "@pipcook/plugins-tfjs-text-lstm-model-define@0.6.0"
start loading plugin @pipcook/plugins-text-creation-tfjs-model-train
created train dataset class_1 { size: 4384 }
Epoch 1 / 200
56325ms 205564us/step - acc=0.0892 loss=7.14
Epoch 2 / 200
55531ms 202667us/step - acc=0.138 loss=5.85
Epoch 3 / 200
55571ms 202815us/step - acc=0.182 loss=5.52
Epoch 4 / 200
55544ms 202717us/step - acc=0.183 loss=5.44
Epoch 5 / 200
55416ms 202249us/step - acc=0.186 loss=5.29
Epoch 6 / 200
55264ms 201694us/step - acc=0.187 loss=5.16
Epoch 7 / 200
...
55305ms 201843us/step - acc=0.869 loss=1.06
Epoch 199 / 200
55756ms 203490us/step - acc=0.868 loss=1.04
Epoch 200 / 200
55617ms 202980us/step - acc=0.875 loss=1.04
为什么要设置为200?从下面的代码块中可以看到,在每次 eopch 都会输出 accuracy(acc) 和 loss 两个值,每次训练后,这两个值都会更新,它们代表模型的训练进度,一般来说,随着训练地进行,accuracy 值会越来越高,而 loss 值会越来越低,那么对于这样的模型我们称之为模型在收敛,这里选择 200 的原因是文中定义的模型收敛比较慢,一般需要 200 次后,accuracy 值才会接近 0.9 左右。
训练完成后,会在当前目录生成 output,这是一个全新的 npm 包,那么我们首先安装依赖:
$ cd output && npm install
安装完成后,就可以使用 output 中的模型了:
const predict = require('./output');
(async () => {
const v1 = await predict('一二三四');
console.log(v1); // 一二三四過,橈泛澄違篁。。。
const v2 = await predict('天涯');
console.log(v2); // 天涯酒祠輿,悽慟歡夫寛。。。
const v3 = await predict('中');
console.log(v3); // 中慟前弧日,當余弱冠年。。。
const v4 = await predict('乐乐');
console.log(v4); // 乐乐池方志,衰病各華顛。。。
const v5 = await predict('月明');
console.log(v5); // 月明三象服,凄凉對夕暉。。。
const v6 = await predict('妙静');
console.log(v6); // 妙静尋世夜,里感仗履遊。。。
})();
最后使用 Node.js 执行这个文件,就会输出一句以“一二”开头的诗句了。
到目前为止,相信大家已经明白如何使用 Pipcook 来完成 AI 作诗这样的事情了,接下来就给大家介绍一些拓展性的玩法,我们先来看看现在的诗歌数据集长什么样:
[
{
"author": "喻汝礪",
"paragraphs": [
"扣橈泛澄虚,濯流睇幽芳。",
"晚霙襯奇樹,夕霏媚疏篁。",
"歸鳥亦暫閒,夜魄動初凉。",
"忽焉衆星微,天髙月舒光。",
"昔也杜陵子,澹然此茅堂。",
"客至酒自斟,句得意已忘。",
"云何常念饑,零落在道旁。",
"古來技入神,一飯豈所望。",
"吾輩天所窮,慨歌淚霑裳。"
],
"title": "晚泛浣花遂宿草堂",
"id": "db5ea295-2c0e-4810-9f4c-de4b0d2a92c5"
},
...
]
这个 Pipeline 在处理的时候,其实就是把所有的 paragraphs 中按照一行一行的输入到模型中,以此来找到文字前后的关系来进行诗歌创作。
那么类似的,比如你是一个命名困难症,那么你也可以将之前代码中的命名数据抓出来,按照类似的格式丢给 Pipeline,那么相信以后命名将不再是困扰你的难题。或者你也可以将散文、甚至 Rap 等风格的文本都按照这种格式输入,也能得到你想要的结果。
总结
相信读者读到这里,已经学会使用 Pipcook 实现诗歌创作了,这也是本系列教程的最后一篇,关于更多使用上的问题欢迎点击原文到 Pipcook 官方文档中来查找对应的答案。
🎉Pipcook 1.0 系列专题 🎉
AI (爱) JavaScript , Pipcook 1.0 正式发布
使用Pipcook对图片中的前端组件进行分类,饼图、折线图还是柱状图?
👉使用 Node.js 创作诗歌
❤️欢迎大家关注 Alibaba F2E 微信公众号前端智能化技术分享周(6.29-7.3)❤️