【keras】使用fit_generator训练超大数据集

2023-05-16

对于小规模的数据集我们可以将其一次性读入内存(CPU)中然后再分batch让GPU去训练,只要简单地使用fit函数即可;然而当数据集规模超大时,一次性读入所有数据会使得内存溢出(与GPU无关,GPU是显存,batch_size过大才会导致显存爆炸),我们需要使用fit_generator来训练

如下,

fit_generator(generator, steps_per_epoch=None,
              epochs=1, verbose=1,
              callbacks=None, validation_data=None,
              validation_steps=None,  class_weight=None,
              max_queue_size=10, workers=1,
              use_multiprocessing=False, shuffle=True, initial_epoch=0)

它具有很多参数,其中比较重要的参数是generator,我们可以使用python的生成器,也可以使用keras.utils中的Sequence,个人比较推荐后者,它需要重写两个函数:

  • len()
  • getitem()

其实也很简单,以下举个简单的例子你便能学会写自己的数据自动生成器。

代码如下,接下来一个个函数解释。

import numpy
import matplotlib.image as mpimg  # read image
from keras.utils import Sequence, to_categorical

class DataGenerator(Sequence):

    def __init__(self, files, batch_size=1, shuffle=True):
        """
        # Arguments
        ---
            files: filename.
            batch_size: . """

        self.batch_size = batch_size
        self.files = files
        self.indexes = numpy.arange(len(self.files))
        self.shuffle = shuffle

    def __len__(self):
        """return: steps num of one epoch. """
        return len(self.files) // self.batch_size

    def __getitem__(self, index):
        """Gets the `index-th` batch.
        ---
        # Arguments
            index: position of the batch in the Sequence.
        # Returns
            A batch data. """

        # get batch data inds.
        batch_inds = self.indexes[index *
                                  self.batch_size:(index+1)*self.batch_size]
        # get batch data file name.
        batch_files = [self.files[k] for k in batch_inds]

        # read batch data
        batch_images, batch_labels = self._read_data(batch_files)

        return batch_images, batch_labels

    def on_epoch_end(self):
        """shuffle data after one epoch. """
        if self.shuffle == True:
            numpy.random.shuffle(self.indexes)

    def _read_data(self, batch_files):
        """Read a batch data.
        ---
        # Arguments
            batch_files: the file of batch data.

        # Returns
            images: (batch_size, (image_shape)).
            labels: (batch_size, (label_shape)). """

        images = []
        labels = []

        for file in batch_files:
            image = mpimg.imread('data/Images/'+file+'.jpg')
            images.append(image)
            lable = numpy.loadtxt('data/labels/'+file+'.arr', dtype=int)
            labels.append(lable)  # to one hot

        return numpy.array(images), numpy.array(labels)

init

首先定义自己的数据生成器 DataGenerator 继承Sequence类,初始化参数

class DataGenerator(Sequence):
    def __init__(self, files, batch_size=1, shuffle=True):
        """
        # Arguments
        ---
            files: filename.
            batch_size: . """
        self.batch_size = batch_size
        self.files = files
        self.indexes = numpy.arange(len(self.files))
        self.shuffle = shuffle
  • files:所有训练样本的文件路径
  • batch_size:一个batch的大小

例如我做图像分割任务,图片大概是这样的
在这里插入图片描述
label是像素标签矩阵,与上面的每张图片对应
在这里插入图片描述
因此我只需要除了文件后缀之外的字符串即可,当读取对应的图片或label时我再在后面添加对应的后缀。所以传入的 files 大概是这样的:
在这里插入图片描述
并且创建一个index变量用来划分数据集。

len

len函数计算每一个epoch的步长,即每个epoch有多少个batch要训练

def __len__(self):
    """return: steps num of one epoch. """
    return len(self.files) // self.batch_size

getitem函数要求返回一个batch的data,包括输入数据和标签,参数是index(训练的时候会自动调用),代表第index个batch,通过这个index我们去计算这个batch的数据的下标(batch_inds),然后提取出它对应的文件名字(batch_files),把这个batch_files传入给_read_data函数让它取读取这个batch的image和label

