Tensorflow DeepDream Пример утечки памяти? - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть блокнот jupyter из начального банка Google Colab, и в нем есть пример для Deap Dream, в котором он выполняет итерацию на выходном изображении и увеличивает масштаб после каждой итерации, создавая эффект масштабирования. Я заметил, что после многих шагов масштабирования у моего компьютера заканчивается оперативная память. Я слышал, как люди говорят, что вы не должны строить график во время итераций, но я не уверен, где в моем коде я это делаю?

with open("pumpkinresized.jpg", 'rb') as f:
file_contents = f.read()

#from PIL import Image
#img = Image.open('pumpkin.jpg')
#new_img = img.resize((500,500))
#new_img.save("pumpkinresized.jpg", "JPEG", optimize=True)
#file_contents = new_img.read()

from io import BytesIO
from IPython.display import clear_output, Image, display
import numpy as np
import PIL.Image
import tensorflow as tf
from __future__ import print_function
import os
import zipfile
import matplotlib.pyplot

model_fn = 'tensorflow_inception_graph.pb'

# creating TensorFlow session and loading the model
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)
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') # define the input tensor
imagenet_mean = 117.0
t_preprocessed = tf.expand_dims(t_input-imagenet_mean, 0)
tf.import_graph_def(graph_def, {'input':t_preprocessed})

def T(layer):
    '''Helper for getting layer output tensor'''
    return graph.get_tensor_by_name("import/%s:0"%layer)


def showarray(a, fmt='jpeg',i=0):
    a = np.uint8(np.clip(a, 0, 255))
    f = BytesIO()
    PIL.Image.fromarray(a).save(f, fmt)
    matplotlib.pyplot.imsave(str(i) + ".png",a)
    display(Image(data=f.getvalue()))
img0 = sess.run(tf.image.decode_image(file_contents))
showarray(img0)


octave_n = 4
octave_scale = 1.4
iter_n = 10
strength = 200

# Helper function that uses TensorFlow to resize an image
def resize(img, new_size):
    return sess.run(tf.image.resize_bilinear(img[np.newaxis,:], new_size))[0]

# Apply gradients to an image in a seires of tiles
def calc_grad_tiled(img, t_grad, tile_size=256):
    '''Random shifts are applied to the image to blur tile boundaries over
    multiple iterations.'''
    h, w = img.shape[:2]
    sx, sy = np.random.randint(tile_size, size=2)
    # We randomly roll the image in x and y to avoid seams between tiles.
    img_shift = np.roll(np.roll(img, sx, 1), sy, 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):
            sub = img_shift[y:y+tile_size,x:x+tile_size]
            g = sess.run(t_grad, {t_input:sub})
            grad[y:y+tile_size,x:x+tile_size] = g
    imggrad = np.roll(np.roll(grad, -sx, 1), -sy, 0)
    # Add the image gradient to the image and return the result
    return img + imggrad*(strength * 0.01 / (np.abs(imggrad).mean()+1e-7))

# Applies deepdream at multiple scales
def render_deepdream(t_obj, input_img, show_steps = True):
    # Collapse the optimization objective to a single number (the loss)
    t_score = tf.reduce_mean(t_obj)
    # We need the gradient of the image with respect to the objective
    t_grad = tf.gradients(t_score, t_input)[0]

    # split the image into a number of octaves (laplacian pyramid)
    img = input_img
    octaves = []
    for i in range(octave_n-1):
        lo = resize(img, np.int32(np.float32(img.shape[:2])/octave_scale))
        octaves.append(img-resize(lo, img.shape[:2]))
        img = lo

    # generate details octave by octave
    for octave in range(octave_n):
        if octave>0:
            hi = octaves[-octave]
            img = resize(img, hi.shape[:2])+hi
        for i in range(iter_n):
            img = calc_grad_tiled(img, t_grad)
        if show_steps:
            clear_output()
            showarray(img)
    return img

А вот и цикл:

layer = "mixed4d_3x3_bottleneck_pre_relu"  #@param ["mixed4d_3x3_bottleneck_pre_relu", "mixed3a", "mixed3b", "mixed4a", "mixed4c", "mixed5a"]
iter_n = 12 #@param {type:"slider", max: 50}
strength = 120 #@param {type:"slider", max: 1000}
zooming_steps = 500 #@param {type:"slider", max: 512}
zoom_factor = 1.1 #@param {type:"number"}

tf.get_default_graph().finalize

frame = img0
img_y, img_x, _ = img0.shape
for i in range(zooming_steps):
  if i > 20:
    layer = "mixed3a"
  if i > 40:
    layer = "mixed4a"

  if i > 70:
    layer = "mixed4d_3x3_bottleneck_pre_relu"

  if i > 100:
    layer = "mixed5a"

  frame = render_deepdream(tf.square(T(layer)), frame, False)
  clear_output()
  showarray(frame,i=i)
  print("iteration: " +str(i))
  newsize = np.int32(np.float32(frame.shape[:2])*zoom_factor)
  frame = resize(frame, newsize)
  frame = frame[(newsize[0]-img_y)//2:(newsize[0]-img_y)//2+img_y,
                (newsize[1]-img_x)//2:(newsize[1]-img_x)//2+img_x,:]

Есть идеи, что я могу изменить, чтобы предотвратить утечку памяти? Есть ли в цикле что-то, чего не должно быть?

...