当前位置: 首页 > 面试题库 >

TensorFlow 2.0 Keras:如何为TensorBoard编写图像摘要

段干飞翔
2023-03-14
问题内容

我正在尝试使用TensorFlow 2.0设置图像识别CNN。为了能够分析我的图像增强,我想查看我在张量板上馈入网络的图像。

不幸的是,我不知道如何使用TensorFlow 2.0和Keras做到这一点。我也没有真正找到关于此的文档。

为简单起见,我展示了MNIST示例的代码。如何在此处添加图片摘要?

import tensorflow as tf
(x_train, y_train), _ = tf.keras.datasets.mnist.load_data()

def scale(image, label):
    return tf.cast(image, tf.float32) / 255.0, label

def augment(image, label):
    return image, label  # do nothing atm

dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
dataset = dataset.map(scale).map(augment).batch(32)

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(dataset, epochs=5, callbacks=[tf.keras.callbacks.TensorBoard(log_dir='D:\\tmp\\test')])

问题答案:

除了提供您问题的答案外,我还将使代码更像TF2.0。如果您有任何疑问/需要澄清,请在下面发表评论。

我建议使用Tensorflow
Datasets
库。如果可以在一行中完成数据,则绝对不需要加载数据numpy并将其转换为tf.data.Dataset

import tensorflow_datasets as tfds

dataset = tfds.load("mnist", as_supervised=True, split=tfds.Split.TRAIN)

上面的行只会返回TRAINsplit(在此处了解更多信息)。

2.定义扩充和摘要

为了保存图像,必须在每次遍历期间保留tf.summary.SummaryWriter对象。

我创建了一个带有__call__方法的便捷包装类,可轻松使用tf.data.Datasetmap功能:

import tensorflow as tf

class ExampleAugmentation:
    def __init__(self, logdir: str, max_images: int, name: str):
        self.file_writer = tf.summary.create_file_writer(logdir)
        self.max_images: int = max_images
        self.name: str = name
        self._counter: int = 0

    def __call__(self, image, label):
        augmented_image = tf.image.random_flip_left_right(
            tf.image.random_flip_up_down(image)
        )
        with self.file_writer.as_default():
            tf.summary.image(
                self.name,
                augmented_image,
                step=self._counter,
                max_outputs=self.max_images,
            )

        self._counter += 1
        return augmented_image, label

name将是保存图像各部分的名称。您可能会问哪一部分-由定义的部分max_outputs

image__call__将具有形状(32, 28, 28, 1),其中第一维是分批,第二宽度,第三高度和最后通道(MNIST的情况下,只有1升但需要在此维度tf.image扩充)。此外,假设max_outputs指定为4。在这种情况下,批次中仅保存4张第一张图像。默认值为3,因此您可以将其设置为BATCH_SIZE保存每张图像。

在中Tensorboard,每个图像将是一个单独的样本,您可以在其上最后进行迭代。

_counter是必需的,这样图像 就不会 被覆盖(我想,不是很确定,其他人的澄清会很好)。

重要提示: 您可能希望将此类重命名为类似的操作,例如ImageSaver,进行更严重的商务活动并将增强移动到单独的函子/
lambda函数时。我猜这足以满足演示目的。

3.设置全局变量

请不要混合使用函数声明,全局变量,数据加载和其他内容
(例如加载数据并随后创建函数)。我知道TF1.0鼓励这种类型的编程,但是他们正设法摆脱这种编程,您可能想跟上潮流。

我在下面定义了一些全局变量,这些变量将在接下来的部分中使用,我想这很容易解释:

BATCH_SIZE = 32
DATASET_SIZE = 60000
EPOCHS = 5

LOG_DIR = "/logs/images"
AUGMENTATION = ExampleAugmentation(LOG_DIR, max_images=4, name="Images")

4.数据集扩充

与您的相似,但略有不同:

dataset = (
    dataset.map(
        lambda image, label: (
            tf.image.convert_image_dtype(image, dtype=tf.float32),
            label,
        )
    )
    .batch(BATCH_SIZE)
    .map(AUGMENTATION)
    .repeat(EPOCHS)
)
  • repeat 因为加载的数据集是生成器,所以需要
  • tf.image.convert_image_dtype-比显式tf.cast混合除法更好和更具可读性的选项255(并确保正确的图像格式)
  • 为了演示起见,在增强之前完成了批处理

5.定义模型,编译,训练

几乎与您在示例中所做的一样,但是我提供了额外的steps_per_epoch,因此fit知道构成一个纪元的批次数:

