Tensorflow se queda sin memoria mientras se calcula: ¿cómo encontrar memory leaks?

Realizo repetidamente imágenes de ensueño en un directorio utilizando la implementación de TensorFlow DeepDream de Google ( https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb ).

Mi código es el siguiente:

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 render_deepdream(t_obj, img0=img_noise, iter_n=10, step=1.5, octave_n=4, octave_scale=1.4): t_score = tf.reduce_mean(t_obj) # defining the optimization objective t_grad = tf.gradients(t_score, t_input)[0] # behold the power of automatic differentiation! # split the image into a number of octaves img = img0 octaves = [] for i in range(octave_n-1): hw = img.shape[:2] lo = resize(img, np.int32(np.float32(hw)/octave_scale)) hi = img-resize(lo, hw) img = lo octaves.append(hi) # 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): g = calc_grad_tiled(img, t_grad) img += g*(step / (np.abs(g).mean()+1e-7)) #print('.',end = ' ') #clear_output() #showarray(img/255.0) return img/255.0 def morphPicture(filename1,filename2,blend,width): img1 = PIL.Image.open(filename1) img2 = PIL.Image.open(filename2) if width is not 0: img2 = resizePicture(filename2,width) finalImage= PIL.Image.blend(img1, img2, blend) del img1 del img2 return finalImage def save_array(arr, name,direc, ext="png"): img = np.uint8(np.clip(arr, 0, 1)*255) img =cv2.cvtColor(img, cv2.COLOR_RGB2BGR) cv2.imwrite("{d}/{n}.{e}".format(d=direc, n=name, e=ext), img) del img framesDir = "my directory" os.chdir(framesDir) outputDir ="my directory" for file in os.listdir(framesDir): img0 = PIL.Image.open(file) img0 = np.float32(img0) dreamedImage = render_deepdream(tf.square(T('mixed4c')),img0,iter_n=3,octave_n=6) save_array(dreamedImage,1,outputDir,'jpg') break i=1 j=0 with tf.device('/gpu:0'): for file in os.listdir(framesDir): if j<=1: #already processed first image so we skip it here j+=1 continue else: dreamedImage = "my directory"+str(i)+'.jpg' # get the previous deep dreamed frame img1 = file # get the next undreamed frame morphedImage = morphPicture(dreamedImage,img1,0.5,0) #blend the images morphedImage=np.float32(morphedImage) dreamedImage = render_deepdream(tf.square(T('mixed4c')),morphedImage,iter_n=3,octave_n=6) #deep dream a #blend of the two frames i+=1 save_array(dreamedImage,i,outputDir,'jpg') #save the dreamed image del dreamedImage del img1 del morphedImage time.sleep(0.5) 

Cada vez que ejecuto el código durante más de una hora, el script se detiene con un error de memoria. Supongo que debe haber una pérdida de memoria en algún lugar, pero no puedo encontrarlo. Pensé que al incluir varias declaraciones del , me desharía de los objetos que estaban obstruyendo la RAM / CPU, pero no parece estar funcionando.

¿Hay una acumulación obvia de objetos que me faltan en mi código? ¿O es la acumulación en algún lugar debajo de mi código, es decir, dentro de tensorflow?

Cualquier ayuda / sugerencia sería muy apreciada. Gracias.

Para su información hay 901 imágenes en el directorio. Estoy usando Windows 7 con NVIDIA GeForce GTX 980 Ti.

El 99% de las veces, cuando se usa tensorflow, las “memory leaks” se deben realmente a operaciones que se agregan continuamente al gráfico mientras se repite, en lugar de generar el gráfico primero, luego usarlo en un bucle.

El hecho de que especifique un dispositivo ( with tf.device('/gpu:0 ) para su bucle es un indicio de que es así: normalmente especifica un dispositivo para nuevos nodos, ya que esto no afecta a los nodos que ya están definidos.

Afortunadamente, tensorflow tiene una herramienta conveniente para detectar esos errores: tf.Graph.finalize . Cuando se le llama, esta función evita que se agreguen más nodos a su gráfico. Es una buena práctica llamar a esta función antes de iterar.

Entonces, en su caso, llamaría tf.get_default_graph().finalize() antes de su bucle y busque cualquier error que pueda lanzar.