本文首发于微信公众号——世界上有意思的事,搬运转载请注明出处,不然将追究版权责任。微信号:a1018998632,交流qq群:859640274 node
最近学了近一个月半月的深度学习,因此想检验一下学习成果。正好毕设是图像处理APP的实现,因此就把快速风格迁移 的前馈神经网络 经过Tensorflow for Android 移植到了APP上面,做为滤镜快速风格迁移的 效果还挺不错,就是速度有点慢。可能和如今Android端的深度学习还不支持gpu有关吧。android
1.关于MyPhotoShop
这是一个图片处理APP,里面使用了Opencv、深度学习、MVVM、Databinding、RxJava、各类设计模式等等 ,在后面一段时间我会写一系列博客来一步步剖析这个项目,但愿你们能多多关注。git
1.效果
2.项目相关
3.缺点
1.没有组件化
2.没有混淆
3.有些地方抽象不够
2.深度学习和神经网络的基本概念
1.什么是深度学习
1.AI--》机器学习--》深度学习,前面三个概念是递进的,简单来讲深度学习 是机器学习的一种,深度学习 就是利用机器来学习不少数据,而机器学习又是实现AI的一种方式。
2.在深度学习中有两个重要的东西:数据和神经网络。在深度学习中有两个重要的过程:训练和测试
1.数据和网络:
1.数据:咱们想象一个简单的图片分类场景,咱们有10000张已经被人工分好类的图片,每张图片都有一个正确的分类,好比猫、狗等等。
2.网络:这里的神经网络 咱们能够想象成一个函数,咱们的输入是一张图片,输出则是这张图片在每一个分类下面的分数。也就是一个分数的数组。
2.训练和测试:
1.训练:在训练的时候咱们会将图片集中的图片一次次的输入到神经网络 里面去,而后会一次次获得该图片在每一个分类下的分数,每当咱们得出了一个分数数组以后咱们能够计算当前的神经网络 的损失值(当前的网络准确率越高损失值越低) ,有了损失值 ,咱们的目标就是下降损失值 。了解导数的同窗都知道咱们能够经过求导损失值函数 获得让损失值 下降的梯度方向,而后反馈到神经网络 中。就这样一次次的循环,让损失值 降到最低。
2.测试:当咱们将神经网络 训练到了一个最佳的状态,咱们就能够将咱们须要进行分类的图片,输入到神经网络 中,获得最终神经网络 对该图片分类的结果。
3.总结:深度学习究竟是怎么学习的呢?咱们能够看见咱们的训练数据是通过人的处理的,那么深度学习的过程就是将人的处理过程固化到咱们的神经网络 中,最终让神经网络 来代替人工处理的过程。
4.上面只是介绍深度学习的基本流程,若是要更深刻的了解能够看这篇博客
2.什么是神经网络
咱们在上一节中说到了,最终人处理数据的过程经过咱们的训练被固化到神经网络 中去了。下面我会简单介绍一下前面说到的神经网络 。程序员
1.仍是在简单的图片分类场景:
1.咱们假设图片为x的大小为100 * 100(咱们把图片平铺成为1 * 10000的矩阵),图片一共有10个分类。
2.那么一个两层的神经网络 就是这样的:y = x * w1 * w2(w1为 10000 * a的矩阵,w2为a * 10的矩阵),这里最终y就是一张图片在各个分类下的分数,式子中的乘法是矩阵乘法。
3.固然层数更多的神经网络 就是有更多的w,咱们w1 和 w2中的a能够本身定义。
2.解释一下y = x * w1 * w2:
1.研究代表咱们在看x这张图片的时候,咱们会先看图片的轮廓,这里咱们大脑中看图片轮廓的神经元就至关于w1
2.看完轮廓以后咱们会对这个图片中的东西有基本感受,判断这张图片属于哪些类别,这里的类别就是x * w1的结果
3.2中的结果会被输入大脑中下一层神经元,这里的神经元就至关于w2,通过w2以后咱们就会输出一个结果这里就是y。
4.固然人的神经元层数远比上面说到的多
3.训练y = x * w1 * w2的过程以人作对比就至关于:咱们有一堆图片给一个啥也不懂的小孩看,刚开始他确定输出的结果都是错的,可是咱们只要每次纠正一下他的错误,那么他脑壳中的神经元(w)就会不断的修改而后识别的准确率不断提升。
3.Android中的Tensorflow
这一节将会介绍如何在Android中使用已经训练好的神经网络 github
1.开始
本篇文章中,我只会以一个demo为例子进行讲解,前面提到的MyPhotoShop 项目会另起一个专题进行剖析。编程
1.demo地址:github地址
2.引入Tensorflow:compile 'org.tensorflow:tensorflow-android:+'
2.Tensorflow中的概念
1.图(graph):咱们在前面讲解了一个神经网络 是什么样子的,在Tensorflow中神经网络 的每一个神经元w都属于图中的一个节点,神经网络 所有的节点就构成了一个有向无环图也就是Tensorflow的图的一部分。固然Tensorflow的图中除了神经网络 的节点外,还有其余辅助的操做:好比图片解码、图片编码、图片预处理操做等等。咱们举一个图的例子就是:图片a--》解码图片产生b--》处理b产生图片数据矩阵c(1 * 10000)--》c与w1(10000 * x)矩阵相乘产生d(1 * x)--》d与w2(x * 10)矩阵相乘产生e(1 * 10)--》选出e中值最大的分类,神经网络 就判断图片a是这种分类的图片。
2.节点(node):每一个节点都是图的一部分,每一个节点有:入参、出参、具体操做函数(好比矩阵乘法)、可能有神经元值w。
3.TensorFlowInferenceInterface:一个Tensorflow中训练的上下文,在不一样语言中名字不一样。内部包含了一个训练中须要的所有实例。
3.demo代码讲解
咱们本次demo中只涉及Tensorflow在Android中神经网络 模型的使用,并不涉及训练的过程。缘由有两个:1.移动端并不适合训练神经网络 2.Tensorflow for Android没有训练的API。设计模式
1.我此次使用的神经网络 是已经训练好的快速风格迁移网络
2.对于模型咱们的输入是:一张图片转化为的float类型的张量,大小为(1 * 800 * 600 * 3),输入节点的名字是padsss:0 ,这里的名字是在训练过程当中定义的。
3.对于这个模型咱们的输出是:大小为(1 * 780 * 680 * 3)的float类型张量。输出节点的名字是squeezesss:0 ,名字也是在训练过程当中定义的。
4.咱们看代码,先用RxPermission获取了一下权限,获取成功以后将assets中须要处理的图片写入到sd卡中一遍后面使用,进入make()方法
5.将4中的图片读取到内存中
6.以ARGB为例咱们知道Bitmap中每一个像素是以int十六进制储存像素的,相似这种形式FFFFFFFF ,那么每两位就是一个通道的数值,上限是256。因此接下来就是将Bitmap中的像素值,转化为float类型的数组,数组大小是(800 * 600 * 3)。
7.建立了一个TensorFlowInferenceInterface对象,入参是AssetManager和模型文件,这里就表示将神经网络 在内存中创建起来
8.输出一下每一个节点的名字
9.向神经网络 中传入输入节点的名字、输入节点的数据、数据张量的维度
10.运行神经网络 ,入参是输出节点的名字
11.神经网络 的运行时阻塞的,因此运行好了以后,就能获取数据了,这里将数据存入(780 * 580 * 3)的float数组中。
12.将float数组从新整合成Bitmap的像素值,而后写入Bitmap中。
4.注意点
1.demo运行的时候速度会比较慢,耐心等待一下
2.我运行的设备是:小米mix二、Android8.0。其余设备可能会有问题,要么就是速度很是慢,还多是cpu或者系统版本不支持。
4.总结
在Android中运行一个已经训练好的神经网络 仍是比较简单的,只要知道了输入输出,就像运行一个普通的函数那么简单。至于如何去训练一个神经网络 ,那就是另外的故事了,能够关注个人我学机器学习 文集!里面会持续更新我学习机器学习的心得和体会。数组
不贩卖焦虑,也不标题党。分享一些这个世界上有意思的事情。题材包括且不限于:科幻、科学、科技、互联网、程序员、计算机编程。下面是个人微信公众号:世界上有意思的事 ,干货多多等你来看。 微信