Deep Dream是Google公司在2015年公布的一项有趣的技术。在训练好的卷积神经网络中,只需要设定几个参数,就可以通过这项技术生成一张图像。

假设输入网络的图像为x,网络输出的各个类别的概率为t,若一共有1000个分类,那么t是一个1000维的向量,代表了1000中类别的概率。假设香蕉类别的概率输出值为t[100],则t[100]的值代表了香蕉的概率,t[100]的值越高,香蕉的概率就越高。那么我们反过来想,将t[100]作为我们的优化目标,不断调整图像的值,使得t[100]的值尽可能的大,同时,图像也越来越具有香蕉的特征。

总而言之,图片越像香蕉,那么t[100]的值就越大,那么t[100]的值越大,图片就越像香蕉,我们通过不断调整图像增大t[100]的值,从而得到香蕉的图像或者说具有香蕉的特征的图像。

import numpy as np
import tensorflow as tf
import scipy.misc
import PIL.Image
from functools import partial#这里我们使用已经训练好的inception模型
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)
#导入模型
model_fn = 'tensorflow_inception_graph.pb'
with tf.gfile.FastGFile(model_fn,'rb') as f:graph_def  = tf.GraphDef()graph_def.ParseFromString(f.read())t_input = tf.placeholder(np.float32,name='input')
#由于inception模型的输入是去平均化的,这里我们也同时减去117实现去平均化
image_mean = 117
#由于input的格式是[batch,height,width,depth],这里我们添加batch维度
t_preprocessed = tf.expand_dims(t_input - image_mean,0)
tf.import_graph_def(graph_def,{'input':t_preprocessed})#对大张图片求梯度
#将大张的图片分成多个512*512的tile,分别对每个tile求梯度,最后将tile合并即可
def cal_grad_tiled(img,t_grad,tile_size=512):#对图像分别在x,y方向随机滑动,避免每个tile的边缘出现明显的分界线h,w = img.shape[:2]shift_x,shift_y = np.random.randint(tile_size,size=2)img_shift = np.roll(np.roll(img,shift_x,1),shift_y,0)grad = np.zeros_like(img)for y in range(0,max(h - tile_size//2,tile_size),tile_size):for x in range(0,max(w - tile_size//2,tile_size),tile_size):#在滑动后的img中截取一个tile,求出其梯度sub_img = img_shift[y:y+tile_size,x:x+tile_size]grad_sub = sess.run(t_grad,{t_input:sub_img})grad[y:y+tile_size,x:x+tile_size] = grad_sub#还原梯度图return np.roll(np.roll(grad,-shift_x,1),-shift_y,0)#对图像进行放缩,这样做是为了保证放缩前后像素的范围不会改变
def resize(img,ratio):min = img.min()max = img.max()img = (img - min) / (max - min) * 255img = np.float32(scipy.misc.imresize(img,ratio))img = img / 255 * (max - min) + minreturn img#将array保存为图像
def savearray(img_array,img_name):scipy.misc.toimage(img_array).save(img_name)print('img saved: %s '%img_name)#自定义一个5*5*3*3的卷积核
k = np.float32([1,4,6,4,1])
k = np.outer(k,k)
k5x5 = k[:,:,None,None] / k.sum() * np.eye(3,dtype=np.float32)#拉普拉斯金字塔分解及融合
def lap_split(img):with tf.name_scope('split'):#对图像进行卷积及反卷积后,图像会变得模糊,即失去了高频成分#将原图像与处理后的图像相减即可得到高频成分#多次处理后即可得到高频成分的金字塔及失去了高频成分的图像lo = tf.nn.conv2d(img,k5x5,[1,2,2,1],'SAME')lo2 = tf.nn.conv2d_transpose(lo,k5x5*4,tf.shape(img),[1,2,2,1],'SAME')hi = img - lo2return lo,hidef lap_split_n(img,n):levels = []for i in range(n):img,hi = lap_split(img)levels.append(hi)levels.append(img)return levels[::-1]#将失去高频成分后的图像从上往下融合高频成分
def lap_merge(levels):img = levels[0]for hi in levels[1:]:with tf.name_scope('merge'):img = tf.nn.conv2d_transpose(img,k5x5*4,tf.shape(hi),[1,2,2,1],'SAME') + hireturn img#标准化,除以方差使得高低频成分分布的方差为1,减小了高低频成分的差值,使得高低频成分的分布更加均衡
def normalize_std(img,eps=1e-10):with tf.name_scope('normalize'):std = tf.sqrt(tf.reduce_mean(tf.square(img)))return img / tf.maximum(std,eps)#将图像分解为拉普拉斯金字塔,对每一层都进行标准化,最后将每一层融合,得到拉普拉斯算法处理后的图像
def lap_normalize(img,scale_n=4):img = tf.expand_dims(img,0)tlevles = lap_split_n(img,scale_n)tlevles = list(map(normalize_std,tlevles))out = lap_merge(tlevles)return out[0,:,:,:]#只需要知道这是一个对Tensor定义的函数转化为对numpy.ndarray定义的函数即可
#即原函数输入和输出都是Tensor,转换后输入输入都是numpy.ndarray,且功能相同
def tffunc(*argtypes):placeholders = list(map(tf.placeholder, argtypes))def wrap(f):out = f(*placeholders)def wrapper(*args, **kw):return out.eval(dict(zip(placeholders, args)), session=kw.get('session'))return wrapperreturn wrapdef render_lapnorm(t_obj,img0,iter_n=10,learning_rate=1.,octave_n=3,octave_scale=1.4,lap_n=4):#t_obj是需要最大化的某个通道,我们的目标函数是这个通道的平均值,即最大化这个通道的平均值t_score = tf.reduce_mean(t_obj)#求目标函数对图像像素的梯度t_grad = tf.gradients(t_score,t_input)[0]#转换函数lap_norm_func = tffunc(np.float32)(partial(lap_normalize,scale_n=lap_n))#尽量不对img0产生影响img = img0.copy()#总体过程:放大图像,求梯度,对梯度进行拉普拉斯函数处理,使得高低频成分分布均衡,最后更新图像for octave in range(octave_n):if octave > 0:img = resize(img,octave_scale)for i in range(iter_n):g = cal_grad_tiled(img,t_grad)g = lap_norm_func(g)img += g * learning_rateprint('round:%s,iter:%s'%(octave,i))savearray(img,'lapnorm.jpg')if __name__ == '__main__':#test.jpg自己找即可#将图像转化为numpy.ndarray的格式img0 = PIL.Image.open('test.jpg')img0 = np.float32(img0)# img0 = np.random.uniform(size=(224,224,3)) + 100.0#我们使用这个卷基层的第139个通道进行优化name = 'mixed4d_3x3_bottleneck_pre_relu'#通道可以选择0-144channel = 139layer_output = graph.get_tensor_by_name('import/%s:0'%name)render_lapnorm(layer_output[:,:,:,channel],img0)

