来用 Node.js 做首诗吧!-阿里云开发者社区

开发者社区> AlibabaF2E> 正文

来用 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)❤️

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
AlibabaF2E
使用钉钉扫一扫加入圈子
+ 订阅

阿里经济体前端技术最新内容汇聚在此,由阿里经济体前端委员会官方运营。我们的愿景是建立全球一流的前端团队,链接商业,让数字世界触手可及是我们的使命。阿里经济体前端委员会致力于加强技术前瞻性、推进集体成长、提升国际影响力。同时我们运营着阿里经济体前端的官方公众号:Alibaba F2E,欢迎关注。

官方博客
官网链接