Ejecuta múltiples redes Tensorflow pre-entrenadas al mismo tiempo

Lo que me gustaría hacer es ejecutar varias redes Tensorflow pre-entrenadas al mismo tiempo. Debido a que los nombres de algunas variables dentro de cada red pueden ser iguales, la solución común es usar un ámbito de nombre cuando creo una red. Sin embargo, el problema es que entrené estos modelos y guardo las variables entrenadas dentro de varios archivos de puntos de control. Después de usar un ámbito de nombre cuando creo la red, no puedo cargar variables de los archivos de punto de control.

Por ejemplo, he entrenado una AlexNet y me gustaría comparar dos conjuntos de variables, un conjunto es de la época 10 (guardado en el archivo epoch_10.ckpt) y otro es de la época 50 (guardado en el archivo epoch_50) ckpt). Debido a que estos dos son exactamente la misma red, los nombres de las variables internas son idénticos. Puedo crear dos redes usando

with tf.name_scope("net1"): net1 = CreateAlexNet() with tf.name_scope("net2"): net2 = CreateAlexNet() 

Sin embargo, no puedo cargar las variables entrenadas desde archivos .ckpt porque cuando entrené esta red, no usé un ámbito de nombre. Aunque puedo configurar el scope del nombre en “net1” cuando entreno la red, esto me impide cargar las variables para net2.

Yo he tratado:

 with tf.name_scope("net1"): mySaver.restre(sess, 'epoch_10.ckpt') with tf.name_scope("net2"): mySaver.restre(sess, 'epoch_50.ckpt') 

Esto no funciona.

¿Cuál es la mejor manera de resolver este problema?

La solución más sencilla es crear diferentes sesiones que usen gráficos separados para cada modelo:

 # Build a graph containing `net1`. with tf.Graph().as_default() as net1_graph: net1 = CreateAlexNet() saver1 = tf.train.Saver(...) sess1 = tf.Session(graph=net1_graph) saver1.restre(sess1, 'epoch_10.ckpt') # Build a separate graph containing `net2`. with tf.Graph().as_default() as net2_graph: net2 = CreateAlexNet() saver2 = tf.train.Saver(...) sess2 = tf.Session(graph=net1_graph) saver2.restre(sess2, 'epoch_50.ckpt') 

Si esto no funciona por alguna razón, y tiene que usar una sola tf.Session (por ejemplo, porque desea combinar los resultados de las dos redes en otro cálculo de TensorFlow), la mejor solución es:

  1. Cree las diferentes redes en los ámbitos de nombres como ya lo está haciendo, y
  2. Cree instancias de tf.train.Saver separadas para las dos redes, con un argumento adicional para volver a asignar los nombres de las variables.

Al construir los salvadores, puede pasar un diccionario como el argumento var_list , mapeando los nombres de las variables en el punto de control (es decir, sin el prefijo de scope del nombre) a los objetos tf.Variable que ha creado en cada modelo.

Puede crear var_list progtwigción y debería poder hacer algo como lo siguiente:

 with tf.name_scope("net1"): net1 = CreateAlexNet() with tf.name_scope("net2"): net2 = CreateAlexNet() # Strip off the "net1/" prefix to get the names of the variables in the checkpoint. net1_varlist = {v.name.lstrip("net1/"): v for v in tf.get_collection(tf.GraphKeys.VARIABLES, scope="net1/")} net1_saver = tf.train.Saver(var_list=net1_varlist) # Strip off the "net2/" prefix to get the names of the variables in the checkpoint. net2_varlist = {v.name.lstrip("net2/"): v for v in tf.get_collection(tf.GraphKeys.VARIABLES, scope="net2/")} net2_saver = tf.train.Saver(var_list=net2_varlist) # ... net1_saver.restre(sess, "epoch_10.ckpt") net2_saver.restre(sess, "epoch_50.ckpt") 

Tengo el mismo problema que me molestó mucho tiempo. Encontré una buena solución aquí: cargar dos modelos de Saver en la misma sesión de Tensorflow y guardar y leer el punto de control de TensorFlow .

El comportamiento predeterminado para un tf.train.Saver() es asociar cada variable con el nombre de la op correspondiente. Esto significa que cada vez que construyes un tf.train.Saver() , incluye todas las variables para las llamadas anteriores. Por lo tanto, debe crear diferentes gráficos y ejecutar diferentes sesiones con ellos.