TensorFlow实战(五)Deep Dream(计算机生成梦幻图像)——理解深度神经网络结构及应用

一、疑问

  • 卷积层究竟学到了什么内容
  • 同一卷积层中不同通道学习到的内容有什么区别
  • 浅层的卷积和深层的卷积学习到的内容有什么区别

二、Deep Dream技术原理

Deep Dream生成梦幻图像

1. 利用CNN进行图像分类:

CNN的图像分类

2. Deep Dream

使用梯度上升的方法可视化网络每一层的特征,即用一张噪声图像输入网络,反向更新的时候不更新网络权重,而是更新初始图像的像素值,(这里卷积神经网络是固定的,使用预训练好的ImageNet图像识别模型),以这种“训练图像”的方式可视化网络

Deep Dream技术原理

Deep Dream技术原理

三、Inception模型文件导入与卷积层分析

1. 模型的加载

TensorFlow提供了以下两种方式来存储和加载模型:

  • 生成检查点文件(checkpoint file),拓展名一般为.ckpt,通过在tf.train.Saver对象上调用Saver.save()生成,通过saver.restore()来加载。
  • 生成图协议文件(graph proto file),这是一个二进制文件,拓展名一般为.pb,用tf.train.write_graph()保存,然后使用tf.import_graph_def()来加载图。

2. 图模型的加载

#图模型的加载

import tensorflow as tf
# 图的保存
v = tf.Variable(1.0, name='my_variable')
with tf.Session() as sess:
    tf.train.write_graph(sess.graph_def,'./tfmodel','test_pb.pb',as_text=False)
# 图的加载
with tf.Session() as sess:
    with tf.gfile.FastGFile('./tfmodel/test_pb.pb','rb')as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        sess.graph.as_default()
        tf.import_graph_def(graph_def,name='tf.graph')
        print(graph_def)

3. 导入Inception模型

# 导入库
from _future_ import print_function
import os
from io import BytestIO
import numpy as np
from functools import partial
import PIL.Image
import scipy.misc
import tensorflow as tf

# 创建图和会话
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)

# 导入Inception网络
model_fn = 'tensorflow_inception_graph.pb'
# tensorflow_inception_graph.pb文件的下载:
# https://storage.gooleapis.com/download.tensorflow.org/models/inception5h.zip

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')

# 图像预处理——减均值
imagenet_mean = 117.0
# 在训练Inception模型时做了减均值预处理,此处也需减同样的均值以保持一致

# 图像预处理——增加维度
# 图像数据格式一般是(height, width, channels),为同时将多张图片输入网络而在前面增加一维
# tf.expand_dims(input,dim,name=None)
# 向tensor插入维度1,插入位置就是参数代表的位置(维度从0开始)
t_preprocessed = tf.expand_dims(t_input - imagenet_mean, 0)


# 导入模型并将经预处理的图像送入网络中
tf.import_graph_def(graph_def,{'input':t_preprocessed})

4. 图的基本操作

  • 创建、重置和获得默认图
import numpy as np
import tensorflow as tf

g = tf.Graph() # 创建新的图
with g.as_default():
    c1 = tf.constant(0,0) # 在新图中添加变量
    print(c1) #Tensor("Const:0", shape=(), dtype = float32)
    # 可通过变量的'.graph'可获得其所在的图
    print("c1.graph:", c1.graph) 
    #c1.graph:
    
tf.reset_default_graph() # 重置默认图
g2 = tf.get_default_graph() # 获得默认图
print("g2:", g2) 
#g2:
  • 获取张量:get_tensor_by_name
# 先获取张量的名字
print(c1.name) #Const:0
# 然后将张量名字放到tf.Graph().get_tensor_by_name(name="")中
t = g.get_tensor_by_name(name = "Const:0")
# 通过打印 t 验证get_tensor_by_name所获取的张量就是前面定义的张量c1
print(t) #Tensor("Const:0",shape=(),dtype=float32)
  • 获取节点操作:get_operation_by_name
a = tf.constant([[1.0,2.0]])
b = tf.constant([[1.0],[2.0]])

tensor1 = tf.matmul(a,b,name='example_op')
print(tensor1) #Tensor("example_op:0",shape=(1,1),dtype=float32)
print(tensor1.name) #example_op:0

# 先把op的名字打印出来
print(tensor1.op.name) #example_op
# 然后get_operation_by_name函数
test_op = g2.get_operation_by_name("example_op")
print(test_op)

5. 模型中各卷积层分析

# 找出卷积层
layers = [op.name for op in graph.get_operations() if op.type == 'Conv2D'] 
# 输出卷积层层数
print('Number of layers',len(layers))
#Number of layers 59
# 输出所有卷积层名称
print(layers)

# 还可输出指定卷积层的参数
name1 = 'mixed4d_3x3_bottleneck_pre_relu'
print('shape of %s:%s' % (name1,str(graph.get_tensor_by_name('import/'+name1+':0').get_shape())))

四、Deep Dream图像生成

1. 以背景图像为起点生成Deep Dream图像

背景图像

生成的Deep Dream图像

2. 生成原始Deep Dream图像

可视化卷积层

你可能感兴趣的:(TensorFlow实战(五)Deep Dream(计算机生成梦幻图像)——理解深度神经网络结构及应用)