【问题标题】:How to combine a pre-trained KerasLayer from TensorFlow (v. 2) Hub and tfrecords?如何将来自 TensorFlow (v. 2) Hub 的预训练 KerasLayer 和 tfrecords 结合起来?
【发布时间】:2020-03-21 05:08:47
【问题描述】:

我有一个包含 23 个类的 tfrecord,每个类有 35 个图像(总共 805 个)。我当前的 tfrecord 读取函数是:

def read_tfrecord(serialized_example):
 feature_description = {
    'image': tf.io.FixedLenFeature((), tf.string),
    'label': tf.io.FixedLenFeature((), tf.int64),
    'height': tf.io.FixedLenFeature((), tf.int64),
    'width': tf.io.FixedLenFeature((), tf.int64),
    'depth': tf.io.FixedLenFeature((), tf.int64)
 }

 example = tf.io.parse_single_example(serialized_example, feature_description)
 image = tf.io.parse_tensor(example['image'], out_type=float)
 image_shape = [example['height'], example['width'], example['depth']]
 image = tf.reshape(image, image_shape)
 label = tf.cast(example["label"], tf.int32)
 image = image/255

 return image, label

然后我有一个如下所示的 make_dataset 函数:

def make_dataset(tfrecord, BATCH_SIZE, EPOCHS, cache=True):
 files = tf.data.Dataset.list_files(os.path.join(os.getcwd(), tfrecord))
 dataset = tf.data.TFRecordDataset(files)

 if cache:
    if isinstance(cache, str):
      dataset = dataset.cache(cache)
    else:
      dataset = dataset.cache()

 dataset = dataset.shuffle(buffer_size=FLAGS.shuffle_buffer_size)
 dataset = dataset.map(map_func=read_tfrecord, num_parallel_calls=AUTOTUNE)
 dataset = dataset.repeat(EPOCHS)
 dataset = dataset.batch(batch_size=BATCH_SIZE)
 dataset = dataset.prefetch(buffer_size=AUTOTUNE)

 return dataset

这个 make_dataset 函数被传入

train_ds = make_dataset(tfrecord=FLAGS.tf_record, BATCH_SIZE=BATCH_SIZE, EPOCHS=EPOCH)
image_batch, label_batch = next(iter(train_ds))
feature_extractor_layer = hub.KerasLayer(url, input_shape=IMAGE_SHAPE + (3,)) 
feature_batch = feature_extractor_layer(image_batch)
feature_extractor_layer.trainable = False
model = tf.keras.Sequential([feature_extractor_layer, layers.Dense(2048, input_shape=(2048,)), layers.Dense(len(CLASS_NAMES), activation='softmax')])

model.summary()
predictions = model(image_batch)
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=rate),
                              loss='categorical_crossentropy',
                              metrics=['acc'])

batch_stats_callback = CollectBatchStats()
STEPS_PER_EPOCH = np.ceil(image_count / BATCH_SIZE)
history = model.fit(image_batch, label_batch, epochs=EPOCH, batch_size=BATCH_SIZE, steps_per_epoch=STEPS_PER_EPOCH, callbacks=[batch_stats_callback])

这段代码运行的意义在于它输出关于我有多少个 epoch 和一些训练准确度数据的常用信息(即 0,损失约为 100k)。我得到的错误对我没有任何意义,因为它说:函数实例化在索引处具有未定义的输入形状:外部推理上下文中的 100。 您可以将数字替换为 1000 以下的任何值(不确定它是否超过了我的 tfrecord 中的图像数量)。

我对这个完全不知所措。

编辑:

我得到的这个“错误”似乎只是一条警告消息。我怀疑这与 TensorFlow Hub 的使用和潜在的急切执行有关。我加了

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

在文件的开头,警告消失了。

【问题讨论】:

    标签: python keras tensorflow2.0 tfrecord tensorflow-hub


    【解决方案1】:

    我发现如果指定了特征提取层的输出形状,警告信息就会消失,如下所示:

     feature_extractor_layer = hub.KerasLayer(feature_extractor_url, input_shape=(224, 224, 3), output_shape=[1280])
    

    对于您正在使用的特征提取器的实际输入和输出形状。训练过程将像运行时出现警告一样运行。

    【讨论】:

      【解决方案2】:

      按照 kelkka 的规定,它不是错误,而只是警告。

      在程序开始时添加以下代码行将限制要打印的警告消息。

      os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
      

      该环境变量的其他值及其行为如下所述:

      • 0 = 记录所有消息(默认行为)
      • 1 = 不打印 INFO 消息
      • 2 = 不打印 INFO 和 WARNING 消息
      • 3 = 不打印 INFO、WARNING 和 ERROR 消息

      有关控制警告消息的详细程度的更多信息,请参阅Stack Overflow Answer

      【讨论】:

      • 我认为这只是一个警告,而不是错误。您能否详细说明为什么更改日志记录级别是解决当前问题的可行解决方案?
      • 修改了答案以详细说明为什么更改日志记录级别是一个可行的解决方案。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2017-01-27
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多