Сохраните глубокую сеть и измените ее центральный слой в Tensorflow

#python #tensorflow

#python #tensorflow

Вопрос:

Я создал автоэнкодер в TensorFlow. Он имеет 5 скрытых слоев. Я обучил сеть, и теперь я хочу сохранить ее в каком-нибудь внешнем файле.

Позже я хотел бы загрузить автоэнкодер обратно и изменить его центральный уровень. Затем я хотел бы запустить автоэнкодер для некоторых входных данных.

Вот мой код для автоэнкодера. Я вставил несколько saver строк, где, я думаю, они могут помочь мне сохранить модель. Однако я не уверен, как перезагрузить сохраненную модель и, самое главное, как изменить ее центральный слой.

 input = ### some data
output = input

tf.reset_default_graph()

num_inputs=501    
num_hid1=250
num_hid2=100
num_hid3=50
num_hid4=num_hid2
num_hid5=num_hid1
num_output=num_inputs
lr=0.01
actf=tf.nn.tanh

X=tf.placeholder(tf.float32,shape=[None,num_inputs])
initializer=tf.variance_scaling_initializer()

w1=tf.Variable(initializer([num_inputs,num_hid1]),dtype=tf.float32)
w2=tf.Variable(initializer([num_hid1,num_hid2]),dtype=tf.float32)
w3=tf.Variable(initializer([num_hid2,num_hid3]),dtype=tf.float32)
w4=tf.Variable(initializer([num_hid3,num_hid4]),dtype=tf.float32)
w5=tf.Variable(initializer([num_hid4,num_hid5]),dtype=tf.float32)
w6=tf.Variable(initializer([num_hid5,num_output]),dtype=tf.float32)

b1=tf.Variable(tf.zeros(num_hid1))
b2=tf.Variable(tf.zeros(num_hid2))
b3=tf.Variable(tf.zeros(num_hid3))
b4=tf.Variable(tf.zeros(num_hid4))
b5=tf.Variable(tf.zeros(num_hid5))
b6=tf.Variable(tf.zeros(num_output))

hid_layer1=actf(tf.matmul(X,w1) b1)
hid_layer2=actf(tf.matmul(hid_layer1,w2) b2)
hid_layer3=actf(tf.matmul(hid_layer2,w3) b3)
hid_layer4=actf(tf.matmul(hid_layer3,w4) b4)
hid_layer5=actf(tf.matmul(hid_layer4,w5) b5)
output_layer=tf.matmul(hid_layer5,w6) b6

loss=tf.reduce_mean(tf.square(output_layer-X))

optimizer=tf.train.AdamOptimizer(lr)
train=optimizer.minimize(loss)

init=tf.global_variables_initializer()

num_epoch=100000
batch_size=150

saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(init)
    for epoch in range(num_epoch):

        sess.run(train,feed_dict={X:input})

        train_loss=loss.eval(feed_dict={X:input})
        print("epoch {} loss {}".format(epoch,train_loss))


    results=output_layer.eval(feed_dict={X:input})
    saver.save(sess, 'my_test_model')
  

Редактировать:

В ответ на ответ @mujjiga, на самом деле мне нужно отключить кодирующую часть этого автоэнкодера. А затем используйте оставшийся декодер для декодирования нового набора hid_layer3 функций.

Комментарии:

1. когда вы говорите «изменить», вы собираетесь отрезать и использовать для прогнозирования или вы намерены изменить график вычислений и переобучиться?

Ответ №1:

Если вы намерены отключить часть декодера и использовать кодировщик для получения скрытого представления вашего ввода (обычное применение автокодеров), то вы можете сделать следующее (если hid_layer3 представляет собой скрытое представление / вывод кодировщика)

 tf.reset_default_graph()

num_inputs=501    
num_hid1=250
num_hid2=100
num_hid3=50
num_hid4=num_hid2
num_hid5=num_hid1
num_output=num_inputs
lr=0.01
actf=tf.nn.tanh

output = np.random.rand(100,num_inputs)

X=tf.placeholder(tf.float32,shape=[None,num_inputs])
initializer=tf.variance_scaling_initializer()

w1=tf.Variable(initializer([num_inputs,num_hid1]),dtype=tf.float32)
w2=tf.Variable(initializer([num_hid1,num_hid2]),dtype=tf.float32)
w3=tf.Variable(initializer([num_hid2,num_hid3]),dtype=tf.float32)
w4=tf.Variable(initializer([num_hid3,num_hid4]),dtype=tf.float32)
w5=tf.Variable(initializer([num_hid4,num_hid5]),dtype=tf.float32)
w6=tf.Variable(initializer([num_hid5,num_output]),dtype=tf.float32)

b1=tf.Variable(tf.zeros(num_hid1))
b2=tf.Variable(tf.zeros(num_hid2))
b3=tf.Variable(tf.zeros(num_hid3))
b4=tf.Variable(tf.zeros(num_hid4))
b5=tf.Variable(tf.zeros(num_hid5))
b6=tf.Variable(tf.zeros(num_output))

hid_layer1=actf(tf.matmul(X,w1) b1)
hid_layer2=actf(tf.matmul(hid_layer1,w2) b2)
hid_layer3=actf(tf.matmul(hid_layer2,w3) b3)
hid_layer4=actf(tf.matmul(hid_layer3,w4) b4)
hid_layer5=actf(tf.matmul(hid_layer4,w5) b5)
output_layer=tf.matmul(hid_layer5,w6) b6

saver = tf.train.Saver()
with tf.Session() as sess:
  saver.restore(sess,  'my_test_model')
  print("Model restored.")    
  x = sess.run(hid_layer3, feed_dict={X:output})
  assert x.shape[1] == hid_layer3.shape[1]
  

Как вы можете видеть, вам все равно нужно определить архитектуру модели, но загрузить вес из сохраненной модели.

Комментарии:

1. Да, это почти то, что мне нужно. На самом деле мне нужна только часть «декодера». Предположим, что каким-то образом (детали здесь не важны) Я получаю набор hid_layer3, который отличается от тех, которые я получил с помощью обученного автоэнкодера. Я хотел бы посмотреть, какой тип вывода выдает этот новый hid_layer3

2. он будет полностью отличаться в зависимости от данных, используемых для обучения, нет: эпох, на которых он обучался. Я бы предложил проверить векторное сходство hid_layer3 этих двух разных моделей. Вы можете использовать евклидово расстояние, косинусное сходство и т. Д.

3. спасибо, в любом случае, как я уже сказал, не имеет значения, является ли новый hid_layer3 похожим на исходный или нет. Не могли бы вы все же показать мне, как декодировать новый hid_layer3, используя ранее обученный декодер? Спасибо