利用神经网络让Shader纯数学绘制任意图片

  • 背景
  • 基本原理介绍
  • 工具准备
  • 训练神经网络
  • 模型数学逻辑说明
  • 模型数据shader代码
  • 结果

背景

这个 idea 来自 iq 大佬的 这个shadertoy项目(链接处的shader需要编译一段时间才能看到效果),把神经网络和Shader巧妙地组合起来了,真的好酷啊!
那么,这里我来简单复现一下他的工作吧。

基本原理介绍

我们知道,shadertoy 上面写的 shader 其实就是一个片元着色器,每个像素将并行执行对应逻辑。
神经网络得到的模型其实就是把输入数据进行一定操作获得输出数据,比如对于传统神经网络其实每层就是乘以权重矩阵加上偏差矩阵再经过激活函数处理就可以了。
如果我们把这两个结合起来,把屏幕坐标作为神经网络的输入,图片的颜色作为神经网络的输出,让神经网络训练获得模型。
我们只要把经过训练好的神经网络模型翻译成 glsl 就可以让 shader 显示出指定的图片了!

工具准备

神经网络相关:python、keras
shader相关:在线的如 shadertoy 或者本地的比如vscode插件

训练神经网络

前面已经说了,确定好输入为屏幕坐标(二维数据),输出为图片颜色(三维数据),构建对应神经网络模型就行。我选择的参数为:

model = keras.Sequential([tf.keras.layers.Dense(2, activation = 'relu', input_shape = (2,)),tf.keras.layers.Dense(16, activation = 'relu'),tf.keras.layers.Dense(32, activation = 'relu'),tf.keras.layers.Dense(64, activation = 'relu'),tf.keras.layers.Dense(16, activation = 'relu'),tf.keras.layers.Dense(3, activation = 'sigmoid')])

在我的电脑上,差不多训练二十多分钟就可以得到比较合适的模型了

模型数学逻辑说明

模型数据转shader代码需要我们对神经网络模型的数学构造有一点点了解。对于一个如下的传统神经网络模型

其中间层的每一个元素的计算公式为:
x j ( n ) = Σ i ( w j i ( n , n − 1 ) x i ( n − 1 ) ) + b i ( n ) x^{(n)}_j = \Sigma_i (w^{(n,n-1)}_{ji} x^{(n-1)}_i) + b^{(n)}_i xj(n)​=Σi​(wji(n,n−1)​xi(n−1)​)+bi(n)​ x j ( n ) = f ( n ) ( x j ( n ) ) x^{(n)}_j = f^{(n)}(x^{(n)}_j) xj(n)​=f(n)(xj(n)​)
其中:
x j ( n ) x^{(n)}_j xj(n)​ 指的是第 n n n层第 j j j个参数
w j i ( n , n − 1 ) w^{(n,n-1)}_{ji} wji(n,n−1)​ 指的是第 n − 1 n-1 n−1 层第 i i i 个参数对第 n n n 层第 j j j 个参数的权重影响
b i ( n ) b^{(n)}_i bi(n)​ 指的是第 n n n 层第 i i i 个参数的 b i a s bias bias
f ( n ) f^{(n)} f(n)是激活函数

我们可以简单地获取到模型的权重、bias,激活函数又是我们训练时候选取的。
relu 就是 f r e l u ( x ) = m a x ( 0 , x ) f_{relu}(x)=max(0, x) frelu​(x)=max(0,x)
sigmoid 就是 f s i g m o i d ( x ) = 1 1 + e − x f_{sigmoid}(x)=\frac{1}{1+e^{-x}} fsigmoid​(x)=1+e−x1​

知道了这些,我们就足以把简单的神经网络模型翻译成 shader 语言了!

模型数据shader代码

我们举个简单的例子,如果输入模型特别简单,输入为2个神经元,输出为2个神经元,没有隐藏层,权重为
0.1 0.3 0.2 0.4 \begin{matrix} 0.1 & 0.3 \\ 0.2 & 0.4 \end{matrix} 0.10.2​0.30.4​
bias 为
0.5 0.6 \begin{matrix} 0.5 \\ 0.6 \end{matrix} 0.50.6​
对应的示意 glsl 代码就是

float x_1_0 = 0.1 * x_0_0 + 0.3 * x_0_1 + 0.5;
x_1_0 = sigmoid(x_1_0);
float x_1_1 = 0.2 * x_0_0 + 0.4 * x_0_1 + 0.6;
x_1_1 = sigmoid(x_1_1);

这里 x_0_0x_0_1指的就是输入层的两个数据,x_1_0x_1_1就是输出层的两个数据。
基本原理就是这样,我们可以简单写个转换脚本,将上面keras训练得到的模型翻译成对应的 shader 代码就行了。

结果

如果想要参考一下我的代码,项目参见我的 github 仓库:ShadertoyNNImage
我选取的参考图为:

得到的结果为:

如果要自己实现,有几点需要注意:

  • 为了shader适应不同分辨率,神经网络输入的坐标最好变化到 [-1, 1],并做下分辨率适配
  • 由于参数比较多,编译shader需要比较长时间,差不多需要半分钟,请耐心等待
  • 神经网络模型数据比原始图片都要大很多,仅供学习和娱乐

