用于训练 GoogLeNet 模型的快速数据生成器

发布于 2025-01-12 00:33:21 字数 2427 浏览 0 评论 0原文

我尝试在 Keras 中从头开始训练 GoogLeNet。我构建了网络架构,并准备好进行训练。使用辅助输出训练 GoogLeNet,数据生成器应具有三个输出标签。我使用 tf.keras.utils.Sequence 编写自定义数据生成器。

我的自定义生成器是:

from skimage.transform import resize
from skimage.io import imread
import numpy as np
import math
from tensorflow.keras.utils import Sequence


class GoogLeNetDatasetGenerator(Sequence):

    def __init__(self, X_train_path, y_train, batch_size):
        """
        Initialize the GoogLeNet dataset generator.
        :param X_train_path: Path of train images
        :param y_train: Labels of train images
        :param batch_size:
        """

        self.X_train_path = X_train_path
        self.y_train = y_train
    self.batch_size = batch_size

        self.indexes = np.arange(len(self.X_train_path))
        np.random.shuffle(self.indexes)

    def __len__(self):
        """
        Denotes the number of batches per epoch
        :return:
        """

        return math.ceil(len(self.X_train_path) / self.batch_size)

    def __getitem__(self, index):
        """
        Get batch indexes from shuffled indexes
        :param index:
        :return:
        """

        indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]
        X_batch_names = [self.X_train_path[i] for i in indexes]
        y_batch_naive = self.y_train[indexes]

        X_batch = np.array([resize(imread(file_name), (224, 224) for file_name in X_batch_names],
                       dtype='float32')
        y_batch = [y_batch_naive, y_batch_naive, y_batch_naive]

        return X_batch, y_batch

    def on_epoch_end(self):
        """
        Updates indexes after each epoch
        :return:
        """

        self.indexes = np.arange(len(self.X_train_path))
        np.random.shuffle(self.indexes)

另外,我使用以下代码编译和训练模型:

# Compile model
model.compile(loss=[CategoricalCrossentropy(), CategoricalCrossentropy(), CategoricalCrossentropy()],
                  loss_weights=[1, 0.3, 0.3], optimizer='adam',
                  metrics=['accuracy'])

# Train model
history = model.fit(train_dataset, validation_data=test_dataset, epochs=100)

使用 GPU 版本的 TensorFlow 时,在数据生成器中加载图像非常耗时。它导致训练过程缓慢。有什么建议或其他解决方案可以加快加载数据的速度吗?

聚苯乙烯 我搜索 StackOverflow 问题,例如 this,但我没有找到任何想法。

I try to train GoogLeNet from scratch in Keras. I build the network architecture, and it is ready to train. Train GoogLeNet with auxiliaries outputs, the data generator should have three output labels. I write my custom data generator using tf.keras.utils.Sequence.

My custom generator is:

from skimage.transform import resize
from skimage.io import imread
import numpy as np
import math
from tensorflow.keras.utils import Sequence


class GoogLeNetDatasetGenerator(Sequence):

    def __init__(self, X_train_path, y_train, batch_size):
        """
        Initialize the GoogLeNet dataset generator.
        :param X_train_path: Path of train images
        :param y_train: Labels of train images
        :param batch_size:
        """

        self.X_train_path = X_train_path
        self.y_train = y_train
    self.batch_size = batch_size

        self.indexes = np.arange(len(self.X_train_path))
        np.random.shuffle(self.indexes)

    def __len__(self):
        """
        Denotes the number of batches per epoch
        :return:
        """

        return math.ceil(len(self.X_train_path) / self.batch_size)

    def __getitem__(self, index):
        """
        Get batch indexes from shuffled indexes
        :param index:
        :return:
        """

        indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]
        X_batch_names = [self.X_train_path[i] for i in indexes]
        y_batch_naive = self.y_train[indexes]

        X_batch = np.array([resize(imread(file_name), (224, 224) for file_name in X_batch_names],
                       dtype='float32')
        y_batch = [y_batch_naive, y_batch_naive, y_batch_naive]

        return X_batch, y_batch

    def on_epoch_end(self):
        """
        Updates indexes after each epoch
        :return:
        """

        self.indexes = np.arange(len(self.X_train_path))
        np.random.shuffle(self.indexes)

Also, I compile and train the model with the following codes:

# Compile model
model.compile(loss=[CategoricalCrossentropy(), CategoricalCrossentropy(), CategoricalCrossentropy()],
                  loss_weights=[1, 0.3, 0.3], optimizer='adam',
                  metrics=['accuracy'])

# Train model
history = model.fit(train_dataset, validation_data=test_dataset, epochs=100)

While using the GPU version of TensorFlow, loading images in the data generator is time-consuming. It causes the training process slow. Is there any suggestion or other solutions for speeding up the loading data?

P.S.
I search the StackOverflow question such as this, but I did not find any idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱殇璃 2025-01-19 00:33:21

我找到了另一个更快的解决方案。您可以使用tf.data.Dataset。在第一步中,我列出了所有训练图像目录。使用map方法帮助我读取图像并正确配置相应的标签。这是我的示例代码,用于加载带有三元标签的图像。

image_filenames = tf.constant(image_list)

slices_dataset = tf.data.Dataset.from_tensor_slices(image_filenames)
slices_labels = tf.data.Dataset.from_tensor_slices(label_list)

image_dataset = slices_dataset.map(map_func=process_image)
label_dataset = slices_labels.map(map_func=process_label)

x_dataset = image_dataset.shuffle(buffer_size=Cfg.BUFFER_SIZE, seed=0).\
    batch(batch_size=Cfg.BATCH_SIZE)
y_dataset = label_dataset.shuffle(buffer_size=Cfg.BUFFER_SIZE, seed=0).\
    batch(batch_size=Cfg.BATCH_SIZE)

dataset = tf.data.Dataset.zip((x_dataset, y_dataset))

I found another faster solution. You can use tf.data.Dataset. In the first step, I list all training images directory. Using the map method helped me read the image and properly configure the corresponding label. Here is my sample code to load an image with the ternary label.

image_filenames = tf.constant(image_list)

slices_dataset = tf.data.Dataset.from_tensor_slices(image_filenames)
slices_labels = tf.data.Dataset.from_tensor_slices(label_list)

image_dataset = slices_dataset.map(map_func=process_image)
label_dataset = slices_labels.map(map_func=process_label)

x_dataset = image_dataset.shuffle(buffer_size=Cfg.BUFFER_SIZE, seed=0).\
    batch(batch_size=Cfg.BATCH_SIZE)
y_dataset = label_dataset.shuffle(buffer_size=Cfg.BUFFER_SIZE, seed=0).\
    batch(batch_size=Cfg.BATCH_SIZE)

dataset = tf.data.Dataset.zip((x_dataset, y_dataset))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文