tensorflow.keras估计器train_and_evaluate在评估时抛出RuntimeError

时间:2019-04-25 12:04:11

标签: python-3.x tensorflow tensorflow-estimator tf.keras

我的张量流版本为 1.12.0

我正在尝试在我的自定义数据集(存储为tfrecords)上对经过预训练的Keras ResNet-50网络进行再训练。下面是我的代码:

import tensorflow as tf
from tensorflow import keras
import numpy as np

from tensorflow.keras.applications import resnet50

from tensorflow.keras import models, layers, optimizers

def dummy_model(features, num_classes):

    conv1 = layers.Conv2D(32, kernel_size=4, activation='relu')(features)
    pool1 = layers.MaxPooling2D(pool_size=(2, 2))(conv1)
    conv2 = layers.Conv2D(16, kernel_size=4, activation='relu')(pool1)
    pool2 = layers.MaxPooling2D(pool_size=(2, 2))(conv2)
    flat = layers.Flatten()(pool2)
    hidden_layer_1 = layers.Dense(10, activation='relu')(flat)
    logits = layers.Dense(num_classes)(hidden_layer_1) 

    return logits



def resnet50_network(features, num_classes):

    base = resnet50.ResNet50(weights='imagenet', input_tensor=features,include_top=False)
    base_features = base.output    
    flat = layers.Flatten()(base_features)    
    hidden_layer_1 = layers.Dense(1024, activation='relu')(flat)    
    logits = layers.Dense(num_classes)(hidden_layer_1)

    return logits



def model_fn(features, labels, mode, params):

    num_classes = params['num_classes']
    #tf.keras.backend.set_learning_phase(mode==tf.estimator.ModeKeys.TRAIN)
    #logits = dummy_model(features, num_classes)
    logits = resnet50_network(features, num_classes)

    loss_tensor = tf.nn.softmax_cross_entropy_with_logits_v2(
        logits=logits,
        labels=labels)

    loss = tf.reduce_mean(loss_tensor, name='loss')

    if mode==tf.estimator.ModeKeys.EVAL:
        prec, prec_update_op = tf.metrics.precision(labels=tf.argmax(labels), predictions=logits, name='precision_op')
        recall, recall_update_op = tf.metrics.recall(labels=tf.argmax(labels), predictions=logits, name='recall_op')

        metrics = { \
        'recall':(recall, recall_update_op), 
        'precision':(prec, prec_update_op) }

        return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics)

    assert mode==tf.estimator.ModeKeys.TRAIN

    optimizer = tf.train.AdamOptimizer(
                 learning_rate=params['learning_rate'],
                 name='Adam')

    global_step = tf.train.get_global_step()

    update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
    with tf.control_dependencies(update_ops):
        train_op = optimizer.minimize(loss, global_step = global_step)

    return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)

configuration = tf.estimator.RunConfig(
      model_dir = save_directory,
      keep_checkpoint_max=10,
      session_config = sess_config,
      save_checkpoints_steps=1000,
      log_step_count_steps=100)  

classifier = tf.estimator.Estimator(
      model_fn=model_fn, 
      params={ \
      'learning_rate':1e-3,
      'num_classes':20,
      'decay':0.995}, 
      config=configuration
      )


train_spec = tf.estimator.TrainSpec(
      input_fn=lambda:imgs_input_fn(filenames=train_outpath), 
      max_steps=10000) 

eval_spec = tf.estimator.EvalSpec(
      input_fn=lambda:imgs_input_fn(filenames=test_outpath), 
      steps=100)

tf.estimator.train_and_evaluate(classifier, train_spec, eval_spec)

当我使用logits = dummy_model(features, num_classes)而不是logits = resnet50_network(features, num_classes)时,以上代码可以正常工作。当我使用后面的(resnet50_network)运行时,它会抛出

  

RuntimeError:图形已完成,无法修改。

应该使用后来的resnet50_network函数来在imagenet上获取经过预训练的resnet-50,以添加一个密集层并将logit返回给调用方。

前者,即dummy_model创建了一个小的CNN,可以从头开始进行训练。

如果我尝试使用预训练的模型,以上内容只会引发错误。

0 个答案:

没有答案