model = tf.keras.models.Sequential(
    [
        tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
        tf.keras.layers.Dense(128, activation="relu"),
        tf.keras.layers.Dropout(0.2),
        tf.keras.layers.Dense(10, activation="softmax"),
    ]
)

model.compile(
    optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"]
)
model.fit(
    dataset,
    epochs=EPOCHS,
    steps_per_epoch=DATASET_SIZE // BATCH_SIZE,
    callbacks=[tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR)],
)

除了我认为的以外,没有太多其他解释。

6.运行Tensorboard

由于TF2.0可以在colab中使用进行操作%tensorboard --logdir /logs/images,因此只想为可能访问此问题的其他人添加此功能。随心所欲地做,无论如何,您肯定会知道如何做。

图像应在内部,IMAGES并且每个由命名的样本都应name提供给AUGMENTATION对象。

7.完整代码(使每个人的生活更轻松)

import tensorflow as tf
import tensorflow_datasets as tfds


class ExampleAugmentation:
    def __init__(self, logdir: str, max_images: int, name: str):
        self.file_writer = tf.summary.create_file_writer(logdir)
        self.max_images: int = max_images
        self.name: str = name
        self._counter: int = 0

    def __call__(self, image, label):
        augmented_image = tf.image.random_flip_left_right(
            tf.image.random_flip_up_down(image)
        )
        with self.file_writer.as_default():
            tf.summary.image(
                self.name,
                augmented_image,
                step=self._counter,
                max_outputs=self.max_images,
            )

        self._counter += 1
        return augmented_image, label


if __name__ == "__main__":

    # Global settings

    BATCH_SIZE = 32
    DATASET_SIZE = 60000
    EPOCHS = 5

    LOG_DIR = "/logs/images"
    AUGMENTATION = ExampleAugmentation(LOG_DIR, max_images=4, name="Images")

    # Dataset

    dataset = tfds.load("mnist", as_supervised=True, split=tfds.Split.TRAIN)

    dataset = (
        dataset.map(
            lambda image, label: (
                tf.image.convert_image_dtype(image, dtype=tf.float32),
                label,
            )
        )
        .batch(BATCH_SIZE)
        .map(AUGMENTATION)
        .repeat(EPOCHS)
    )

    # Model and training

    model = tf.keras.models.Sequential(
        [
            tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
            tf.keras.layers.Dense(128, activation="relu"),
            tf.keras.layers.Dropout(0.2),
            tf.keras.layers.Dense(10, activation="softmax"),
        ]
    )

    model.compile(
        optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"]
    )
    model.fit(
        dataset,
        epochs=EPOCHS,
        steps_per_epoch=DATASET_SIZE // BATCH_SIZE,
        callbacks=[tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR)],
    )


 类似资料:
  • 本文向大家介绍TensorFlow保存TensorBoard图像操作,包括了TensorFlow保存TensorBoard图像操作的使用技巧和注意事项,需要的朋友参考一下 简单的代码: ipython中使用!+命令可以直接运行terminal命令。 terminal输入: tensorboard --logdir graph/ 跳出:Starting TensorBoard 54 at http:

  • 问题内容: 您能否指导我如何将图像从URL转换为base64编码? 问题答案: 我认为应该是:

  • 问题内容: 我的NodeJS服务器收到一个图片,编码为base64。 收到的数据应另存为jpg。因此,我使用了Buffer和FileSystemWriter: fs.writeFile不会调用错误。jpeg文件已保存,但无法打开。图像查看器说: 原始文件大6kb,新文件大7kb。 问题答案: 您必须从其中剥离url元信息。(重申@CBroe所说的)这是一个小函数,用于从输入字符串返回正确的信息。

  • 我想写一个小游戏,我可以用W,a,S,D键在JavaFX面板上移动一个球 我有一个和但是我不知道如何编写一个,如果我按D,它将计算。 我必须做什么?

  • 问题内容: 我可以在iPhone上的Objective-C中执行此操作,但是现在我正在寻找等效的Android Java代码。我也可以用普通Java做到这一点,但是我不知道Android特定的类是什么。我想动态生成一个PNG图像,该图像中有一些文本居中。 相关线程: 如何在Objective-C(iOS)中的图像上写文字? 如何使用Java加载图像并向其中写入文本? 问题答案: 怎么样呢?

  • 正如你在下面的代码片段中看到的,我很难让蓝色覆盖贴在图像上,但是正如你所看到的,在左侧,由于某种原因,它没有贴在图片上。是的,我希望一整列的位置比另一列低/高一点,所以这里我尝试将整列1定位70px,但它撕裂了蓝色覆盖层和图像。有什么想法吗? null null