【问题标题】:Any Advice on how to make this CNN training faster?关于如何使这个 CNN 训练更快的任何建议?
【发布时间】:2021-06-30 03:35:01
【问题描述】:

我一直在训练神经网络来识别手写纸和绘图纸之间的差异,我的图像都是 (3508, 2480) 大小,我正在使用 CNN 来完成这项任务,问题是训练需要很长时间,我有 30,000 个数据属于 2 个类别,分为验证和训练,所以我有:

  • 13650张手写段落图片用于训练
  • 13650 张图片用于训练
  • 1350 张图纸图片供验证
  • 1250 张图纸图片供验证

如果你想在这里看到我的架构,那就是我的

这是我的代码:

import tensorflow as tf
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

from google.colab import drive
drive.mount('/content/drive')
l0 = tf.keras.layers.Conv2D(32, (60,60), activation='relu', input_shape=(438, 310, 1), name='input')
l1 = tf.keras.layers.Dropout(.3)
l2 = tf.keras.layers.BatchNormalization()
l3 = tf.keras.layers.MaxPool2D(pool_size=(2,2),padding='same')

l12 = tf.keras.layers.Flatten()

l16 = tf.keras.layers.Dense(32, activation='relu')
l17 = tf.keras.layers.Dropout(.5)
l18 = tf.keras.layers.BatchNormalization()

l22 = tf.keras.layers.Dense(1, activation='sigmoid', name='output')
from keras.preprocessing.image import ImageDataGenerator
trdata = ImageDataGenerator(rescale=1/255)
traindata = trdata.flow_from_directory("/content/drive/MyDrive/Sae/TesisProgra/DataSets/ParagraphsVsDrawings/Paste/0_Final/Training",target_size=(438, 310), color_mode="grayscale", batch_size=250)
valdata = ImageDataGenerator(rescale=1/255)
validationdata = valdata.flow_from_directory("/content/drive/MyDrive/Sae/TesisProgra/DataSets/ParagraphsVsDrawings/Paste/0_Final/Validation",target_size=(438, 310), color_mode="grayscale", batch_size=250)
from keras.callbacks import ModelCheckpoint, EarlyStopping
checkpoint = ModelCheckpoint("ParagraphsVsDrawings.h5", monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=False, save_freq='epoch', mode='auto')
history = model.fit(traindata, validation_data=validationdata, validation_steps=10,epochs=20, verbose=True, callbacks=[checkpoint])

我正在使用 Google Colab PRO 进行培训,并激活了 TPU 和 Big RAM 选项

我以前训练过 CNN,但他们训练得非常快,我不知道是不是因为我的图像太大,也许我可以尝试用枕头调整它们的大小,但我现在真的迷路了,我一直等待 12 小时,它仍然在第一个 epoch

【问题讨论】:

  • 从基本概述中,我可以看出您的批量很大。考虑降低它。通常,我使用 15-30 左右的批量大小。图像形状也是一个值得关注的问题。如果可能,请减少它。另一件事是我注意到您正在使用 TPU。 AFAIK,TPU 需要在代码中以不同方式处理。对于这个微不足道的 CNN,您应该使用 GPU。
  • 感谢您的建议,我做了很多您推荐的事情,并将时间从大约 336 小时减少到 36 小时,但仍然需要处理很多,所以可能是因为我的数据集太大了?我终于得到了 37,937 个参数并改为 GPU,将批量大小更改为 32,它工作得更快,但不像我习惯的那样
  • 37k+ 参数对 ConvNets 来说很好。事实上,我使用具有大约 1000 万个参数的免费 colab,并且只需要几个小时就可以进行提前停止的训练。但是,最后一件事是,如果需要减少训练时间,你真的应该考虑添加一些 Conv 层以及最大池和 dropout。谢谢!
  • 非常感谢您的建议,我用各自的 BatchNormalization、Pooling 和 dropout 层制作了 4 层 Conv2D,现在我的准确度保持不变,但这是另一个问题,CNN 正在快速训练

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

您的内核大小(60 x 60)相当大。尝试 3 x 3 内核或 5 x 5 内核。图像大小似乎不是问题,因为您将大小从 (3508, 2480) 调整为 (438, 310)。

还要注意,您拥有的权重数量非常非常多。大约是2400万。这是因为您正在展平 (189, 125, 32) 形状阵列,然后您的下一层(密集)有 32 个单位,因此该层的权重为 189 * 125 * 32 * 32。这将需要非常非常长的时间来训练。

尝试添加一两个以上的卷积层 + 池化层,以便扁平化时的权重数量可控。

【讨论】:

    【解决方案2】:

    对于在这里遇到同样问题的任何人,这是我的 CNN 架构的最终代码,它的运行速度比我以前的要快得多,感谢用户 Afif Al Mamunntlarry

    ModelSummary()

    代码

    lc0 = tf.keras.layers.Conv2D(64, (5,5), activation='relu', input_shape=(438, 310, 1), name='input')
    lc1 = tf.keras.layers.Dropout(.3)
    lc2 = tf.keras.layers.BatchNormalization()
    lc3 = tf.keras.layers.MaxPool2D(pool_size=(2,2),padding='same')
    
    lc4 = tf.keras.layers.Conv2D(32, (3,3), activation='relu')
    lc5 = tf.keras.layers.Dropout(.3)
    lc6 = tf.keras.layers.BatchNormalization()
    lc7 = tf.keras.layers.MaxPool2D(pool_size=(2,2),padding='same')
    
    lc8 = tf.keras.layers.Conv2D(16, (3,3), activation='relu')
    lc9 = tf.keras.layers.Dropout(.3)
    lc10 = tf.keras.layers.BatchNormalization()
    lc11 = tf.keras.layers.MaxPool2D(pool_size=(4,80),padding='same')
    
    lc8 = tf.keras.layers.Conv2D(8, (3,3), activation='relu')
    lc9 = tf.keras.layers.Dropout(.3)
    lc10 = tf.keras.layers.BatchNormalization()
    lc11 = tf.keras.layers.MaxPool2D(pool_size=(4,80),padding='same')
    
    lf = tf.keras.layers.Flatten()
    
    ld1 = tf.keras.layers.Dense(32, activation='relu')
    ld2 = tf.keras.layers.Dropout(.5)
    ld3 = tf.keras.layers.BatchNormalization()
    
    lfinal = tf.keras.layers.Dense(1, activation='sigmoid', name='output')
    
    model = tf.keras.Sequential([lc0,lc1,lc2,lc3,lc8,lc9,lc10,lc11,lf,ld1,ld2,ld3,lfinal], name="ParagraphIdentification")
    model.compile(loss='binary_crossentropy', optimizer=tf.keras.optimizers.RMSprop(lr = 0.001), metrics=['accuracy'])
    model.summary()
    

    【讨论】:

    • 我还想评论一下,通常惯例是随着您的深入而增加过滤器的数量(例如 6 -> 12 -> 16 -> 32 而不是 64 -> 32 -> 16 -> 8),即使这样会增加参数的数量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多