У меня есть блокнот 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,:]
Есть идеи, что я могу изменить, чтобы предотвратить утечку памяти? Есть ли в цикле что-то, чего не должно быть?