深度学习:数据增强时损失和准确度低

时间:2021-02-01 18:47:31

标签: python deep-learning augmentedimage

我是深度学习概念的新手。我创建了一个 CNN 模型,通过 MNIST 数据集以及 tensorflow 和 keras 来预测我的数字手写。

我不知道为什么我的模型无法预测 6 个数字图像。所以我决定对 mnist 数据集进行数据增强。我尝试为 mnist 实现增强,所以这是代码:

(X_train, y_train), (X_test, y_test) = mnist.load_data()# Reshaping to format which CNN expects (batch, height, width, channels)
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], X_test.shape[2], 1).astype('float32')

image_size = X_train.shape[1]
input_size = image_size * image_size

X_train/=255
X_test/=255

number_of_classes = 10
y_train = np_utils.to_categorical(y_train, number_of_classes)
y_test = np_utils.to_categorical(y_test, number_of_classes)

batch_size = 128
epochs = 2

# create model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(X_train.shape[1], X_train.shape[2], 1), activation = tf.nn.relu))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation = tf.nn.relu))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128, activation = tf.nn.relu))
model.add(keras.layers.Dense(50, activation = tf.nn.relu))
#model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(number_of_classes, activation=tf.nn.softmax))


# Compile model
model.compile(
    loss='categorical_crossentropy', 
    optimizer=Adam(), 
    metrics=['accuracy']
)


datagen = ImageDataGenerator(
        featurewise_center=True,
        featurewise_std_normalization=True,
        rotation_range=20,
        width_shift_range=0.2,
        height_shift_range=0.2,
        horizontal_flip=False)

datagen.fit(X_train.reshape(X_train.shape[0], 28, 28, 1))



for e in range(epochs):
    print('Epoch', e)
    batches = 0
    for x_batch, y_batch in datagen.flow(X_train,y_train,batch_size=batch_size):
          #x_batch = np.reshape(x_batch, [-1, image_size*image_size])
          model.fit(x_batch, y_batch)
          batches += 1
          if batches >= len(X_train) / 32:
                # we need to break the loop by hand because
                # the generator loops indefinitely
            break

# Score trained model.
scores = model.evaluate(X_test,
                        y_test,
                        batch_size=batch_size,
                        verbose=False)
print('Test loss:', scores[0])
print('Test accuracy: %0.1f%%' % (100 * scores[1]) )

在训练中损失和准确率是: loss: 0.0917 - accuracy: 0.9688 但是当我通过测试预测数据丢失和准确率很低时:

Test loss: 2.3218765258789062
Test accuracy: 11.2%

有人知道什么是问题,我该如何改进?

2 个答案:

答案 0 :(得分:1)

这称为过度拟合,您正在记住您的训练数据。您在可见数据方面做得很好,但您的网络无法预测未见数据。

一般来说,数据集拆分有3种

  • 培训
  • 验证
  • 测试

使用验证数据,您可以调整超参数,并使用测试拆分的看不见的数据进行测试。测试拆分不会增加。因为我们想要表示真实世界的数据,所以用户不会增加他们的数据来获得他们的预测等。数据增加是向你的神经网络展示更多种类数据的好方法。如果您使用得当,它可以显着提高您的测试准确性。您可以使用 library(dplyr) df <- data.frame(stringsAsFactors=FALSE, Subset = c("A","B","C","D","A","B","C","D","A","B","C","D"), ID = c(1,2,3,4,5,3,1,5,2,3,4,1), score = c(123,42,564,234,123,345,6678,87,543,121,123,55)) averages <- df %>% group_by(Subset) %>% summarise(mean.subs = mean(score)) %>% ungroup() %>% group_by(ID) %>% summarise(mean.id = mean(score) / mean.subs) 来查看它是否会影响您的测试准确性。

所以回到你的问题,你需要规范你的模型以防止过度拟合。这就是 dropout 层的实际作用,它使模型不那么复杂。此外,我看到您只训练了 2 个 epoch,这不足以使您的模型与数据拟合以获得良好的预测。您需要训练更长时间并规范模型。或者您可以使模型不那么复杂,这取决于您。

编辑:我刚刚意识到您设置了 horizontal_flip = True featurewise_center=True,,您将训练集的输入均值设置为 0。但是当您将测试集重新缩放 1/255 时,它的平均值为 0.5,您需要将相同的预处理 (非增强) 技术应用于测试集。这也会影响预测。

答案 1 :(得分:0)

您的扩充不反映测试集。如果你给神经网络一些数据,它会在很大程度上从中“学习”。您决定为其提供一些在测试集中找不到的“增强”数据。因此,您的 NN 很好地了解了您的假数据,并调整了其系数来做到这一点,但是,当您向其展示“真实”数据时,NN 的权重对“真实”数据的预测效果非常差。

尝试不同的技术。合成数据通常从来都不是一个好的选择。