"[Las neuronas son] células de formas delicadas y elegantes, las misteriosas mariposas del alma, cuyo batir de alas quién sabe si esclarecerá algún día el secreto de la vida mental." (Ramón y Cajal)
Este artículo es una continuación de mi entrada anterior "Las matemáticas de la mente"[2]. Vimos en ese artículo cómo era posible que un simple algoritmo de computación pudiese imitar el modo en que nuestro cerebro aprende a realizar tareas con éxito, simplemente a partir del equivalente computacional de una red neuronal.
Sin embargo, a pesar de que en dicha entrada os comentaba el caso de cómo se puede programar un algoritmo capaz de conseguir literalmente, aprender a jugar al Conecta4 (4 en raya) sin especificar (pre-programar) en ningún momento las reglas del juego; es posible que muchos notasen que aún así, todavía había que pre-procesar la entrada de la red neuronal para ofrecerle a las neuronas (nodos) de la capa de entrada (inputs) qué fichas había en cada casilla del tablero y qué casillas estaban aún libres. Este hecho podía hacer a algunos sospechar de la autonomía real de este programa para aprender de un modo no supervisado a jugar.
Por lo tanto, y con ánimo de solventar este asunto, os voy a presentar un nuevo ejemplo en esta nueva entrada para intentar reforzar así la validez de las conclusiones a las que llegamos al final del artículo "Las matemáticas de la mente"[2]. Haremos ésto mediante un nuevo experimento de aprendizaje automático mediante redes neuronales, pero esta vez; aprovechando el estado del arte teórico que nos ofrece el equipo del departamento de inteligencia artificial de Google DeepMind[4].
En concreto, he dedicado un par de semanas de mi tiempo libre en implementar un muy prometedor algoritmo de aprendizaje por refuerzo (RL según siglas en inglés). Para aquellos interesados técnicamente en el asunto, pueden leer el siguiente paper[1] del que me hecho referencia: "Asynchronous Methods for Deep Reinforcement Learning", publicado a fecha del 4 de febrero de este año 2016, en colaboración con la Universidad de Montreal.
La cuestión fundamental tratada en este paper de Google es que explica el modo en que es posible entrenar una red neuronal artificial para que realice tareas sin supervisión ni pre-programación alguna. Se trata de un proceso end-to-end, mediante el cual el algoritmo accede directamente a los píxeles de la pantalla (simulando el modo en que nosotros obtenemos la información visual desde nuestra retina), y luego convoluciona y post-procesa dicha información sensible en varias capas de nodos (neuronas) internas (simulando el modo en que nuestro cerebro procesa la información obtenida en la retina posteriormente en sucesivas partes de la corteza visual); para terminar tratando dicha información visual en nuevas capas de neuronas que darán lugar finalmente a una respuesta (una acción).
Esto implica que ya no es necesario que nosotros pre-programemos y ofrezcamos como entrada a la red neuronal el estado del entorno (que en el caso del Conecta4 era estado del tablero), sino que es la propia red neuronal la que observa visualmente el entorno (por ejemplo, el tablero), y luego procesa dicha información visual en otras zonas de la misma red de manera autónoma, hasta ofrecer finalmente como salida una determinada acción a realizar.
Y sobra decir que los chicos de Google lo han conseguido (en realidad lo que han logrado es perfeccionar una técnica ya existente en gran medida); han desarrollado un algoritmo capaz de enseñar a una red neuronal artificial a procesar toda la información sensible disponible sobre el entorno de cualquier tarea a realizar, y; conseguir de un modo totalmente autónomo (end-to-end), ¡conseguir una respuesta con habilidades bastante cercanas a las humanas!
Metodología.
En el paper[1] arriba indicado nos explican teóricamente el modo en que es posible implementar un algoritmo de aprendizaje realmente autónomo como el que estamos buscando en un intento de reforzar las conclusiones obtenidas en el anterior artículo[2]. Y lo hacen mediante una detallada explicación, y ofreciendo además un pseudocódigo de guía para el interesado en realizar algún experimento o prueba práctica de lo que proponen. En realidad se ofrecen varias alternativas y variantes de lo que en DeepMind han denominado Deep Q NetWorks, aunque yo me he decantado por utilizar la variante en principio más sencilla de implementar (aunque también es la relativamente menos eficiente). Esto es, el "Asynchronous one-step Q-learning".
Os dejo a continuación una copia del pseudocódigo ofrecido en el paper, pero aquellos lectores no técnicos no tenéis que preocuparos, continuad adelante sin prestar más atención al mismo:
Configuración experimental.
Para poner a prueba el pseudocódigo, me decidí a aprovechar la librería para desarrollo numérico computacional que desde hace unos meses ofrece el propio Google de acceso gratuito: TensorFlow[3]. En concreto, hice uso de la interfaz Python de la librería para programar mediante esta técnica de aprendizaje por refuerzo una red neuronal artificial capaz de aprender a jugar de manera totalmente autónoma (a partir únicamente de los pixels de la pantalla del ordenador) al clásico juego del Pong (el mítico juego de Atari de la pelotita rebotando en las paredes ;)).
Revisión utilizada del mítico juego del Pong |
Utilicé TensorFlow para diseñar una red neuronal artificial de 6 capas: una para recibir los inputs de la imagen del entorno (el estado del juego) en formato RGB (donde cada pixel se representa mediante un número entero que es una combinación para el tono rojo, verde y azul). Estos píxels (simulando al modo en que la retina recoge los fotones en el ojo), se pasan luego a dos capas internas (o, como se las suelen llamar: ocultas -"hidden"-) que convolucionan y pre-procesan esta información visual para facilitar su uso más tarde por parte de las otras dos capas de neuronas, que finalmente procesan la información y devuelven una acción a realizar gracias a una capa de salida (output). Y esta es la red neuronal que se entrena de manera autónoma mediante el código de RL propuesto en el paper.
Como digo, todo se programó en Python usando varios hilos (threads) como requiere el pseudocódigo (ya que este aprendizaje hace uso de un procesamiento asíncrono en paralelo del entrenamiento).
Os dejo a continuación un par de vídeos donde podréis ver gráficamente en vivo cómo se produce este proceso. En un primer vídeo podréis observar como la red neuronal al inicio no se encuentra entrenada (es decir; sus "sinapsis" no están bien balanceadas), por lo que juega a lo loco (la red neuronal es la barra azul de la izquierda) . También veréis cómo se inicia el proceso de entrenamiento en paralelo mediante ensayo y error, gracias al refuerzo que supone la recompensa de ganar una partida, o el castigo que supone perderla (algo similar a lo que nosotros experimentamos como alegría y frustración cuando nos enfrentamos al aprendizaje de una nueva tarea):
Este segundo vídeo muestra la misma red neuronal inicial una vez que sus pesos (sinapsis) han sido bien moduladas por el proceso de aprendizaje. Como se puede observar, el algoritmo ahora es capaz de obtener la imagen (pixels) de la pantalla, "objetivar" lo importante de la misma (la pelota y su posición relativa), y actuar en consecuencia para maximizar el beneficio de sus acciones (ganar partidas):
Resultados.
Los resultados son muy favorables, alcanzando el algoritmo por sí mismo tras el entrenamiento autónomo un nivel de juego muy admirable y equiparable al de una persona. Además, es importante señalar una cuestión técnica: el proceso de aprendizaje se lleva a cabo con esta novedosa técnica propuesta por Google en un simple ordenador personal, sin requerir de grandes estaciones de trabajo distribuidas, y ni siquiera de un hardware específico (como tarjetas GPU). De hecho, con un simple procesador Intel Core i5 he conseguido entrenar en menos de 24 horas lo que hasta hace poco requería de grandes estaciones de trabajo distribuidas usando la técnica conocida como "Gorila" (ver el paper[1] de referencia para más información).
Por si hay algún interesado en probar todo el tinglado, os dejo a continuación copia del código fuente Python [5] que he desarrollado:
#!/usr/bin/env python import threading import tensorflow as tf import cv2 import sys sys.path.append("Wrapped Game Code/") import pong_fun as game # Whichever is imported "as game" will be used import random import numpy as np import time #Shared global parameters TMAX = 5000000 T = 0 It = 10000 Iasync = 5 THREADS = 12 WISHED_SCORE = 10 GAME = 'pong' # The name of the game being played for log files ACTIONS = 3 # Number of valid actions GAMMA = 0.99 # Decay rate of past observations OBSERVE = 5. # Timesteps to observe before training EXPLORE = 400000. # Frames over which to anneal epsilon FINAL_EPSILONS = [0.01, 0.01, 0.05] # Final values of epsilon INITIAL_EPSILONS = [0.4, 0.3, 0.3] # Starting values of epsilon EPSILONS = 3 def weight_variable(shape): initial = tf.truncated_normal(shape, stddev = 0.01) return tf.Variable(initial) def bias_variable(shape): initial = tf.constant(0.01, shape = shape) return tf.Variable(initial) def conv2d(x, W, stride): return tf.nn.conv2d(x, W, strides = [1, stride, stride, 1], padding = "SAME") def max_pool_2x2(x): return tf.nn.max_pool(x, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = "SAME") def createNetwork(): # network weights W_conv1 = weight_variable([8, 8, 4, 32]) b_conv1 = bias_variable([32]) W_conv2 = weight_variable([4, 4, 32, 64]) b_conv2 = bias_variable([64]) W_conv3 = weight_variable([3, 3, 64, 64]) b_conv3 = bias_variable([64]) W_fc1 = weight_variable([256, 256]) b_fc1 = bias_variable([256]) W_fc2 = weight_variable([256, ACTIONS]) b_fc2 = bias_variable([ACTIONS]) # input layer s = tf.placeholder("float", [None, 80, 80, 4]) # hidden layers h_conv1 = tf.nn.relu(conv2d(s, W_conv1, 4) + b_conv1) h_pool1 = max_pool_2x2(h_conv1) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2, 2) + b_conv2) h_pool2 = max_pool_2x2(h_conv2) h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3, 1) + b_conv3) h_pool3 = max_pool_2x2(h_conv3) h_pool3_flat = tf.reshape(h_pool3, [-1, 256]) h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1) # readout layer readout = tf.matmul(h_fc1, W_fc2) + b_fc2 return s, readout, W_conv1, b_conv1, W_conv2, b_conv2, W_conv3, b_conv3, W_fc1, b_fc1, W_fc2, b_fc2 def copyTargetNetwork(sess): sess.run(copy_Otarget) def actorLearner(num, sess, lock): # We use global shared O parameter vector # We use global shared Otarget parameter vector # We use global shared counter T, and TMAX constant global TMAX, T # Open up a game state to communicate with emulator lock.acquire() game_state = game.GameState() lock.release() # Initialize network gradients s_j_batch = [] a_batch = [] y_batch = [] # Get the first state by doing nothing and preprocess the image to 80x80x4 lock.acquire() x_t, r_0, terminal = game_state.frame_step([1, 0, 0]) lock.release() x_t = cv2.cvtColor(cv2.resize(x_t, (80, 80)), cv2.COLOR_BGR2GRAY) s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2) aux_s = s_t time.sleep(3*num) # Initialize target network weights copyTargetNetwork(sess) epsilon_index = random.randrange(EPSILONS) INITIAL_EPSILON = INITIAL_EPSILONS[epsilon_index] FINAL_EPSILON = FINAL_EPSILONS[epsilon_index] epsilon = INITIAL_EPSILON print "THREAD ", num, "STARTING...", "EXPLORATION POLICY => INITIAL_EPSILON:", INITIAL_EPSILON, ", FINAL_EPSILON:", FINAL_EPSILON # Initialize thread step counter t = 0 score = 0 while T < TMAX and score < WISHED_SCORE: # Choose an action epsilon greedily readout_t = O_readout.eval(session = sess, feed_dict = {s : [s_t]}) a_t = np.zeros([ACTIONS]) action_index = 0 if random.random() <= epsilon or t <= OBSERVE: action_index = random.randrange(ACTIONS) a_t[action_index] = 1 else: action_index = np.argmax(readout_t) a_t[action_index] = 1 # Scale down epsilon if epsilon > FINAL_EPSILON and t > OBSERVE: epsilon -= (INITIAL_EPSILON - FINAL_EPSILON) / EXPLORE # Run the selected action and observe next state and reward lock.acquire() x_t1_col, r_t, terminal = game_state.frame_step(a_t) lock.release() x_t1 = cv2.cvtColor(cv2.resize(x_t1_col, (80, 80)), cv2.COLOR_BGR2GRAY) x_t1 = np.reshape(x_t1, (80, 80, 1)) aux_s = np.delete(s_t, 0, axis = 2) s_t1 = np.append(aux_s, x_t1, axis = 2) # Accumulate gradients readout_j1 = Ot_readout.eval(session = sess, feed_dict = {st : [s_t1]}) if terminal: y_batch.append(r_t) else: y_batch.append(r_t + GAMMA * np.max(readout_j1)) a_batch.append(a_t) s_j_batch.append(s_t) # Update the old values s_t = s_t1 T += 1 t += 1 score += r_t # Update the Otarget network if T % It == 0: copyTargetNetwork(sess) # Update the O network if t % Iasync == 0 or terminal: if s_j_batch: # Perform asynchronous update of O network train_O.run(session = sess, feed_dict = { y : y_batch, a : a_batch, s : s_j_batch}) #Clear gradients s_j_batch = [] a_batch = [] y_batch = [] # Save progress every 5000 iterations if t % 5000 == 0: saver.save(sess, 'save_networks_asyn/' + GAME + '-dqn', global_step = t) # Print info state = "" if t <= OBSERVE: state = "observe" elif t > OBSERVE and t <= OBSERVE + EXPLORE: state = "explore" else: state = "train" if terminal: print "THREAD:", num, "/ TIME", T, "/ TIMESTEP", t, "/ STATE", state, "/ EPSILON", epsilon, "/ ACTION", action_index, "/ REWARD", r_t, "/ Q_MAX %e" % np.max(readout_t), "/ SCORE", score score = 0 # Save the last state of each thread saver.save(sess, 'save_networks_asyn/' + GAME + '-final-' + num) # We create the shared global networks # O network s, O_readout, W_conv1, b_conv1, W_conv2, b_conv2, W_conv3, b_conv3, W_fc1, b_fc1, W_fc2, b_fc2 = createNetwork() # Training node a = tf.placeholder("float", [None, ACTIONS]) y = tf.placeholder("float", [None]) O_readout_action = tf.reduce_sum(tf.mul(O_readout, a), reduction_indices=1) cost_O = tf.reduce_mean(tf.square(y - O_readout_action)) train_O = tf.train.RMSPropOptimizer(0.00025, 0.95, 0.95, 0.01).minimize(cost_O) # Otarget network st, Ot_readout, W_conv1t, b_conv1t, W_conv2t, b_conv2t, W_conv3t, b_conv3t, W_fc1t, b_fc1t, W_fc2t, b_fc2t = createNetwork() copy_Otarget = [W_conv1t.assign(W_conv1), b_conv1t.assign(b_conv1), W_conv2t.assign(W_conv2), b_conv2t.assign(b_conv2), W_conv3t.assign(W_conv3), b_conv3t.assign(b_conv3), W_fc1t.assign(W_fc1), b_fc1t.assign(b_fc1), W_fc2t.assign(W_fc2), b_fc2t.assign(b_fc2)] # Initialize session and variables sess = tf.InteractiveSession() saver = tf.train.Saver() sess.run(tf.initialize_all_variables()) checkpoint = tf.train.get_checkpoint_state("save_networks_asyn") if checkpoint and checkpoint.model_checkpoint_path: saver.restore(sess, checkpoint.model_checkpoint_path) print "Successfully loaded:", checkpoint.model_checkpoint_path if __name__ == "__main__": # Start n concurrent actor threads lock = threading.Lock() threads = list() for i in range(THREADS): t = threading.Thread(target=actorLearner, args=(i,sess, lock)) threads.append(t) # Start all threads for x in threads: x.start() # Wait for all of them to finish for x in threads: x.join() print "ALL DONE!!"
Por cierto, que no os engañe lo reducido del código. Detrás tenemos la enorme librería TensorFlow trabajando, y también una librería para Python llamada Pygame ;).
Conclusiones y discusión.
La principal conclusión que me gustaría destacar, es la de que la inteligencia artificial está avanzando de un modo casi exponencial estos últimos años (aunque los medios apenas se hagan eco de ello). Muy en particular, el grupo de IA dentro de Google llamado DeepMind[4] tiene gran parte de culpa. Sus papers de los últimos años son espectaculares, y están rebasando constantemente el estado del arte en casi todos los ámbitos. Y, además, señalar que todos y cada uno de los hitos conseguidos en el ámbito de la IA se están logrando sin excepción al imitarse cada vez mejor (en cuanto a eficiencia y escala) el modo en que la neurociencia nos cuenta que funciona nuestro cerebro. Cuestión que nos permite reflexionar sobre lo siguiente:
Las capacidades cognitivas humanas (y del resto del reino animal) parecen ser, como vemos, producto exclusivo del procesado eléctrico por entre trillones de sinapsis en el cerebro. Esto supone que sería precisamente este procesamiento de información eléctrica entre neuronas el que lograría otorgarnos todas y cada una de nuestras capacidades, sin que exista evidencia empírica alguna de que nada más intervenga en el proceso que origina lo que se entiende por mente: englobando aquí conducta, emociones, sensaciones, etc. Esta afirmación basa su fuerza en tres hechos probados: 1º) Que la moderna neurociencia indica experimentalmente que todo apunta a que las redes neuronales biológicas se sobran para acometer la gama completa cognitiva del hombre, 2º) que no se ha observado empíricamente nada más en el cuerpo humano capaz contribuir a tales procesos, y 3º) que además, por otra parte, al emular este comportamiento neuronal biológico de un modo computacional, se observan cada vez resultados más y más parecidos a los observados en los seres vivos.
Por lo tanto, esto nos permite concluir (gracias a todo lo que ya conocemos sobre las redes neuronales biológicas y artificiales) que:
Nuestra mente, en el fondo, no es más que el fruto de una enorme calculadora digital capaz de ejecutar en paralelo cientos de trillones de operaciones por segundo: operaciones que, por cierto, se reducen a meras sumas de potenciales eléctricos.
Referencias.
[1] http://arxiv.org/pdf/1602.01783v1.pdf "Asynchronous Methods for Deep Reinforcement Learning" (Google DeepMind) (2016)
[2] http://quevidaesta2010.blogspot.com.es/2016/02/las-matematicas-de-la-mente.html
[3] https://www.tensorflow.org/ (librería de código abierto ofrecida por Google)
[4] https://deepmind.com/publications.html (web del equipo de desarrollo Google DeepMind)
[5] https://github.com/Zeta36/Asynchronous-Methods-for-Deep-Reinforcement-Learning (repositorio en GitHub donde he subido todo el código fuente completo que he implementado en Python para esta entrada)
[1] http://arxiv.org/pdf/1602.01783v1.pdf "Asynchronous Methods for Deep Reinforcement Learning" (Google DeepMind) (2016)
[2] http://quevidaesta2010.blogspot.com.es/2016/02/las-matematicas-de-la-mente.html
[3] https://www.tensorflow.org/ (librería de código abierto ofrecida por Google)
[4] https://deepmind.com/publications.html (web del equipo de desarrollo Google DeepMind)
[5] https://github.com/Zeta36/Asynchronous-Methods-for-Deep-Reinforcement-Learning (repositorio en GitHub donde he subido todo el código fuente completo que he implementado en Python para esta entrada)
Hola Samu,
ResponderEliminarestoy intentando ejecutar tu red neuronal y me da error en la importación de la librería de pygame. Me dice:
Traceback (most recent call last):
File "./RedNeu.py", line 7, in
import pong_fun as game # Whichever is imported "as game" will be used
ImportError: No module named pong_fun
He instalado el phython-game con sudo apt-get install python-pygame. Estoy en ubuntu 14.04 y creo que tengo todo correctamente. Eso sí, lo ejecuto con phython o phyton2
¿Me puedes decir si es otro paquete el que debo instalar?
Si lo hago con phython 3 me da error de sintaxis en la línea 119, por lo que deduzco que utilizas las versiones de python o python 2.
Muchas gracias y felicidades por tu blog.
Félix
Hola, Felix.
ResponderEliminarVamos por partes:
1) En efecto utilizo python 2.
2) El problema que tienes no es con pygame, sino con la importación de un fichero .py (pong_fun.py) que se me pasó incluir en el artículo. Te enlazo a un repositorio GitHub donde tienes todo mi código completo (debí de haberlo hecho desde el principio pero se me pasó): https://github.com/Zeta36/Asynchronous-Methods-for-Deep-Reinforcement-Learning
Un saludo!!
Muchas gracias Samu, allá voy !!!
ResponderEliminarSaludos !
Hola Samu,
ResponderEliminardisculpa que continúe molestando he conseguido arrancar el programa pero cuando dibuja la pantalla del juego peta.
La verdad, no sé cómo resolverlo. ¿Se te ocurre qué pasa? Te dejo el volcado de lo que dice. Gracias. Félix
Enviado en 2 mensaje pues el máximo de caracteres que me permite es 4.096
>>>>>>>>>>
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 2
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 2
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Continúa:
ResponderEliminarException in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-6:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-5:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-11:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-7:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-9:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-10:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-8:
ResponderEliminarTraceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
Exception in thread Thread-12:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "./RedNeu.py", line 106, in actorLearner
s_t = np.stack((x_t, x_t, x_t, x_t), axis = 2)
AttributeError: 'module' object has no attribute 'stack'
ALL DONE!!
Hola, Felix.
ResponderEliminarHay un hilo en StackOverFlow donde tratan este error que te da: http://stackoverflow.com/questions/35517954/numpy-module-object-has-no-attribute-stack
Creo que es un problema con tu versión local de la librería numpy:
"It is only present since numpy 1.10 ... you are probably using an older version"
Por lo visto, el atributo 'stack' no empieza a usarse en la librería numpy hasta la versión 1.10.0, probablemente tengas una versión más antigua (revísalo a ver).
Si tienes numpy >= 1.10 entonces el problema puede ser otro. Para comprobar tu versión de numpy escribe desde la línea de comandos de Linux lo siguiente: "python -c "import numpy; print numpy.version.version"
Un saludo!!
Hola Samu.
EliminarEste fin de semana me he puesto y he conseguido que funcione todo. Sin embargo al cabo de media hora (o más) peta el programa. Me da la impresión de que intenta grabar los estados de las neuronas y, por alguna razón, peta.
Quiero aprender más sobre cómo programar neuronas, alguna idea para aconsejarme.
Te lo agradezco.
Félix
Hola, Felix.
EliminarSi quieres aprender a programar redes neuronales, te recomiendo comenzar con el siguiente tutorial impartido por Google (donde utilizan por cierto TensorFlow como herramienta práctica):
https://www.udacity.com/course/deep-learning--ud730
Este curso es gratuito; y aunque es básico, a la vez es completo y trata el asunto desde el estado del arte actual.
Ya me cuentas como te va ;-).
Un saludo!!
Gracias Samu.
ResponderEliminarEstoy mirando la documentación para instalar la última versión. Yo tenía la 1.8 e intento instalar la 1.11.
Ya te cuento si lo consigo.
Saludos !!!