def __getitem__(self, index):
    """Gets the `index-th` batch.
    ---
    # Arguments
        index: position of the batch in the Sequence.
    # Returns
        A batch data. """

    # get batch data inds.
    batch_inds = self.indexes[index *
                                self.batch_size:(index+1)*self.batch_size]
    # get batch data file name.
    batch_files = [self.files[k] for k in batch_inds]

    # read batch data
    batch_images, batch_labels = self._read_data(batch_files)

    return batch_images, batch_labels

_read_data

这个函数就是根据文件名去读取自己对应任务的数据了。

def _read_data(self, batch_files):
    """Read a batch data.
    ---
    # Arguments
        batch_files: the file of batch data.

    # Returns
        images: (batch_size, (image_shape)).
        labels: (batch_size, (label_shape)). """

    images = []
    labels = []

    for file in batch_files:
        image = mpimg.imread('data/Images/'+file+'.jpg')
        images.append(image)
        lable = numpy.loadtxt('data/labels/'+file+'.arr', dtype=int)
        labels.append(lable)  # to one hot

    return numpy.array(images), numpy.array(labels)

on_epoch_end

这个函数是每个epoch结束后调用,是否将数据集打乱。

def on_epoch_end(self):
    """shuffle data after one epoch. """
    if self.shuffle == True:
        numpy.random.shuffle(self.indexes)

以上即为构造数据生成器的过程,在构造模型时,可参考以下例子。构造FCN32模型,且用两个GPU来训练,此时batchsize的大小如果是1会报错,因为另一个GPU就没有训练数据了,所以batchsize至少是2,如果是单个GPU训练则不影响。

def get_generator(num_classes, batch_size=2, preprocess=True, shuffle=True, train_ratio=0.8):
    """Get data generator for training and test files.
    ---
    # Arguments
        num_classes: .
        preprocess: preprocess image data.
        shuffle: shuffle data after epoch.
        train_ratio: split data.

    # Returns
        generator: data generator for fit_generator.
        test_files: test model after training. """

    images_files = os.listdir('data/Images')
    allfiles = []
    for file in images_files:
        allfiles.append(file.split('.')[0])  # get image name
    N = len(allfiles)
    train_files = allfiles[:int(N*train_ratio)]
    test_files = allfiles[int(N*train_ratio):]
    generator = DataGenerator(train_files, num_classes,
                              batch_size, preprocess, shuffle)
    return generator, test_files

num_classes = 34
# Get generator.
generator, test_files = get_generator(num_classes,
                                      batch_size=2,
                                      preprocess=True,
                                      shuffle=True,
                                      train_ratio=0.8)
