Python 将估计器转换为TPU估计器

Python 将估计器转换为TPU估计器,python,tensorflow,machine-learning,keras,tensorflow-estimator,Python,Tensorflow,Machine Learning,Keras,Tensorflow Estimator,是否可以在TensorFlow中将估计器转换为TPUEstimator,而无需重新编写其函数?我有一个估计器形式的模型,它可以在CPU上很好地工作,但是我不知道有什么方便的方法可以将它转换成TPUEstimator,而不必重写模型和输入 这需要手动完成大量工作的原因是,我正在使用Keras创建我的模型,然后使用以下帮助函数创建估计器: my_keras_model.compile( optimizer=tf.keras.optimizers.SGD(lr=0

是否可以在TensorFlow中将
估计器
转换为
TPUEstimator
,而无需重新编写其函数?我有一个
估计器
形式的模型,它可以在CPU上很好地工作,但是我不知道有什么方便的方法可以将它转换成
TPUEstimator
,而不必重写
模型和
输入

这需要手动完成大量工作的原因是,我正在使用Keras创建我的模型,然后使用以下帮助函数创建
估计器

   my_keras_model.compile(
                optimizer=tf.keras.optimizers.SGD(lr=0.0001, momentum=0.9),
                loss='categorical_crossentropy',
                metric='accuracy')
   estimator = tf.keras.estimator.model_to_estimator(keras_model=my_keras_model)

如果我能做一些类似于
estimator.to_TPU_estimator()
或类似的事情,那就太好了——也许有人知道一个解决方案?

不可能有这样的函数,因为
model\u fn
规范在两个估计器中是不同的。有些差异相当深刻,例如这一个(来自):

在云TPU上进行培训时,您必须将优化器包装在
tf.contrib.tpu.CrossShardOptimizer
,它使用
allreduce
来 聚合梯度并将结果广播到每个碎片(每个TPU 核心)

这意味着修补keras optimizer的内部并更新ops

推荐的方法是为GPU和TPU型号使用不同的
model\fn
wrapper,这似乎是最快的方法。在您的例子中,这意味着重写TPU估计器的keras函数


第一个也是最简单的近似是:

def模型到估计器(keras模型=None,
keras_模型_路径=无,
自定义对象=无,
model_dir=无,
配置=无):
keras_权重=keras_模型。获取_权重()
keras_model_fn=_create_keras_tpu_model_fn(keras_model,自定义_对象)
est=tf.contrib.tpu.TPUEstimator(keras_model_fn,model_dir=model_dir,config=config)
_保存第一个检查点(keras_模型、est、自定义_对象、keras_权重)
返回est
在这里,
\u save\u first\u checkpoint
调用实际上是可选的,但如果您想保留它,请从
tensorflow.python.keras.\u impl.keras.estimator
导入此函数


真正的工作发生在
\u create\u keras\u tpu\u model\u fn
函数中,该函数替换了。这些变化是:

  • 内部tensorflow优化器必须使用前面提到的
    CrossShardOptimizer
    包装,并且

  • 内部函数必须返回
    TPUEstimatorSpec

可能还需要再补几条线,但我觉得没问题。完整版本如下:

来自tensorflow.python.keras.\u impl.keras.estimator import\u save\u first\u checkpoint、\u clone\u和\u build\u model
def模型到估计器(keras模型=无,
keras_模型_路径=无,
自定义对象=无,
model_dir=无,
配置=无):
keras_权重=keras_模型。获取_权重()
keras_model_fn=_create_keras_tpu_model_fn(keras_model,自定义_对象)
est=tf.contrib.tpu.TPUEstimator(keras_model_fn,model_dir=model_dir,config=config)
_保存第一个检查点(keras_模型、est、自定义_对象、keras_权重)
返回est
def_创建_keras_tpu_模型_fn(keras_模型,自定义_对象=无):
def型号(功能、标签、模式):
“”“keras估计器的模型。”“”
模型=_克隆_和_构建_模型(模式、keras_模型、自定义_对象、功能、,
标签)
预测=dict(zip(model.output_名称,model.outputs))
损失=无
列车运行=无
评估度量操作=无
#仅在培训和评估期间设置损耗和度量。
如果模式不是tf.estimator.ModeKeys.PREDICT:
model.optimizer.optimizer=tf.contrib.tpu.CrossShardOptimizer(model.optimizer.optimizer)
型号._make_train_function()35; pylint:disable=受保护访问
损失=模型总损失
如果是model.metrics:
评估度量操作={}
#当每个度量映射到一个输出时
如果存在(model.metrics,dict):
对于i,在enumerate(model.metrics.keys())中输出_名称:
metric\u name=model.metrics[输出\u name]
如果可调用(度量单位名称):
公制名称=公制名称__
#当某些输出使用相同的度量时
如果列表(model.metrics.values()).count(metric_name)>1:
度量值_名称+=''+输出_名称
评估度量操作[度量名称]=tf.metrics.mean(
模型度量\张量[i-len(模型度量)])
其他:
对于i,枚举中的度量_名称(model.metrics):
如果可调用(度量单位名称):
公制名称=公制名称__
评估度量操作[度量名称]=tf.metrics.mean(
模型度量(张量[i])
如果模式为tf.estimator.ModeKeys.TRAIN:
列车运行=model.train\u function.updates\u op
返回tf.contrib.tpu.TPUEstimatorSpec(
模式=模式,
预测=预测,
损失=损失,
列车运行=列车运行,
评估度量操作=评估度量操作)
返回模型