Я разрабатываю ансамблевую нейронную сеть с 3 простыми сетевыми узлами прямого распространения. И теперь я столкнулся с проблемой восстановления этих 3 нейронных сетей для целей тестирования. К настоящему времени 3 модели NN созданы и сохранены функцией saver
.
saver = tf.train.Saver()
saver.save(sess, save_path=get_save_path(i), global_step=1000)
Я успешно сохранил их в файлах «.checkpoint», «.meta», «.index» и «.data», как показано ниже.
Я попытался восстановить их, используя такую кодировку:
saver = tf.train.import_meta_graph(get_save_path(i) + '-1000.meta')
saver.restore(sess,tf.train.latest_checkpoint(save_dir))
Но он восстанавливает только третий NN, который является network2
, для тестирования. Это повлияло на мой результат, поскольку алгоритм принимает только 1 модель (network2
) и предполагает, что все три модели NN одинаковы в функции ансамбля.
К вашему сведению:
Моя идеальная функция ансамбля:
ensemble = (network0 + network1 + network2) / 3
Реальный результат:
ensemble = (network2 + network2 + network2) / 3
Как я могу заставить TF восстанавливать все 3 модели NN вместе?
Я думаю, вы все путаете. Но позвольте мне сначала ответить на вопрос:
Вам нужно будет создать модель несколько раз в разных масштабах. Тогда появится возможность усреднить эти переменные.
Допустим, вы создали 3 сети с помощью
import tensorflow as tf
# save 3 version
for i in range(3):
tf.reset_default_graph()
a = tf.get_variable('test', [1])
assign_op = a.assign([i])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(assign_op)
print a.name, sess.run(a)
saver = tf.train.Saver(tf.global_variables())
saver.save(sess, './model/version_%i' % i)
Здесь каждая сеть имеет одинаковую структуру графа и содержит только один параметр / весовое имя test.
Затем вам нужно будет создать график одно и тоже несколько раз, но в разные variable_scopes, например
# load all versions in different scopes
tf.reset_default_graph()
a_collection = []
for i in range(3):
# use different var-scopes
with tf.variable_scope('scope_%0i' % i):
# create same network
a = tf.get_variable('test', [1])
a_collection.append(a)
Теперь каждый восстановитель должен знать, какую область видимости или сопоставление имен переменных следует использовать. Это можно сделать
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print zip(sess.run(a_collection), [n.name for n in a_collection])
for i in range(3):
loader = tf.train.Saver({"test": a_collection[i]})
loader = loader.restore(sess, './model/version_%i' % i)
print sess.run(a_collection)
Что даст вам
[array([0.], dtype=float32), array([1.], dtype=float32), array([2.], dtype=float32)]
как и ожидалось. Теперь вы можете делать со своей моделью все, что захотите.
Но это нет, как работают ансамблевые предсказания! В ансамблевых моделях вы обычно усредняете прогнозы Только. Итак, вы можете запускать свой скрипт несколько раз с разными моделями, а затем усреднять прогнозы.
Если вы действительно хотите усреднить веса своей модели, рассмотрите возможность сброса весов как python-dict с помощью numpy.
a = tf.get_variable()
- это объект TensorFlow. Не путайте с numpy-arys.
Я обнаружил эту ошибку в своем коде:
AttributeError: 'numpy.ndarray' object has no attribute 'assign'