作者 | 牟牟
前言
为了让大家更好地学习 Pipcook 和机器学习,我们准备了实战系列教程,会分别从前端组件识别、图片风格迁移、AI 作诗以及博客自动分类,这几个具体示例来讲解如何在我们日常开发中使用 Pipcook,如果需要了解 Pipcook 1.0,请阅读文章 AI ❤️ JavaScript, Pipcook 1.0。
背景
图片风格转换在一些相机 App 或者照片编辑 App 中有比较多的应用,可以对图片进行各种转换。Pipcook 已经支持图片风格迁移模型,可以实现很多有趣的图片风格转换,比如将马变成斑马:
或者苹果和橘子的图片互转:
或者照片和各种风格艺术画之间的相互转换(每种类型需要进行一次模型训练):
是不是很有趣,让我们瞧瞧如何在 Pipcook 上实现这个功能吧!
Pipeline
首先定义一个 pipeline 配置文件 cycle-gan.json
,内容如下:
{
"plugins": {
"dataCollect": {
"package": "@pipcook/plugins-image-classification-data-collect",
"params": {
"url": "https://ai-sample.oss-cn-hangzhou.aliyuncs.com/apple2orange.zip"
}
},
"dataAccess": {
"package": "@pipcook/plugins-pascalvoc-data-access"
},
"modelDefine": {
"package": "@pipcook/plugins-tensorflow-cycle-gan-model-define"
},
"modelTrain": {
"package": "@pipcook/plugins-image-generation-tensorflow-model-train",
"params": {
"niter": 50000
}
},
"modelEvaluate": {
"package": "@pipcook/plugins-image-generation-model-evaluate"
}
}
}
我们使用了以下插件来完成我们的 pipeline:
- @pipcook/plugins-image-classification-data-collect 这个插件用于下载图片分类的数据集,我们需要提供 url 参数,插件会下载并解压数据集。
- @pipcook/plugins-pascalvoc-data-access 下载好了数据集后,需要将数据集转换为 pascal voc 格式才能被风格转换模型识别,所以我们采用此插件。
- @pipcook/plugins-tensorflow-cycle-gan-model-define 基于 TensorFlow 实现的 CycleGAN 模型定义插件。
- @pipcook/plugins-image-generation-tensorflow-model-train 使用这个插件开始模型训练,主要的参数为 niter 训练的周期,调整该参数将会影响训练时长和模型预测效果,在我们的例子中,设置到 50000 可以基本满足。
- @pipcook/plugins-image-generation-model-evaluate 此插件在训练结束后对模型效果的评估,最终给出的是测试图片生成目标图标的各项 loss 值。
需要注意的是,CycleGAN 模型训练需要比较多的计算资源,建议使用 GPU 服务器进行训练。
训练
准备好 pipeline 配置文件后,在 shell 中执行:
$ pipcook run cycle-gan.json --verbose
start loading plugin @pipcook/plugins-image-classification-data-collect
downloading dataset ...
unzip and collecting data...
create annotation file...
start loading plugin @pipcook/plugins-pascalvoc-data-access
create a result "b1192e00-20ff-4872-adbc-6f7d408ea0fc" for plugin "@pipcook/plugins-pascalvoc-data-access@0.6.3"
start loading plugin @pipcook/plugins-cycle-gan-model-define
create a result "6dda48eb-52da-425e-a95f-748fb8180954" for plugin "@pipcook/plugins-cycle-gan-model-define@0.6.0"
start loading plugin @pipcook/plugins-image-generate-tensorflow-model-train
Model: "dis_B"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 128, 128, 3)] 0
_________________________________________________________________
conv2d_18 (Conv2D) (None, 64, 64, 64) 3136
_________________________________________________________________
leaky_re_lu (LeakyReLU) (None, 64, 64, 64) 0
_________________________________________________________________
conv2d_19 (Conv2D) (None, 32, 32, 128) 131200
_________________________________________________________________
instance_normalization2d_17 (None, 32, 32, 128) 64
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU) (None, 32, 32, 128) 0
_________________________________________________________________
conv2d_20 (Conv2D) (None, 16, 16, 256) 524544
_________________________________________________________________
instance_normalization2d_18 (None, 16, 16, 256) 32
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU) (None, 16, 16, 256) 0
_________________________________________________________________
conv2d_21 (Conv2D) (None, 16, 16, 512) 2097664
_________________________________________________________________
instance_normalization2d_19 (None, 16, 16, 512) 32
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU) (None, 16, 16, 512) 0
_________________________________________________________________
conv2d_22 (Conv2D) (None, 16, 16, 1) 8193
=================================================================
Total params: 2,764,865
Trainable params: 2,764,865
Non-trainable params: 0
_________________________________________________________________
Model: "dis_A"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_4 (InputLayer) [(None, 128, 128, 3)] 0
_________________________________________________________________
conv2d_41 (Conv2D) (None, 64, 64, 64) 3136
_________________________________________________________________
leaky_re_lu_4 (LeakyReLU) (None, 64, 64, 64) 0
_________________________________________________________________
conv2d_42 (Conv2D) (None, 32, 32, 128) 131200
_________________________________________________________________
instance_normalization2d_37 (None, 32, 32, 128) 64
_________________________________________________________________
leaky_re_lu_5 (LeakyReLU) (None, 32, 32, 128) 0
_________________________________________________________________
conv2d_43 (Conv2D) (None, 16, 16, 256) 524544
_________________________________________________________________
instance_normalization2d_38 (None, 16, 16, 256) 32
_________________________________________________________________
leaky_re_lu_6 (LeakyReLU) (None, 16, 16, 256) 0
_________________________________________________________________
conv2d_44 (Conv2D) (None, 16, 16, 512) 2097664
_________________________________________________________________
instance_normalization2d_39 (None, 16, 16, 512) 32
_________________________________________________________________
leaky_re_lu_7 (LeakyReLU) (None, 16, 16, 512) 0
_________________________________________________________________
conv2d_45 (Conv2D) (None, 16, 16, 1) 8193
=================================================================
Total params: 2,764,865
Trainable params: 2,764,865
Non-trainable params: 0
_________________________________________________________________
create a result "b15b7472-d430-4289-9216-a7e2f9ee852c" for plugin "@pipcook/plugins-image-generate-tensorflow-model-train@0.6.0"
start loading plugin @pipcook/plugins-cycle-gan-model-evaluat
训练预计持续时间12小时,训练完成后,将在当前目录生成output文件夹,里面就是我们训练好的模型了。我们可以使用 npm 对它进行安装:
$ cd output && npm install
风格转换
此时,模型已经准备就绪,我们找一张苹果的图片和一张橘子的图片:
const predict = require('./output');
const fs = require('fs');
function saveToFile (base64Data, file) {
var dataBuffer = new Buffer(base64Data, 'base64');
fs.writeFile(file, dataBuffer, function(err) {
if (err) {
console.log('保存文件失败', err.message);
} else {
console.log('保存文件成功:', file);
}
});
}
(async () => {
const orange_from_apple = await predict({ path: '/path/to/apple.jpg', predictType: 'a2b' });
saveToFile(orange_from_apple, '/path/to/save/orange_from_apple.jpg'); // 生成的橘子图片
const apple_from_orange = await predict({ path: '/path/to/orange.jpg', predictType: 'b2a' });
saveToFile(apple_from_orange, '/path/to/save/apple_from_orange.jpg'); // 生成的苹果图片
})();
保存为 apple2orage.js, 然后运行:
$ node ./apple2orange.js
保存文件成功: /path/to/save/orange_from_apple.jpg
保存文件成功: /path/to/save/apple_from_orange.jpg
转换之后的图片:
将代码包装一下,一个可以提供苹果和橘子互转的图片风格转换服务就完成啦!
数据集
图片风格转换的数据集目录结构如图:
其中 train
为训练数据集,用于模型训练,test
为测试数据集,用于模型训练结束后验证模型准确性。
测试数据集和训练数据集包含 A,B 两个文件夹,这两个文件夹内的数据不需要配对,也就是说,A 和 B 文件夹内是无关联的图片,在我们这个例子中,我们只需要在 A 文件夹内放入任意苹果的图片,B 文件夹内放入任意橘子的图片,就可以进行模型训练了。这对我们收集数据来说非常友好,比如你可以将人脸部照片放入 A 文件夹, 二次元的脸部照片放入 B 文件夹,不需要任何标注,就可以完成照片二次元相互转换模型数据集的整理。
进阶
了解了 Pipcook 风格转换的实现后,是不是有上手试一试的冲动呢?同学们可以尝试下面的训练集,也可以自己整理训练数据完成想要的风格变换模型。
总结
读者到这里已经学会如识使用 Pipcook 实现图片风格迁移,下一篇文章,我们将使用 Pipcook 来看看如何通过文本创作类模型来创作中文诗歌。
🎉Pipcook 1.0 系列专题 🎉
AI (爱) JavaScript , Pipcook 1.0 正式发布
使用Pipcook对图片中的前端组件进行分类,饼图、折线图还是柱状图?
👉使用 Node.js 将图片中的苹果变成橘子
未完待续...
❤️欢迎大家关注 Alibaba F2E 微信公众号前端智能化技术分享周(6.29-7.3)❤️