Есть ли способ использовать обученную модель tf.estimator A в другой модели B?
Вот ситуация,
Допустим, у меня есть обученная «Модель A» с model_a_fn ().
«Модель A» получает изображения в качестве входных данных и выводит некоторые векторные плавающие значения, аналогичные классификатору MNIST.
И есть еще одна «Модель B», которая определена в model_b_fn ().
Он также получает изображения в качестве входных данных и требует векторного вывода «Модель А» во время обучения «Модель Б».
Так что, в основном, я хочу обучить «Модель B», которая нуждается во входных данных в качестве изображений и результатов прогнозирования «Модели А». (Больше не нужно тренировать «Модель А», только для получения результата прогнозирования во время обучения «Модель Б»)
Я пробовал три случая:
- Использовать объект оценки ('Модель A') внутри model_b_fn ()
- Экспортировал «Модель A» с помощью tf.estimator.export_savedmodel () и создал функцию прогнозирования. Передал его в model_b_fn () с параметром dict.
- То же, что 2, но восстановить «Модель A» внутри model_b_fn ()
Но во всех случаях отображаются ошибки:
- ... должен быть из того же графика, что и ...
- TypeError: невозможно выбрать объекты _thread.RLock
- TypeError: значение фида не может быть объектом tf.Tensor.
А вот мой код, который я использовал ... только прикрепление важных частей
train_model_a.py
def model_a_fn(features, labels, mode, params):
# ...
# ...
# ...
return
def main():
# model checkpoint location
model_a_dir = './model_a'
# create estimator for Model A
model_a = tf.estimator.Estimator(model_fn=model_a_fn, model_dir=model_a_dir)
# train Model A
model_a.train(input_fn=lambda : input_fn_a)
# ...
# ...
# ...
# export model a
model_a.export_savedmodel(model_a_dir, serving_input_receiver_fn=serving_input_receiver_fn)
# exported to ./model_a/123456789
return
if __name__ == '__main__':
main()
train_model_b_case_1.py
# follows model_a's input format
def bypass_input_fn(x):
features = {
'x': x,
}
return features
def model_b_fn(features, labels, mode, params):
# parse input
inputs = tf.reshape(features['x'], shape=[-1, 28, 28, 1])
# get Model A's response
model_a = params['model_a']
predictions = model_a.predict(
input_fn=lambda: bypass_input_fn(inputs)
)
for results in predictions:
# Error occurs!!!
model_a_output = results['class_id']
# build Model B
layer1 = tf.layers.conv2d(inputs, 32, 5, same, activation=tf.nn.relu)
layer1 = tf.layers.max_pooling2d(layer1, pool_size=[2, 2], strides=2)
# ...
# some layers added...
# ...
flatten = tf.layers.flatten(prev_layer)
layern = tf.layers.dense(10)
# let say layern's output shape and model_a_output's output shape is same
add_layer = tf.add(flatten, model_a_output)
# ...
# do more... stuff
# ...
return
def main():
# load pretrained model A
model_a_dir = './model_a'
model_a = tf.estimator.Estimator(model_fn=model_a_fn, model_dir=model_a_dir)
# model checkpoint location
model_b_dir = './model_b/'
# create estimator for Model A
model_b = tf.estimator.Estimator(
model_fn=model_b_fn,
model_dir=model_b_dir,
params={
'model_a': model_a,
}
)
# train Model B
model_b.train(input_fn=lambda : input_fn_b)
return
if __name__ == '__main__':
main()
train_model_b_case_2.py
def model_b_fn(features, labels, mode, params):
# parse input
inputs = tf.reshape(features['x'], shape=[-1, 28, 28, 1])
# get Model A's response
model_a_predict_fn = params['model_a_predict_fn']
model_a_prediction = model_a_predict_fn(
{
'x': inputs
}
)
model_a_output = model_a_prediction['output']
# build Model B
layer1 = tf.layers.conv2d(inputs, 32, 5, same, activation=tf.nn.relu)
layer1 = tf.layers.max_pooling2d(layer1, pool_size=[2, 2], strides=2)
# ...
# some layers added...
# ...
flatten = tf.layers.flatten(prev_layer)
layern = tf.layers.dense(10)
# let say layern's output shape and model_a_output's output shape is same
add_layer = tf.add(flatten, model_a_output)
# ...
# do more... stuff
# ...
return
def main():
# load pretrained model A
model_a_dir = './model_a/123456789'
model_a_predict_fn = tf.contrib.predictor.from_saved_model(export_dir=model_a_dir)
# model checkpoint location
model_b_dir = './model_b/'
# create estimator for Model A
# Error occurs!!!
model_b = tf.estimator.Estimator(
model_fn=model_b_fn,
model_dir=model_b_dir,
params={
'model_a_predict_fn': model_a_predict_fn,
}
)
# train Model B
model_b.train(input_fn=lambda : input_fn_b)
return
if __name__ == '__main__':
main()
train_model_b_case_3.py
def model_b_fn(features, labels, mode, params):
# parse input
inputs = tf.reshape(features['x'], shape=[-1, 28, 28, 1])
# get Model A's response
model_a_predict_fn = tf.contrib.predictor.from_saved_model(export_dir=params['model_a_dir'])
# Error occurs!!!
model_a_prediction = model_a_predict_fn(
{
'x': inputs
}
)
model_a_output = model_a_prediction['output']
# build Model B
layer1 = tf.layers.conv2d(inputs, 32, 5, same, activation=tf.nn.relu)
layer1 = tf.layers.max_pooling2d(layer1, pool_size=[2, 2], strides=2)
# ...
# some layers added...
# ...
flatten = tf.layers.flatten(prev_layer)
layern = tf.layers.dense(10)
# let say layern's output shape and model_a_output's output shape is same
add_layer = tf.add(flatten, model_a_output)
# ...
# do more... stuff
# ...
return
def main():
# load pretrained model A
model_a_dir = './model_a/123456789'
# model checkpoint location
model_b_dir = './model_b/'
# create estimator for Model A
# Error occurs!!!
model_b = tf.estimator.Estimator(
model_fn=model_b_fn,
model_dir=model_b_dir,
params={
'model_a_dir': model_a_dir,
}
)
# train Model B
model_b.train(input_fn=lambda : input_fn_b)
return
if __name__ == '__main__':
main()
Так что любая идея об использовании обученного пользовательского tf.estimator в другом tf.estimator, пожалуйста ??