github 仓库链接:ShadertoyNNImage

利用神经网络让Shader纯数学绘制任意图片相关推荐

  1. 图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网络生成手写体数字数据(tensorflow)

    图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网络生成手写体数字数据(tensorflow) 文章目录 图像对抗生成网络 GAN学习01:从头搭建最简单的GAN网络,利用神经网 ...

  2. AI赋能5G,利用神经网络进行信道估计

    随着5G和AI技术不断成熟和发展,如今基于AI辅助的无线通信正逐步从学术界走向产业界落地. 1 2022MWC上的5G+AI 近日举行的2022年世界移动通信大会(MWC)上,各大通信玩家纷纷拿出自己 ...

  3. 从图形角度利用神经网络进行选股

    做了一个很low的基于神经网络的选股策略,回测效果惨淡,仅供大家学习使用,带大家入门深度学习. 问题转化与模型选择 首先对于选股这个问题,如果要利用神经网络的话,需要将其转化为有监督学习问题,一般情况 ...

  4. 如何利用神经网络结合遗传算法进行非线性函数极值寻优(2)

    如何利用神经网络结合遗传算法进行非线性函数极值寻优

  5. NVIDIA团队:利用神经网络生成极慢视频

    NVIDIA团队:利用神经网络生成极慢视频 总有那么一些细节,你瞪大双眼拼了命想看清却依然奈不了何,比如下面这个: 跟得上球吗?要看清男子羽毛球比赛的细节实在不容易 有时候想盯住飞来飞去的羽毛球,非常 ...

  6. 用python画玫瑰花教程-利用Python的turtle库绘制玫瑰教程

    用Python的turtle库绘图是很简单的,闲来无事就画了一个玫瑰花,下面奉上源码.... 源码: ''' Created on Nov 18, 2017 @author: QiZhao ''' i ...

  7. matlab 数字识别_在MATLAB中利用神经网络进行分类

    在这篇文章中,主要阐述在MATLAB环境下利用神经网络对输入的数字图像进行识别.我们利用一个5*5的矩阵来表示1-5的数据,如下图所示: 基于以上问题,我们构建的神经网络输入层的神经元个数为25个,即 ...

  8. ML之NN:利用神经网络的BP算法解决XOR类(异或非)问题(BP solve XOR Problem)

    ML之NN:利用神经网络的BP算法解决XOR类(异或非)问题(BP solve XOR Problem) 目录 输出结果 实现代码 输出结果 实现代码 #BP solve XOR Problem im ...

  9. php代码输出笑脸,利用HTML5中的Canvas绘制笑脸的代码

    这篇文章主要介绍了利用HTML5中的Canvas绘制一张笑脸的教程,使用Canvas进行绘图是HTML5中的基本功能,需要的朋友可以参考下 今天,你将学习一项称为Canvas(画布)的web技术,以及 ...

最新文章

  1. java如何构造ajax回调参数,jQuery实现ajax回调函数带入参数的方法示例
  2. VALVE SURVEY RESULTS
  3. 大厂提供什么样的软硬件来吸引人才?
  4. 第三次学JAVA再学不好就吃翔(part3)--基础语法之常量
  5. nodejs简单层级结构配置文件
  6. es6 includes(), startsWith(), endsWith()
  7. [转]ssh常用用法小结
  8. 在Windows系统下搭建ELK日志分析平台
  9. 系统调用之creat
  10. Linux中service命令和/etc/init.d/的关系
  11. cs231n学习笔记-激活函数-BN-参数优化
  12. launching IDEA-If you already have a 64-bit JDK installed, define a JAVA_HOME...问题解析处理
  13. 如何在POWER BI中翻转90度显示标题?
  14. PHP玄帧道长,青龙道长率众弟子朝真“凝真宫”
  15. 关于SQLite创建视图
  16. Ping IPv6在线测试检测 testipv6 加速镜像
  17. Android音乐播放器(高分课设)
  18. 习题3-5 三角形判断 (15 分)-PTA浙大版《C语言程序设计(第4版)》
  19. lm283_BP283X 最小输入输出压差和OVP电压的关系
  20. PowerDesigner删除外键关系,而不删除外键列

热门文章

  1. 这篇文章带你认识一款优秀国产云原生数据库 ,它就是《阿里 PolarDB》数据库
  2. 从体质上能知道什么,为什么胖?为什么瘦?
  3. 安农大计算机研究生怎么样,安徽农业大学考研难吗?一般要什么水平才可以进入?...
  4. 了解苹果自动驾驶“窃密”事件始末,嫌疑人或将面临10年监禁、 25 万美元罚款... 1
  5. 使用jquery移除元素事件
  6. Python3,好看的外(shen)表(cai)千篇一律,炫彩的日志万里挑一。
  7. Byobu 使用技巧
  8. java分时共享办公系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  9. Centos7主机名变成bogon的原因及解决方法
  10. ubuntu/linux系统知识(24)ubuntu自带的录屏软件