# Build model.
model = FCN32.build(height=256, width=256, num_classes=num_classes)
model = multi_gpu_model(model, gpus=2)  # 两个GPU, batch_size至少应该是2
model.summary()
model.compile(optimizer=Adam(0.00001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# fit model.
model.fit_generator(generator, epochs=20)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【keras】使用fit_generator训练超大数据集 的相关文章

  • 使用 CustomCallback() 类在训练时实现冻结层

    我正在尝试在 TensorFlow 中训练自定义 CNN 模型 我想以某种方式在训练仍在运行时冻结特定时期模型的某些层 我已经实现了冻结层 但我必须在某些时期训练模型 然后在我想要冻结的特定层中将可训练属性更改为 False 然后编译模型
  • Google Colab:为什么 CPU 比 TPU 快?

    我正在使用 Google colabTPU训练一个简单的Keras模型 删除分布式strategy并在CPU比TPU 这怎么可能 import timeit import os import tensorflow as tf from sk
  • 结合两个 CNN

    我想在 Keras 中将两个 CNN 合并为一个 我的意思是我希望神经网络拍摄两张图像并在单独的 CNN 中处理每一张图像 然后将它们连接在一起进入扁平化层并使用全连接层来做最后的工作 我做了什么 Start With First Bran
  • 如何设置 1dCNN+LSTM 网络(Keras)的输入形状?

    我有以下想法要实施 Input gt CNN gt LSTM gt Dense gt Output 输入有 100 个时间步长 每个步长有一个 64 维特征向量 A Conv1D层将在每个时间步提取特征 CNN 层包含 64 个滤波器 每个
  • 验证准确性非常好,但预测很差

    我正在构建一个 keras 模型来对猫和狗进行分类 我使用具有瓶颈特征的迁移学习和 vgg 模型的微调 现在我得到了非常好的验证准确率 例如 97 但是当我进行预测时 我得到了关于分类报告和混淆矩阵的非常糟糕的结果 可能是什么问题呢 这是微
  • Keras 获取中间层的输出

    what my model looks like defining the model archictecture model Sequential 1st conv layer model add Conv2D 32 5 5 activa
  • 当我想在电脑中加载该模型时,我可以在 colab bu 中加载我的深度模型,但我不能

    我在colab中通过keras 2 3 1和tensorflow 2 1 0训练了一个深度模型 我用JSON和Keras保存了我的模型 saveWeightPath content drive My Drive model info mod
  • Tensorflow:logits 和标签必须具有相同的第一维

    我是张量流新手 我想改编 MNIST 教程https www tensorflow org tutorials layers https www tensorflow org tutorials layers用我自己的数据 40x40 的图
  • ValueError:“连接”层需要具有匹配形状的输入(连接轴除外)

    我正在尝试为我的项目构建 Pix2Pix 并收到错误 值错误 Concatenate层需要具有匹配形状的输入 除了连接轴之外 获得输入形状 None 64 64 128 None 63 63 128 生成器是一个 U 网模型 我的输入高度
  • 在 keras 中使用自定义张量流操作

    我在张量流中有一个脚本 其中包含自定义张量流操作 我想将代码移植到 keras 但我不确定如何在 keras 代码中调用自定义操作 我想在 keras 中使用tensorflow 所以到目前为止我发现的教程描述了与我想要的相反的内容 htt
  • 如何知道生成的序列最多是一定长度

    我想知道生成的序列是否少于 2 个条目 gt gt gt def sequence for i in xrange secret yield i 我的低效方法是创建一个列表 并测量其长度 gt gt gt secret 5 gt gt gt
  • 如何在 R 中创建循环来生成随机样本列表?

    我正在尝试创建一个循环来创建一系列包含随机样本的对象 如下所示 sample lt ceiling runif 9 min 0 max 20 这是圆形制服的示例 但它可以替换为普通 泊松或任何您想要的 因此 我构建了一个循环来自动生成各种生
  • keras 中的增量学习

    我正在寻找 scikit learn 的 keras 等效项partial fit https scikit learn org 0 15 modules scaling strategies html incremental learni
  • C# 的快速线程安全随机数生成器

    我需要在多个正在运行的线程中快速生成随机浮点数 我尝试过使用System Random 但它对于我的需求来说太慢了 并且它在多个线程中返回相同的数字 当我在单线程中运行应用程序时 它工作正常 此外 我需要确保生成的数字在 0 到 100 之
  • Native TF 与 Keras TF 性能比较

    我使用本机和后端张量流创建了完全相同的网络 但在使用多个不同参数进行了多个小时的测试后 仍然无法弄清楚为什么 keras 优于本机张量流并产生更好 稍微但更好 的结果 Keras 是否实现了不同的权重初始化方法 或者执行除 tf train
  • Tensorflow Hub - 获取模型的输入形状和问题域?

    我正在使用最新版本的tensorflow hub 想知道如何获取有关模型的预期输入形状以及模型属于什么类型的集合的信息 例如 有没有办法以这种方式在 Python 中加载模型后获取有关预期图像形状的信息 model hub load htt
  • 在 Keras 上使用回调 Tensorboard 时出现 AttributeError:“Model”对象没有属性“run_eagerly”

    我已经使用 Keras 的功能 API 构建了一个模型 当我将 Tensorboard 实例添加到 model fit 函数的回调中时 它会抛出一个错误 AttributeError Model object has no attribut
  • ValueError:没有为“dense_input”提供数据

    我正在使用以下简单的代码使用tensorflow加载csv并使用keras执行建模 无法弄清楚这个错误 import tensorflow as tf train dataset fp tf keras utils get file fna
  • ValueError:请使用“Layer”实例初始化“TimeDistributed”层

    我正在尝试构建一个可以在音频和视频样本上进行训练的模型 但出现此错误ValueError Please initialize TimeDistributed layer with a Layer instance You passed Te
  • 如何在 keras 中添加可训练的 hadamard 产品层?

    我试图在训练样本中引入稀疏性 我的数据矩阵的大小为 比如说 NxP 我想将其传递到一个层 keras 层 该层的权重大小与输入大小相同 即可训练权重矩阵W的形状为NxP 我想对这一层的输入矩阵进行哈达玛乘积 逐元素乘法 W 按元素与输入相乘

随机推荐

  • 离散马尔科夫链的平稳分布的两种解法

    假设离散马尔科夫链的转移矩阵为 P P P xff0c 平稳分布为 pi xff0c 则平稳分布满足 xff1a
  • 协方差矩阵的几何意义

    假设原始数据为 X X X xff0c 其协方差矩阵 C C C 为对称矩阵 xff0c 协方差矩阵的特征分解为
  • DBSCAN算法原理

    DBSCAN Density Based Spatial Clustering of Applications with Noise xff0c 基于密度的噪声空间聚类 大概思想 xff1a 给定一组空间中的点 xff0c 它会将紧密挨在一
  • 【tf】tf.expand_dims()

    增加张量维度 span class token keyword import span tensorflow span class token keyword as span tf a span class token operator 6
  • 卷积与反卷积

    卷积与反卷积 xff0c 及其在tensorflow中的接口 xff0c 文章 keras中的卷积 xff0c 文章 卷积时padding选择 same 则卷积结果和输入相同 xff0c 选择 valid 则根据公式 o 61 i
  • 【tf】tf.nn.relu_layer()

    tf nn relu layer x weights biases name 61 None tf nn relu x 函数对卷积后的结果进行激活 xff0c 而tf nn relu layer对输入变量x和weights做矩阵乘法并加上b
  • 【keras】搭建简单的神经网络

    span class token keyword from span keras span class token keyword import span layers span class token keyword from span
  • 进程间数据共享

    windows核心编程之进程间共享数据 走看看 zoukankan com
  • 深度学习训练神经网络时一些名词的意思

    假设训练数据集合 T T T 包含 N N N 个样本 xff0c 将数据集划分为 B
  • 【keras】将标签转化为one-hot

    将标签转换为onehot span class token keyword from span keras span class token punctuation span utils span class token keyword i
  • 交叉熵

    参考自 xff0c 文章 在度量两个概率分布的差距时 xff0c 我们通常会使用KL 散度 xff0c 例如对于 p p p q q q 两个概率分布 xff0c 其KL 散度为
  • 深度学习分类损失函数

    损失函数softmax cross entropy binary cross entropy sigmoid cross entropy之间的区别与联系 xff0c 以及其在tensorflow中的用法 文章 softmax cross e
  • 图像分割任务中的图像增强

    对数据进行增强是一种常用的操作 xff0c 用来生成更多的数据 xff0c 提高模型的泛化能力 xff0c 对图像数据增强的常用方法有 xff1a 弹性形变 旋转 加入噪声等 在图像分割任务中 xff0c 除了需要对图像进行变换外 xff0
  • Python保存图片

    image为三维数组 xff08 RGB xff09 或一维数组 xff08 灰白 xff09 span class token keyword import span matplotlib span class token punctua
  • 【keras】多GPU训练模型及保存

    下面是一个小demo xff0c 需要注意的地方是保存模型的时候只保存单个GPU的模型 xff0c 不要保存多GPU训练的模型 xff0c 否则加载时会报错的 span class token keyword from span sklea
  • LSTM参数个数计算方法

    计算LSTM的参数个数需要了解其工作原理 xff0c 如下 xff1a 可以看到若不加偏置 xff0c 该LSTM层共有4个权重参数 xff0c 图中输入的一个timestep的特征大小为3 xff08 绿色单元 xff09 xff0c 隐
  • 【keras】搭建多层lstm层

    记住中间的lstm层需要返回所有timestep的输出作为下一层lstm的输入 xff0c 所以除了最后一层lstm外其它层的return sequences 61 True span class token keyword from sp
  • 【keras】利用LSTM做简单的时间序列预测

    项目地址 首先加载时间序列数据集 xff0c 数据集 span class token keyword import span pandas span class token keyword as span pd data span cla
  • advanced installer 使用常见问题整理

    1 安装文件没有被覆盖问题 解决 xff1a Files and Folders 选择所有文件 右键 Properties Operations Always overwrite existing file 2 ocx或dll文件的注册 解
  • 【keras】使用fit_generator训练超大数据集

    对于小规模的数据集我们可以将其一次性读入内存 xff08 CPU xff09 中然后再分batch让GPU去训练 xff0c 只要简单地使用fit函数即可 xff1b 然而当数据集规模超大时 xff0c 一次性读入所有数据会使得内存溢出 x