前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[TensorFlow深度学习深入]实战四·使用DeepDream创造艺术画(机器如何创造艺术)

[TensorFlow深度学习深入]实战四·使用DeepDream创造艺术画(机器如何创造艺术)

作者头像
小宋是呢
发布2019-06-27 11:51:36
6750
发布2019-06-27 11:51:36
举报
文章被收录于专栏:深度应用

[TensorFlow深度学习深入]实战四·使用DeepDream创造艺术画(机器如何创造艺术)

代码

代码语言:javascript
复制
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

# -*- coding: utf-8 -*-

#加载库
import tensorflow as tf
import numpy as np
import cv2
from imageio import imread, imsave, mimsave
import matplotlib.pyplot as plt

from scipy.ndimage.filters import gaussian_filter


layer_names = ['conv2d0', 'conv2d1', 'conv2d2', 
               'mixed3a', 'mixed3b', 'mixed4a', 'mixed4b', 'mixed4c', 'mixed4d', 'mixed4e',
               'mixed5a', 'mixed5b']

#加载图片分类模型,这里使用inception5h

graph = tf.Graph()

with graph.as_default() :
    with tf.gfile.FastGFile('/Users/yss/YSSFiles/TFAPP/DeepDream/22 天马星空的DeepDream/inception5h.pb', 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        tf.import_graph_def(graph_def, name='')
    X = graph.get_tensor_by_name('input:0')
    layers = [graph.get_tensor_by_name(name + ':0') for name in layer_names]
    
    all_layers_names = [tensor.name for tensor in tf.get_default_graph().as_graph_def().node]
    print(all_layers_names)

sess = tf.Session(graph=graph)

#定义获取梯度tensor的函数、对原始图片按块计算梯度的函数

def get_gradient(tensor):
    with graph.as_default():
        return tf.gradients(tf.reduce_mean(tf.square(tensor)), X)[0]

def get_tile_size(num_pixels, tile_size=400):
    num_tiles = max(1, int(round(num_pixels / tile_size)))
    return int(np.ceil(num_pixels / num_tiles))
    
def tiled_gradient(gradient, image, tile_size=400):
    grad = np.zeros_like(image)
    H, W, _ = image.shape
    
    h = get_tile_size(H, tile_size)
    h_4 = h // 4
    w = get_tile_size(W, tile_size)
    w_4 = w // 4
    
    h_start = np.random.randint(-3 * h_4, -h_4)
    while h_start < H:
        h_end = h_start + h
        h_start_lim = max(h_start, 0)
        h_end_lim = min(h_end, H)
        
        w_start = np.random.randint(-3 * w_4, -w_4)
        while w_start < W:
            w_end = w_start + w
            w_start_lim = max(w_start, 0)
            w_end_lim = min(w_end, W)
            
            g = sess.run(gradient, feed_dict={X: [image[h_start_lim: h_end_lim, w_start_lim: w_end_lim, :]]})[0]
            g /= (np.std(g) + 1e-8)
            
            grad[h_start_lim: h_end_lim, w_start_lim: w_end_lim, :] = g
            
            w_start = w_end
        
        h_start = h_end
    
    return grad

#根据梯度调整输入图片,即DeepDream
def dream(layer_tensor, image, iteration=10, step=3.0, tile_size=400):
    img = image.copy()
    gradient = get_gradient(layer_tensor)
    
    for i in range(iteration):
        grad = tiled_gradient(gradient, img)
        
        sigma = (i * 4.0) / iteration + 0.5
        grad = gaussian_filter(grad, 0.5 * sigma) + gaussian_filter(grad, sigma) + gaussian_filter(grad, 2 * sigma)
        
        scaled_step = step / (np.std(grad) + 1e-8)
        img += grad * scaled_step
        img = np.clip(img, 0, 255)
        
    return img

#将原始图片进行缩放,对多个尺度进行DeepDream处理并叠加

def recursive_dream(layer_tensor, image, repeat=3, scale=0.7, blend=0.2, iteration=10, step=3.0, tile_size=400):
    if repeat > 0:
        sigma = 0.5
        img_blur = gaussian_filter(image, (sigma, sigma, 0.0))
        
        h0 = img_blur.shape[0]
        w0 = img_blur.shape[1]
        h1 = int(scale * h0)
        w1 = int(scale * w0)
        img_downscaled = cv2.resize(img_blur, (w1, h1))
        
        img_dream = recursive_dream(layer_tensor, img_downscaled, repeat - 1, scale, blend, iteration, step, tile_size)
        img_upscaled = cv2.resize(img_dream, (w0, h0))
        
        image = blend * image + (1.0 - blend) * img_upscaled
        image = np.clip(image, 0, 255)
    
    return dream(layer_tensor, image, iteration, step, tile_size)

#读取一张图片

image = imread('/Users/yss/YSSFiles/TFAPP/DeepDream/22 天马星空的DeepDream/mountain.jpg')
image = image.astype(np.float32)

#分别以12个tensor的响应值作为优化目标,对原始图片进行处理

for i in range(len(layers)):
    print(layer_names[i])
    result = recursive_dream(layers[i], image)
    #plt.figure(figsize=(10, 15))
    #plt.imshow(result / 255.)
    #plt.show()
    imsave('/Users/yss/YSSFiles/TFAPP/DeepDream/22 天马星空的DeepDream/out/%s.jpg' % layer_names[i], result)

结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年12月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • [TensorFlow深度学习深入]实战四·使用DeepDream创造艺术画(机器如何创造艺术)
    • 代码
      • 结果
        • 参考
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档