来用 Node.js 做首诗吧!

简介: 月明三象服,凄凉對夕暉。妙静尋世夜,里感仗履遊。

作者 | 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"
    }
  }
}

通过上面的插件,我们可以看到分别使用了:

  1. @pipcook/plugins-chinese-poem-data-collect 用于下载诗歌的数据集,这里我们使用了 @DavidCai1993 开源的诗歌数据集;
  2. @pipcook/plugins-textline-data-access 文本创作所需要的数据集就是多行文本,所以我们使用这个插件将上游的诗歌处理成多行文本的格式;
  3. @pipcook/plugins-tfjs-text-lstm-model-define 文本创作所使用的模型,我们具体参考了英文诗歌版本的实现:https://github.com/agrawalparth08/poetry-generation-lstm
  4. @pipcook/plugins-text-creation-tfjs-model-train 该插件为文本创作类型的任务提供训练支持
  5. @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 团队有话说

使用Pipcook对图片中的前端组件进行分类,饼图、折线图还是柱状图?

设计稿生成代码核心技术揭秘:获取图片中前端组件的位置信息

使用 Node.js 将图片中的苹果变成橘子

👉使用 Node.js 创作诗歌

❤️欢迎大家关注 Alibaba F2E 微信公众号前端智能化技术分享周(6.29-7.3)❤️

相关文章
|
4月前
|
JavaScript 前端开发 测试技术
什么是Node.js,它有什么作用,可以干啥呢?
什么是Node.js,它有什么作用,可以干啥呢?
33 0
|
9月前
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十四天-node.js安装
前端学习笔记202305学习笔记第二十四天-node.js安装
34 0
|
9月前
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十五天-node.js总结1
前端学习笔记202305学习笔记第二十五天-node.js总结1
47 0
|
9月前
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十五天-node.js总结2
前端学习笔记202305学习笔记第二十五天-node.js总结2
46 0
|
12月前
|
SQL JavaScript 前端开发
Node.js躬行记(21)——花10分钟入门Node.js
Node.js躬行记(21)——花10分钟入门Node.js
|
12月前
|
数据采集 Web App开发 JavaScript
Node.js躬行记(25)——Web自动化测试
Node.js躬行记(25)——Web自动化测试
Node.js躬行记(25)——Web自动化测试
|
监控 JavaScript 前端开发
Node.js入门 | 青训营
Node.js入门 | 青训营
101 0
Node.js入门 | 青训营
|
JavaScript
node.js简短周结
node.js简短周结
|
缓存 JavaScript 前端开发
「Node.js」“寓教于乐”的学习记录
用技术实现梦想。今天分享Node.js学习中总结的知识点。
179 1
「Node.js」“寓教于乐”的学习记录
|
JSON 前端开发 JavaScript
Node.js躬行记(11)——E2E测试
  Cypress是为现代网络构建的前端测试工具,解决了开发人员和 QA 工程师在测试应用程序时面临的关键痛点。   在这个测试框架中包含了E2E测试、集成测试和单元测试(内嵌了Mocha),我们需要的是它的E2E测试的能力。   官网中包含详尽的API接口文档,以及多个视频教程、实例等,只要有耐心,看完文档,上手是不成问题的。   之所以要引入E2E测试,主要是为了保证主流程能够不出错,尤其是在后期做修修补补后,有一个可靠的方式告诉我们当前页面是正常的就行。
Node.js躬行记(11)——E2E测试