【问题标题】:How should I improve Training and Validation Accuracy/Loss?我应该如何提高培训和验证的准确性/损失?
【发布时间】:2021-01-06 17:57:19
【问题描述】:

我正在训练古吉拉特语光学字符识别模型。输入图像是字符图像。我上过20节课。训练图像总数为 12000(每类 600),测试图像为 3200(每类 160)。

我应该如何提高我的准确性并减少损失?

下面是我的代码:

    classifier = Sequential()


# Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (32, 32, 3), activation = 'relu'))
classifier.add(BatchNormalization())

# Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(BatchNormalization())
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Dropout(0.2))

# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(BatchNormalization())
classifier.add(MaxPooling2D(pool_size = (2, 2)))




# Flattening
classifier.add(Flatten())

classifier.add(Dense(units = 1024, activation = 'relu'))

classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 20, activation = 'softmax'))

classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])

classifier.summary()

# Fitting the CNN to the images

from tensorflow.keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   
                                   
                                   horizontal_flip=False)

test_datagen = ImageDataGenerator(horizontal_flip = False)

training_set = train_datagen.flow_from_directory('C:/Users/shweta/Desktop/characters/train',
                                                 target_size = (32, 32),
                                                 batch_size = 32,
                                                 class_mode = 'categorical')

test_set = test_datagen.flow_from_directory('C:/Users/shweta/Desktop/characters/test',
                                            target_size = (32, 32),
                                            batch_size = 32,
                                            class_mode = 'categorical')


classifier.fit_generator(training_set,
                        
                         epochs = 22,
                         validation_data = test_set, shuffle=True)
classifier.save('alphanumeric.mod')

输出:

Epoch 19/22
375/375 [==============================] - 34s 89ms/step - loss: 0.1800 - accuracy: 0.9414 - val_loss: 0.1945 - val_accuracy: 0.9397
Epoch 20/22
375/375 [==============================] - 34s 91ms/step - loss: 0.1729 - accuracy: 0.9445 - val_loss: 0.6013 - val_accuracy: 0.8450
Epoch 21/22
375/375 [==============================] - 34s 91ms/step - loss: 0.1798 - accuracy: 0.9420 - val_loss: 0.1817 - val_accuracy: 0.9409
Epoch 22/22
375/375 [==============================] - 35s 93ms/step - loss: 0.1802 - accuracy: 0.9398 - val_loss: 0.1757 - val_accuracy: 0.9425

【问题讨论】:

  • 最后的密集层不应该有 10 个单位而不是 20 个,因为你只有 10 个类吗?
  • 对不起,实际上我有 20 节课要训练。我在问题中的拼写错误
  • 您期待什么结果?对我来说,准确性似乎是合理的。
  • 我认为你应该尝试添加更多的 Conv2D 层并减少一个或多个 Dense 层,通过使用旋转、移位、翻转、缩放来增加数据......同时使用 BatchNorm 层来增加模型的稳定性训练时间。
  • 我正在为古吉拉特语字符的 OCR 训练我的模型。

标签: tensorflow deep-learning ocr conv-neural-network


【解决方案1】:

不了解数据集的性质,很难提供太多帮助。

以下是我的一些观察。深度卷积神经网络通常只有一个密集的 softmax 层,4 层应该不会显着提高准确率。如果数据具有特征,请考虑使用更多的卷积层和单个密集层。最后,在第一个卷积层之前和每一层之后添加批量归一化。也可以应用贝叶斯优化等其他技术,但它们的工作量要大得多,可能只是很小的改进。

【讨论】:

  • 我已经添加了批量标准化并获得了准确性。看一看。我编辑了这个问题。我需要更改批量标准化的哪些参数以提高验证准确性?
【解决方案2】:

您在代码中做错了一些事情。查看非常接近的训练和验证准确性,这意味着您的模型没有受到高方差的影响。它可能会或可能不会受到高偏差的影响。这取决于贝叶斯错误是什么(我不知道这个特定任务,但它可能低于假设您有合理数据的情况下所达到的错误)。

假设您的模型确实存在高偏差,您可以尝试增加模型的复杂性,直到它开始过度拟合数据。

例如,您可以尝试将 Conv2D 层/块替换为

classifier.add(Conv2D(32, (3, 3), padding="same"))
classifier.add(Conv2D(32, (3, 3), padding="valid"))
classifier.add(BatchNormalization())
classifier.add(ReLU())                             #keras.layers.ReLU
classifier.add(MaxPool2D((2, 2)))

classifier.add(Conv2D(64, (3, 3), padding="same"))
classifier.add(Conv2D(64, (3, 3), padding="valid"))
classifier.add(BatchNormalization())
classifier.add(ReLU())                             #keras.layers.ReLU
classifier.add(MaxPool2D((2, 2)))

classifier.add(Conv2D(128, (3, 3), padding="same"))
classifier.add(Conv2D(128, (3, 3), padding="valid"))
classifier.add(BatchNormalization())
classifier.add(ReLU())                             #keras.layers.ReLU
classifier.add(MaxPool2D((2, 2)))

这里有几点需要注意:

  1. 随着您深入网络,图像的大小将由于valid 填充、步幅和/或池化而缩小。同时,您应该增加过滤器的数量,例如 (32 -> 64 -> 128 -> ...)。这不是一个硬性规则,但它往往比保持过滤器数量相同更好 - 您在所有卷积层中使用 32 个过滤器。

  2. 批量归一化应该应用于层的线性输出(预激活),而不是在您现在正在实施的激活后。所以你应该有z -> batch-norm -> a 其中z 是层的线性输出(在你的情况下Conv2D)和a 是层的激活所以你需要将其拆分为多个“层”(在 Keras 术语中)。

classifier.add(Conv2D(32, (3, 3), padding="valid")) # no activation here
classifier.add(BatchNormalization())
classifier.add(ReLU())
  1. 您可能不需要在顶部设置这么大的Dense 层。它会增加训练时间,但没有太多好处(一两个较小的 Dense 层应该没问题)。
  2. 您还应该尝试更长时间的训练,同时逐渐降低学习率,这通常可以减少损失。您可以重新编译您的模型,将优化器设置为 keras.optimizers.Adam(learning_rate=...) 而不仅仅是字符串 "adam" 来指定学习率(可能还有其他优化器超参数,但默认值通常可以正常工作)。请注意,设置正确的学习率是训练神经网络时最重要的因素之一,并且可能对其性能产生巨大影响 - 不要仅仅依赖默认值。

【讨论】:

  • 嘿,谢谢!这段代码运行良好,我达到了 96% 的准确率,但有一些波动。
  • 我可以进一步应用小批量的概念来进一步提高验证准确性吗?!
  • 小批量大小会影响您训练模型的速度,而不是准确性(至少不会直接影响)。您可以使用批量大小,但我不希望它以任何显着方式提高模型的准确性(如果您已经训练了足够长的时间)。
  • 我必须扩展我的代码来训练大约 6​​00 个字符,即 600 个类。
  • 我也可以尝试一些网络,比如 AlexNet 或 DenseNet。你有什么建议?
猜你喜欢
  • 2019-09-06
  • 2020-08-08
  • 1970-01-01
  • 2022-10-05
  • 2020-04-27
  • 1970-01-01
  • 2021-03-09
  • 2020-12-09
  • 1970-01-01
相关资源
最近更新 更多