tensorflow: deep_dream代码及原理分析

deep_dream:

tensorflow_inception_graph.pb 下载地址:https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip

#-*-coding:utf-8-*-
import tensorflow as tf
import numpy as np
import scipy.misc

graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)

##data_preprocess
t_input = tf.placeholder(np.float32, name='input')
imagenet_mean = 117.0
t_preprocessed = tf.expand_dims(t_input - imagenet_mean, 0)

## load the model
model = 'tensorflow_inception_graph.pb'
with tf.gfile.FastGFile(model, 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def,{'input':t_preprocessed})

##test :print out options in grapg
# layers = [op.name for op in graph.get_operations() if op.type=='Conv2D' and 'import/' in op.name]
# print(len(layers))
# for item in layers:
#     print(item)
# item = 'import/mixed5b_pool_reduce_pre_relu/conv:0'
# print('shape of %s:%s'%(item,str(graph.get_tensor_by_name(item).get_shape())))

##save array as image
def savearray(img_array,img_name):
    scipy.misc.toimage(img_array).save(img_name)
    print('img save as:%s'%(img_name))


##generate dream image
def deep_dream(feature_map,img_input,iter_n=20,learning_rate=1):
    score = tf.reduce_mean(feature_map)
    gradient = tf.gradients(score,t_input)[0]

    img_out = img_input.copy()

    for i in range(iter_n):
        g,s = sess.run([gradient,score],feed_dict={t_input:img_out})

        g_std = g.std()
        g = g/(g_std+1e-8)

        img_out = img_out + g*learning_rate

        print('step = %03d,score = %f'%(i,s))

    savearray(img_out, 'my_deep_dream.jpg')

##main
def main(_):
    layer_name = 'mixed5b_pool_reduce_pre_relu'
    tensor_feature = graph.get_tensor_by_name('import/%s/conv:0'%(layer_name))
    channel = 100
    feature_map = tensor_feature[:,:,:,channel]

    img_input = np.random.uniform(size=(256,256,3))+100

    deep_dream(feature_map,img_input)

if __name__=='__main__':
    tf.app.run()

结果图:

deep_dream 原理分析:

我们从神经网络中学到了什么?

1)神经网络在训练结束后,保存的模型只包含网络结构与加权、偏置等参数,每个layer中的tensor只保留了对应的shape(更严格说只有tensor的维数和通道数两个参数),而没有实际内容,tensor的具体内容需要有具体的输入数据后才产生。

2)神经网络中的某个layer得到的tensor中的某个channel的feature_map对最后的输出有多大贡献,与该feature_map的均值成正相关,如果该feature_map的均值越大,其卷积后或展平后,在加权输出的时候,所占的比例就越大,对最终结果的影响就越大。所以,我们可以设计网络,让输入成为自变量,网络参数是固定值,某feature_map的均值是因变量,看看是怎样的输入使得该feature_map的均值最大,间接地反映该feature_map对什么输入最敏感,即该feature_map提取了什么特征。

deep_dream就是采用第二种方式查看feature_map学习到了什么特征(或对什么特征敏感/有感觉)

deep_dream的feature_map均值最大化原理:梯度上升法,用均值对输入图像求偏导矩阵,将该偏导矩阵累加到输入图像上,逐步迭代。

ps:个人见解,如有不当,请多指教。

 

猜你喜欢

转载自blog.csdn.net/Strive_For_Future/article/details/81748036
今日推荐