我的张量流版本为 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,可以从头开始进行训练。
如果我尝试使用预训练的模型,以上内容只会引发错误。