实验结果:
原图:

处理后:

原图:

处理后:

关于拉普拉斯金字塔,可以参考
https://blog.csdn.net/qq_37059483/article/details/77652921,
言而言之,图像每一次进行缩放(先缩小后放大)后,都会失去高频成分,具体表现为缩放后的图像比原图像更加模糊,使用原图减去处理后的图像,我们便能得到图像的高频成分。这样我们不断缩小放大图像,用原图像相减,我们就能得到一层层的高频成分,构成了高频成分的金字塔和最后失去了高频成分的图像。

我们对拉普拉斯金字塔的每一层进行标准化,使得高频成分和低频成分分布更加均匀,使得图像显得更加柔和,没有锐利的边角和线条。

inception模型下载地址:
https://pan.baidu.com/s/1i7pKvFf#list/path=%2Fbook_data%2Fchapter_4_data
密码:1kmf

TensorFlow实现Deep Dream相关推荐

  1. (tensorflow学习) Deep Dream原理及实现

    Deep Dream生成的图像 算法原理 卷积神经网络,我们输入一张图像后经过各种卷积池化等操作,最后分类出图片属于哪个类别. 可见卷积网络能提取图像中的相应特征.如图各个卷积层,如Conv1提取ed ...

  2. Deep Dream模型

    Deep Dream 是Google 公司在2015 年公布的一顶有趣的技术.在训练好的卷积神经网络中,只需要设定几个参数,就可以通过这项技术生成一张图像.生成出的图像不仅令人印象深刻,而且还能帮助我 ...

  3. TensorFlow学习笔记--Deep Dream模型

    零.目标 Deep Dream是谷歌推出的一个有意思的技术.在训练好的CNN上,设定几个参数就可以生成一张图象.具体目标是: 了解Deep Dream基本原理 掌握实现生成Deep Dream 模型 ...

  4. tensorflow练习8:实现Google的Deep Dream

    Google把自家生成图片的技术 Inceptionism 开源化,称之为 Deep Dream ,一个原本用来将图片分类的AI,让我们看到不一样的世界~在把一张图片喂入之后,选择某一层神经网路(Go ...

  5. Tensorflow入门(10)——Deep Dream

    一.模型 1.AlexNet 卷积神经网络的演进从LeNet到AlexNet到VGGNet.GoogleNet到ResNet.演进的方式是有一定规律的,并且它们也都在ImageNet LSVRC竞赛上 ...

  6. TF之DD:利用Inception模型+GD算法生成更高质量的Deep Dream高质量图片

    TF之DD:利用Inception模型+GD算法生成更高质量的Deep Dream高质量图片 目录 输出结果 设计思路 部分代码 输出结果 设计思路 部分代码 # coding:utf-8#TF之DD ...

  7. TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片

    TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片 目录 输出结果 设计思路 部分代码 输出结果 设计思路 部分代码 TF之TFDeepDream:生成更大尺寸 ...

  8. Deep Dream模型与实现

    Deep Dream是谷歌公司在2015年公布的一项有趣的技术.在训练好的卷积神经网络中,只需要设定几个参数,就可以通过这项技术生成一张图像. 本文章的代码和图片都放在我的github上,想实现本文代 ...

  9. CV之IG之Inception:基于TF框架利用Inception模型+GD算法的某层网络图像生成更高质量的Deep Dream幻觉梦境图片(特征可视化实现图像可解释性)案例应用

    CV之IG之Inception:基于TF框架利用Inception模型+GD算法的某层网络图像生成更高质量的Deep Dream幻觉梦境图片(特征可视化实现图像可解释性)案例应用 目录 基于TF框架利 ...

最新文章

  1. Java项目:宠物商城系统(java+Springboot+Maven+mybatis+Vue+mysql)
  2. bad cpu type in executable_【简讯】Intel将每5年重新开发一次CPU架构;华为EMUI 11曝光…...
  3. python处理excel表格实例-python2 对excel表格操作完整示例
  4. 姿态检测 树莓派_3.使用树莓派控制摄像头采集视频及运动检测
  5. Music Problem
  6. java 集成 kafka 0.8.2.1 适配jdk1.6
  7. VI操作--跳到最后一行和跳到最后一行的最后一个字符
  8. IBM原厂资深专家:DB2优化器和成本模型分析
  9. hbase sqoop 实验_Hive/hbase/sqoop的基本使用教程~
  10. 在Windows平台下实现《简明 Python 教程》第十章案例(利用winrar实现压缩备份)...
  11. 编译Android指定JDK/OpenJdk版本
  12. BaseAdapter使用的三种形式,逗比式,普通式,文艺式
  13. 惠普(HP) LaserJet Pro M1136 MFP 黑白多功能激光一体机 (打印 复印 扫描)驱动安装记录
  14. 达梦数据库的服务启动
  15. 微信支付的分账功能介绍
  16. 答读者:数学不好,能学好算法吗?
  17. 【 58沈剑 架构师之路】究竟啥才是互联网架构“高并发”
  18. SpringCloud服务之间调用,报异常Method has too many Body parameters: public abstract
  19. On children
  20. Drynx: 基于区块链的去中心化隐私保护机器学习系统

热门文章

  1. 蜜蜂剪辑 Apowersoft BeeCut 1.6.8.14 让剪辑更简单,全民都会用的视频剪辑软件
  2. 北理工计算机专业《多媒体技术》论文,多媒体技术学生论文,关于浅淡多媒体技术在计算机专业教学中的应用相关参考文献资料-免费论文范文...
  3. STC单片机程自动序软下载(软下载)实现
  4. 什么是双亲委派?如何打破双亲委派?
  5. 【参数不确定】敏感性分析(sensitivity analysis)
  6. 软件测试工程师的技能树
  7. 正在开发云ERP,业务功能与天心CS ERP一模一样, 欢迎大家指正
  8. [转帖]什么是“可转换可赎回优先股”?小米集团实例详解
  9. java 采集 cms_开源 java CMS - FreeCMS2.6 Web页面信息采集
  10. linux下三个好用的终端分屏工具