【问题标题】:Model accuracy stuck at 0.2505. What is wrong with my code?模型精度停留在 0.2505。我的代码有什么问题?
【发布时间】:2019-07-14 10:36:51
【问题描述】:

我正在尝试使用带有 FER2013 数据集的面部表情来制作情绪分类器。它包含 35887 个样本,每个样本有 2304 个特征和一个用于情绪的整数标签 0-6。当我使用形状为 (2304,1) 的 Conv1D 时,它实现了约 86% 的训练准确度,但在任何看不见的测试图像上表现不佳。所以我想为每个样本将其重塑为 (48,48,1) 并在其上使用 Conv2D。但是现在它只是在第二个 epoch 之后的训练中停留在 0.2505 并且永远不会增加。发生了什么事?

import pandas as pd
import numpy as np
from PIL import Image
import matplotlib.image as mpimg
from skimage import transform
import random
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense

emotion = {0 : 'Angry', 1 : 'Disgust',2 : 'Fear',3 : 'Happy',
           4 : 'Sad',5 : 'Surprise',6 : 'Neutral'}
df=pd.read_csv('fer.csv')
faces=df.values[:,1]
faces=faces.tolist()
emos=df.values[:,0]

for i in range(len(faces)):
    faces[i]=[int(x) for x in faces[i].split()]
    emos[i]=int(emos[i])

faces=np.array(faces)
faces=transform.resize(faces, (35887,48,48))

faces=np.expand_dims(faces, axis=3)

model = Sequential()

model.add(Conv2D(48, (3,3), padding='same', input_shape=(48,48,1), activation='relu'))
model.add(Conv2D(48, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(96, (3,3), padding='same', activation='relu'))
model.add(Conv2D(96, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(192, (3,3), padding='same', activation='relu'))
model.add(Conv2D(192, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(384, (3,3), padding='same', activation='relu'))
model.add(Conv2D(384, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(384, activation='relu'))
model.add(Dropout(0.4))

model.add(Dense(192, activation='relu'))
model.add(Dropout(0.4))

model.add(Dense(96, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(7, activation='softmax'))
    
model.compile(loss='sparse_categorical_crossentropy',
            optimizer='adam',
            metrics=['accuracy'])


model.fit(faces,emos,epochs=100,batch_size=48)
model.save_weights('model.h5')

模型精度曲线

模型损失曲线

【问题讨论】:

  • 你能把你的损失和准确率训练曲线分开放在训练和测试中吗?这将非常有帮助。起初,您似乎有过度拟合,一个太大的网络。特征是否标准化?
  • @IgnacioPeletier 否,功能未标准化。然而,在对它们进行归一化后,具有 Conv1D 的模型(对于 2304,1 形状)现在也停留在 0.2515(之前达到 0.86)。一会儿我会贴出Conv2D模型的loss和accuracy训练曲线(对于48,48,1 shape)。
  • 我会等你的曲线,然后我们可以考虑你的问题!
  • @IgnacioPeletier 我已经编辑了我的帖子。请看一下曲线:)
  • 嗯!看到这个我很兴奋。看一下曲线,我们可以看到什么可能是过度拟合的,因为测试损失现在没有下降并且有些偏差......因为你的精度没有上升。既然您使用的是图像的特征,那么使用卷积层有什么理由吗?如果输入是特征,我建议您使用全连接层。要么这样做,要么使用图像作为输入并与 Conv2d 层保持一致。让我更新!

标签: python keras deep-learning conv-neural-network


【解决方案1】:

在每一层修复问题后标准化输出批次。

只需添加

model.add(BatchNormalization())

每一层之后。

编辑:

认为我应该在这里添加更多信息。 所以,这是我最终制作的最终模型。

model = Sequential()

model.add(Conv2D(32, (3, 3), input_shape=(200,200,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

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

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.25))

model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(512, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.3))

model.add(Dense(256, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.4))

model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))

model.add(Dense(len(classes), activation='softmax'))
            
model.compile(loss='sparse_categorical_crossentropy',
                    optimizer='nadam',
                    metrics=['accuracy'])

这些就是我用它得到的结果。

我也增加了节点并更改了优化器,但是批量标准化显着提高了准确性。使用更多节点和 nadam 优化器进一步帮助了一点。

【讨论】:

  • 谢谢,添加“model.add(BatchNormalization())”帮助了我基于 GRU 的模型,该模型卡在了随机选择精度值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多