tutorial online learning google dream deep-learning caffe conv-neural-network imagenet deep-dream

deep learning - online - Google Deep Dream-Usa clases para "controlar los sueños"



deep dream google (0)

Fondo

He estado jugando con Deep Dream y Inceptionism , utilizando el marco de Caffe para visualizar las capas de GoogLeNet , una arquitectura construida para el proyecto Imagenet , una gran base de datos visual diseñada para usar en el reconocimiento visual de objetos.

Imagenet se puede encontrar aquí: Imagenet 1000 Clases.

Para explorar la arquitectura y generar ''sueños'', estoy usando tres cuadernos:

  1. https://github.com/google/deepdream/blob/master/dream.ipynb

  2. https://github.com/kylemcdonald/deepdream/blob/master/dream.ipynb

  3. https://github.com/auduno/deepdraw/blob/master/deepdraw.ipynb

La idea básica aquí es extraer algunas características de cada canal en una capa específica del modelo o de una imagen de "guía".

Luego ingresamos una imagen que deseamos modificar en el modelo y extraemos las entidades en la misma capa especificada (para cada octava), mejorando las mejores características coincidentes, es decir, el producto de punto más grande de los dos vectores de características.

Hasta ahora he logrado modificar las imágenes de entrada y controlar los sueños utilizando los siguientes métodos:

  • (a) aplicar capas como objetivos ''end'' para la optimización de la imagen de entrada. (ver visualización de características )
  • (b) usar una segunda imagen para guiar el objetivo de optimización en la imagen de entrada.
  • (c) visualizar las clases del modelo Googlenet generadas a partir del ruido .

Sin embargo, el efecto que quiero lograr se encuentra entre estas técnicas, de las cuales no he encontrado ninguna documentación, papel o código.

Resultado deseado

Para que una sola clase o unidad que pertenezca a una capa ''end'' (a) guíe el objetivo de optimización (b) y visualice esta clase (c) en la imagen de entrada:

Un ejemplo donde class = ''face'' y input_image = ''clouds.jpg'' :

tenga en cuenta: la imagen anterior se generó utilizando un modelo para el reconocimiento facial, que no se entrenó en el conjunto de datos Imagenet . Sólo para fines de demostración.

Código de trabajo

Enfoque (a)

from cStringIO import StringIO import numpy as np import scipy.ndimage as nd import PIL.Image from IPython.display import clear_output, Image, display from google.protobuf import text_format import matplotlib as plt import caffe model_name = ''GoogLeNet'' model_path = ''models/dream/bvlc_googlenet/'' # substitute your path here net_fn = model_path + ''deploy.prototxt'' param_fn = model_path + ''bvlc_googlenet.caffemodel'' model = caffe.io.caffe_pb2.NetParameter() text_format.Merge(open(net_fn).read(), model) model.force_backward = True open(''models/dream/bvlc_googlenet/tmp.prototxt'', ''w'').write(str(model)) net = caffe.Classifier(''models/dream/bvlc_googlenet/tmp.prototxt'', param_fn, mean = np.float32([104.0, 116.0, 122.0]), # ImageNet mean, training set dependent channel_swap = (2,1,0)) # the reference model has channels in BGR order instead of RGB def showarray(a, fmt=''jpeg''): a = np.uint8(np.clip(a, 0, 255)) f = StringIO() PIL.Image.fromarray(a).save(f, fmt) display(Image(data=f.getvalue())) # a couple of utility functions for converting to and from Caffe''s input image layout def preprocess(net, img): return np.float32(np.rollaxis(img, 2)[::-1]) - net.transformer.mean[''data''] def deprocess(net, img): return np.dstack((img + net.transformer.mean[''data''])[::-1]) def objective_L2(dst): dst.diff[:] = dst.data def make_step(net, step_size=1.5, end=''inception_4c/output'', jitter=32, clip=True, objective=objective_L2): ''''''Basic gradient ascent step.'''''' src = net.blobs[''data''] # input image is stored in Net''s ''data'' blob dst = net.blobs[end] ox, oy = np.random.randint(-jitter, jitter+1, 2) src.data[0] = np.roll(np.roll(src.data[0], ox, -1), oy, -2) # apply jitter shift net.forward(end=end) objective(dst) # specify the optimization objective net.backward(start=end) g = src.diff[0] # apply normalized ascent step to the input image src.data[:] += step_size/np.abs(g).mean() * g src.data[0] = np.roll(np.roll(src.data[0], -ox, -1), -oy, -2) # unshift image if clip: bias = net.transformer.mean[''data''] src.data[:] = np.clip(src.data, -bias, 255-bias) def deepdream(net, base_img, iter_n=20, octave_n=4, octave_scale=1.4, end=''inception_4c/output'', clip=True, **step_params): # prepare base images for all octaves octaves = [preprocess(net, base_img)] for i in xrange(octave_n-1): octaves.append(nd.zoom(octaves[-1], (1, 1.0/octave_scale,1.0/octave_scale), order=1)) src = net.blobs[''data''] detail = np.zeros_like(octaves[-1]) # allocate image for network-produced details for octave, octave_base in enumerate(octaves[::-1]): h, w = octave_base.shape[-2:] if octave > 0: # upscale details from the previous octave h1, w1 = detail.shape[-2:] detail = nd.zoom(detail, (1, 1.0*h/h1,1.0*w/w1), order=1) src.reshape(1,3,h,w) # resize the network''s input image size src.data[0] = octave_base+detail for i in xrange(iter_n): make_step(net, end=end, clip=clip, **step_params) # visualization vis = deprocess(net, src.data[0]) if not clip: # adjust image contrast if clipping is disabled vis = vis*(255.0/np.percentile(vis, 99.98)) showarray(vis) print octave, i, end, vis.shape clear_output(wait=True) # extract details produced on the current octave detail = src.data[0]-octave_base # returning the resulting image return deprocess(net, src.data[0])

Ejecuto el código de arriba con:

end = ''inception_4c/output'' img = np.float32(PIL.Image.open(''clouds.jpg'')) _=deepdream(net, img)

Enfoque (b)

""" Use one single image to guide the optimization process. This affects the style of generated images without using a different training set. """ def dream_control_by_image(optimization_objective, end): # this image will shape input img guide = np.float32(PIL.Image.open(optimization_objective)) showarray(guide) h, w = guide.shape[:2] src, dst = net.blobs[''data''], net.blobs[end] src.reshape(1,3,h,w) src.data[0] = preprocess(net, guide) net.forward(end=end) guide_features = dst.data[0].copy() def objective_guide(dst): x = dst.data[0].copy() y = guide_features ch = x.shape[0] x = x.reshape(ch,-1) y = y.reshape(ch,-1) A = x.T.dot(y) # compute the matrix of dot-products with guide features dst.diff[0].reshape(ch,-1)[:] = y[:,A.argmax(1)] # select ones that match best _=deepdream(net, img, end=end, objective=objective_guide)

y corro el código de arriba con:

end = ''inception_4c/output'' # image to be modified img = np.float32(PIL.Image.open(''img/clouds.jpg'')) guide_image = ''img/guide.jpg'' dream_control_by_image(guide_image, end)

Enfoque fallido

Y así es como traté de acceder a clases individuales, codificando en caliente la matriz de clases y enfocándome en una (hasta ahora sin resultado):

def objective_class(dst, class=50): # according to imagenet classes #50: ''American alligator, Alligator mississipiensis'', one_hot = np.zeros_like(dst.data) one_hot.flat[class] = 1. dst.diff[:] = one_hot.flat[class]

¿Podría complacer a alguien que me guíe en la dirección correcta aquí? Podria ser muy apreciado.