前一段时间,我开发了Sketchify, 该工具可以把任何以SVG为渲染技术的可视化转化为手绘风格。(参考手绘风格的数据可视化实现 Sketchify)
那么问题来了,很多的chart是以Canvas为渲染技术的,那要怎么办?
我拍脑袋一想,为什么不使用深度学习技术来做呢?
原理很简单:
这听起来就像如何把大象放到冰箱里一样的简单直接。
废话少说,开始干。
数据准备要生成一定数量的原始图和手绘图,利用Sketchify就可以完成功能,但是具体如何做到?参考如下架构:
VizServer是一个web服务,用nodejs开发,代码在这里https://github.com/gangtao/handyModel/tree/master/vizService
VizServer使用restify提供RestAPI接口,利用squirrelly.js的模版引擎生成一个包含可视化的Html页面。模版如下:
<!doctype html>
<html>
<head>
<title>{{sketchify}}</title>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rough.js/3.1.0/rough.js"></script>
<script src="https://gw.alipayobjects.com/os/lib/antv/g2/3.4.10/dist/g2.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.data-set-0.10.1/dist/data-set.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/gangtao/sketchify/dist/sketchify.min.js"></script>
</head>
<body>
<div id="chart" style="height: 400px; width: 600px"></div>
</body>
<script>
$(function() {
var data = {{dataset| safe}};
var chart = new G2.Chart({
container: 'chart',
forceFit: true,
height: 400,
animate: false,
renderer: 'svg'
});
chart.source(data);
chart.scale('sales', {
tickInterval: 20
});
chart.interval().position('{{grammar}}'); //'year*sales'
chart.render();
{{if(options.sketchify === 1)}}
const container = $('#chart')[0];
const handler = Sketchifier(container, {});
handler.handify();
{{/if}}
});
</script>
</html>
数据准备好以后就可以训练神经网络了。
深度神经网络的训练往往比较消耗资源。最好有相当大的内存和GPU。有俩个免费的选择:
有了训练环境,导入数据,设一个神经网络,然后就可以训练了。这里省去若干介绍如何加载数据png,转换成tensor或tf的dataset。大家可以参考这些代码。
总之,大象还是没能顺利的放入冰箱,我训练的模型大都输出这样的手绘图。
离我的设想的输入差距比较大。为什么会失败呢?我想大概有以下这些原因。
总之,完成图像到图像的翻译任务,我们需要更复杂和高深的技术。
经研究我发现,这个任务是一个典型的图像到图像的翻译,例如前些日子火遍大江南北的deepfake,就是基于图像到图像的翻译。
有一些专门的的研究针对图像到图像的翻译任务。一个是CycleGan,另一个是pix2pix(Conditional GAN),这两个都是基于GAN(生成对抗网络)的,所以我们先简单讲讲GAN。 (参考 在浏览器中进行深度学习:TensorFlow.js (八)生成对抗网络 (GAN))
如上图所示,GAN包含两个互相对抗的网络:G(Generator)和D(Discriminator)。正如它的名字所暗示的那样,它们的功能分别是:
在训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量把G生成的图片和真实的图片分别开来。这样,G和D构成了一个动态的“博弈过程”。在最理想的状态下,G可以生成足以“以假乱真”的图片
https://github.com/junyanz/CycleGAN
实现图像间的翻译,借助GAN,应该有两个domain的鉴别器,每个鉴别器单独判断各自domain的数据是否是真实数据。至于generator,图像的翻译需要将domain A的图像翻成domain B的图像,所以generator有点像自编码器结构,只是decoder的输出不是domain A的图像,而是domain B的图像。为了充分利用两个discriminator,还应该有一个翻译回去的过程,也就是说,还有一个generator,它将domain B的数据翻译到domain A。
CycleGAN作者做了很多有意思的实验,包括horse2zebra,apple2orangle,以及风格迁移,如:对风景画加上梵高的风格。
Pix2pix
https://github.com/phillipi/pix2pix
pix2pix是基于条件对抗生成网络,关于CGAN和GAN的架构区别可以参考下图:
CGAN与GAN非常相似,除了生成器和鉴别器均以某些额外信息y为条件。可以通过将鉴别器和生成器作为附加输入层输入来执行这种调节。“ y”可以是任何种类的辅助信息,例如类别标签或来自其他模态的数据。在本教程中,我们将类标签用作“ y”。这里条件信息y是添加的额外条件信息,生成器G和鉴别器D都学会了以某些模式进行操作。例如,在面部生成应用程序的情况下,我们可以要求生成器生成带有微笑的面部,并询问鉴别器特定图像是否包含带有微笑的面部。
作者举了几个图像到图像翻译的应用例子,都挺有趣的。
好了拥有了强大的工具以后,后面的事情就比较简单了。
我利用前面提到的生成工具生成了400对bar chart的原始和手绘图,另外分别有100对测试和验证数据集。利用paperspace的免费GPU,运行https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix的pix2pix代码,使用缺省的参数,训练了200个epoch,每个epoch大概50秒,总共耗时3小时左右。
[Network G] Total number of parameters : 54.414 M
[Network D] Total number of parameters : 2.769 M
缺省的网络的参数数量如上图所示。
训练结果如下图:
上面两个是我的测试数据中的两个例子。A是原始域,B是手绘域。中间的fakeB是pix2pix模型根据原始A图生成的结果。我们看到该生成图形几乎可以乱真。
到这里是不是大功告成了呢?还没有,想想我们之前要解决的问题,对于任意的基于Canvas渲染的可视化图表,我们改如何运用该模型呢?这里我列出还需要做的工作:
本文给出了一个利用深度学习实现数据可视化到手绘风格转化的实际例子,利用机器学习或者深度学习解决一个具体的问题很有趣,但是要完成端到端的功能,需要很多很琐碎的知识和系统思考的能力。希望这个故事对你有所帮助。有问题请发评论给我。
Original url: Access
Created at: 2020-01-29 13:01:46
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论