【问题标题】:How to batch train a CNN with Keras fit_generator?如何使用 Keras fit_generator 批量训练 CNN?
【发布时间】:2017-08-24 10:32:09
【问题描述】:

抱歉,如果这是我提出问题的错误地方(如果是这种情况,请帮助我找出最好的提出问题的地方)。我是 Keras 和 Python 的新手,所以希望回复时考虑到这一点。

我正在尝试训练一个将图像作为输入的 CNN 转向模型。这是一个相当大的数据集,所以我创建了一个数据生成器来使用 fit_generator()。我不清楚如何让这个方法在批次上训练,所以我假设生成器必须将批次返回给 fit_generator()。生成器如下所示:

def gen(file_name, batchsz = 64):
    csvfile = open(file_name)
    reader = csv.reader(csvfile)
    batchCount = 0
    while True:
        for line in reader:
            inputs = []
            targets = []
            temp_image = cv2.imread(line[1]) # line[1] is path to image
            measurement = line[3] # steering angle
            inputs.append(temp_image)
            targets.append(measurement)
            batchCount += 1
            if batchCount >= batchsz:
                batchCount = 0
                X = np.array(inputs)
                y = np.array(targets)
                yield X, y
        csvfile.seek(0)

它读取包含遥测数据(转向角度等)和图像样本路径的 csv 文件,并返回大小为:batchsz 的数组 对 fit_generator() 的调用如下所示:

tgen = gen('h:/Datasets/dataset14-no.zero.speed.trn.csv', batchsz = 128) # Train data generator
vgen = gen('h:/Datasets/dataset14-no.zero.speed.val.csv', batchsz = 128) # Validation data generator
try:
    model.fit_generator(
        tgen,
        samples_per_epoch=113526,
        nb_epoch=6,
        validation_data=vgen,
        nb_val_samples=20001
    )

数据集包含 113526 个样本点,但模型训练更新输出如下所示(例如):

  1020/113526 [..............................] - ETA: 27737s - loss: 0.0080
  1021/113526 [..............................] - ETA: 27723s - loss: 0.0080
  1022/113526 [..............................] - ETA: 27709s - loss: 0.0080
  1023/113526 [..............................] - ETA: 27696s - loss: 0.0080

这似乎是逐个样本训练(随机?)。 结果模型是无用的。我之前使用 .fit() 对一个小得多的数据集进行了训练,并将整个数据集加载到内存中,这产生了一个即使效果不佳也至少可以工作的模型。显然我的 fit_generator() 方法有问题。非常感谢您对此的帮助。

【问题讨论】:

  • samples_per_epoch 应该等于total_samples / batch_size,如keras documentation 中所建议的那样。 samples_per_epoch 指定在一个 epoch 被认为完成之前调用生成器的次数,它不知道你在使用什么 batch_size
  • 谢谢@gionni。从 Keras 1.0.2 更新到最新版本。 fit-generator() 参数在这个版本中更有意义。

标签: keras generator conv-neural-network training-data


【解决方案1】:

这个:

for line in reader:
    inputs = []
    targets = []

... 正在为 csv 文件中的每一行重置批处理。您不是在使用全部数据进行训练,而是仅使用 128 个样本中的一个样本。

建议:

for line in reader:

    if batchCount == 0:
        inputs = []
        targets = []  
    ....
    ....

正如有人评论的那样,合适的生成器samples_per_epoch 应该等于total_samples / batchsz

尽管如此,我认为无论如何你的损失应该会减少。如果不是,则代码中可能还有另一个问题,可能是您加载数据的方式,或者模型的初始化或结构。

尝试绘制图像并在生成器中打印数据:

for X,y in tgen: #careful, this is an infinite loop, make it stop

    print(X.shape[0]) # is this really the number of batches you expect?

    for image in X:
        ...some method to plot X so you can see it, or just print     

    print(y)

检查产生的值是否符合您的预期。

【讨论】:

  • "... 正在为 csv 文件中的每一行重置您的批处理。"哦!应该已经发现了那个。奇怪,因为我有一些测试代码可以打印出 yeilded 数组,它们是大小和顺序正确的批次。
  • 关于损失,最近我遇到了一个“冻结”损失的问题。我决定只训练一个样本很多个时期,突然间损失减少了。然后我逐渐介绍了其他示例,它开始正常训练。我猜这个模型太复杂了,或者我没有正确初始化我的权重,所以花了更长的时间来展示一些有趣的结果。
  • 谢谢丹尼尔。现在好像训练好了。不过 GPU 负载非常低,就好像 GPU 正在等待脚本一样。
猜你喜欢
  • 2020-03-06
  • 2018-12-06
  • 1970-01-01
  • 2017-07-07
  • 2020-03-20
  • 2017-09-18
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多