作者:牟牟
转发链接:https://mp.weixin.qq.com/s/3uZQqgjFgImTIATcr-oMRA
前言
为了让大家更好地学习 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 对它进行安装:
nbsp;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 风格转换的实现后,是不是有上手试一试的冲动呢?同学们可以尝试下面的训练集,也可以自己整理训练数据完成想要的风格变换模型。
- 人像照片和二次元头像: https://ai-sample.oss-cn-hangzhou.aliyuncs.com/pipcook/datasets/image-generation-cycle-gan/selfie2anime.zip
- 苹果和橘子:https://ai-sample.oss-cn-hangzhou.aliyuncs.com/pipcook/datasets/image-generation-cycle-gan/apple2orange.zip
- 斑马和马:https://ai-sample.oss-cn-hangzhou.aliyuncs.com/pipcook/datasets/image-generation-cycle-gan/horse2zebra.zip
- 莫奈风格画:https://ai-sample.oss-cn-hangzhou.aliyuncs.com/pipcook/datasets/image-generation-cycle-gan/monet2photo.zip
- 冬天和夏天:https://ai-sample.oss-cn-hangzhou.aliyuncs.com/pipcook/datasets/image-generation-cycle-gan/summer2winter_yosemite.zip
总结
读者到这里已经学会如何使用 Pipcook 实现图片风格迁移,下一篇文章,我们将使用 Pipcook 来看看如何通过文本创作类模型来创作中文诗歌。
推荐JavaScript学习相关文章
《Angular v10.0.0 正式发布,不再支持 IE9/10》
《「实践」浏览器中的画中画(Picture-in-Picture)模式及其 API》
《「多图」一文带你彻底搞懂 Web Workers (上)》
《「多图」一文带你彻底搞懂 Web Workers (中)》
《webpack4主流程源码解说以及动手实现一个简单的webpack(上)》
《webpack4主流程源码解说以及动手实现一个简单的webpack(下)》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)上》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)中》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)下》
《一文带你搞懂 babel-plugin-import 插件(上)「源码解析」》
《一文带你搞懂 babel-plugin-import 插件(下)「源码解析」》
《教你如何使用内联框架元素 IFrames 的沙箱属性提高安全性?》
《细说DOM API中append和appendChild的三个不同点》
《NodeX Component - 滴滴集团 Node.js 生态组件体系「实践」》
《浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务》
《了不起的 Webpack HMR 学习指南(上)「含源码讲解」》
《了不起的 Webpack HMR 学习指南(下)「含源码讲解」》
《图解 Promise 实现原理(二):Promise 链式调用》
《图解 Promise 实现原理(三):Promise 原型方法实现》
《图解 Promise 实现原理(四):Promise 静态方法实现》
《使用Service Worker让你的 Web 应用如虎添翼(上)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(中)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(下)「干货」》
《一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索》
《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」》
《手把手教你7个有趣的JavaScript 项目-上「附源码」》
《手把手教你7个有趣的JavaScript 项目-下「附源码」》
《JavaScript 使用 mediaDevices API 访问摄像头自拍》
《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》
《可视化的 JS:动态图演示 - 事件循环 Event Loop的过程》
《可视化的 js:动态图演示 Promises & Async/Await 的过程》
《Pug 3.0.0正式发布,不再支持 Node.js 6/8》
《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》
《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》
《JavaScript 已进入第三个时代,未来将何去何从?》
《前端上传前预览文件 image、text、json、video、audio「实践」》
《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》
《推荐13个有用的JavaScript数组技巧「值得收藏」》
《36个工作中常用的JavaScript函数片段「值得收藏」》
《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》
《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》
《JavaScript正则深入以及10个非常有意思的正则实战》
《前端开发规范:命名规范、html规范、css规范、js规范》
《100个原生JavaScript代码片段知识点详细汇总【实践】》
《手把手教你深入巩固JavaScript知识体系【思维导图】》
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》
《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《面试中教你绕过关于 JavaScript 作用域的 5 个坑》
作者:牟牟
转发链接:https://mp.weixin.qq.com/s/3uZQqgjFgImTIATcr-oMRA
本文暂时没有评论,来添加一个吧(●'◡'●)