Tensorflow,在另一个 tf.estimator model_fn 中使用 tf.estimator 训练模型 [英] Tensorflow, use a tf.estimator trained model within another tf.estimator model_fn

查看:27
本文介绍了Tensorflow,在另一个 tf.estimator model_fn 中使用 tf.estimator 训练模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在另一个模型 B 中使用 tf.estimator 训练的模型 A?

Is there a way to use tf.estimator trained model A in another model B?

这是情况,假设我有一个训练有素的模型 A"和 model_a_fn().'模型 A' 获取图像作为输入,并输出一些类似于 MNIST 分类器的向量浮点值.还有另一个在model_b_fn() 中定义的模型B".它还以图像作为输入,在训练模型 B"时需要模型 A"的向量输出.

Here is situation, Let say I have a trained 'Model A' with model_a_fn(). 'Model A' gets images as input, and outputs some vector floating values similar to MNIST classifier. And there is another 'Model B' which is defined in model_b_fn(). It also gets images as input, and needs vector output of 'Model A' while training 'Model B'.

所以基本上我想训练需要输入为图像的模型 B"'模型 A' 的预测输出.(不再需要训练'模型A',只需在训练'模型B'时获得预测输出)

我尝试了三种情况:

  1. 在 model_b_fn() 中使用 estimator object('Model A')
  2. 使用 tf.estimator.export_savedmodel() 导出模型 A",并创建预测函数.使用 params dict 将其传递给 model_b_fn().
  3. 与 2 相同,但在 model_b_fn() 中恢复模型 A"

但所有情况都显示错误:

But all cases shows errors:

  1. ... 必须来自与...相同的图表
  2. TypeError:无法pickle _thread.RLock 对象
  3. TypeError:提要的值不能是 tf.Tensor 对象.

这是我使用的代码...只附上重要的部分

And here is my code I used... only attaching important parts

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 有什么想法吗??

So any idea on using trained custom tf.estimator in another tf.estimator please??

推荐答案

我想出了一个解决这个问题的方法.

I've figured out one solution to this problem.

如果遇到同样的问题,可以使用此方法.

One can use this method if struggling with same problem.

  1. 创建一个运行 tensorflow.contrib.predictor.from_saved_model() 的函数 -> 称之为pretrained_predictor()"
  2. 在模型 B 的 model_fn() 中,调用上面预定义的 'pretrained_predictor()' 用 tensorflow.py_func() 包装它

例如案例,请参见 https://github.com/moono/tf-cnn-mnist/blob/master/4_3_estimator_within_estimator.py 用于简单用例.

For example case, see https://github.com/moono/tf-cnn-mnist/blob/master/4_3_estimator_within_estimator.py for simple use case.

这篇关于Tensorflow,在另一个 tf.estimator model_fn 中使用 tf.estimator 训练模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