【问题标题】:Keras with Theano: Loss decrease but accuracy not changingKeras 与 Theano:损失减少但准确性不变
【发布时间】:2017-08-03 17:00:25
【问题描述】:

这是我的代码。我尝试构建一个 VGG 11 层网络,混合了 ReLu 和 ELu 激活以及内核和活动的许多正则化。结果确实令人困惑:代码位于第 10 个 epoch。我在 train 和 val 上的损失从 2000 年减少到 1.5,但我在 train 和 val 上的 acc 保持在 50% 不变。谁能给我解释一下?

# VGG 11
from keras.regularizers import l2
from keras.layers.advanced_activations import ELU
from keras.optimizers import Adam
model = Sequential()

model.add(Conv2D(64, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          input_shape=(1, 96, 96), activation='relu'))
model.add(Conv2D(64, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001),activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(Conv2D(128, (3, 3), kernel_initializer='he_normal',     
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(256, (3, 3), kernel_initializer='he_normal',     
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(Conv2D(256, (3, 3), kernel_initializer='he_normal',     
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(512, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(Conv2D(512, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001), 
          activation='relu'))
model.add(Conv2D(512, (3, 3), kernel_initializer='he_normal', 
          kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.0001),     
          activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# convert convolutional filters to flat so they can be feed to fully connected layers
model.add(Flatten())

model.add(Dense(2048, kernel_initializer='he_normal',
               kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.01)))
model.add(ELU(alpha=1.0))
model.add(Dropout(0.5))

model.add(Dense(1024, kernel_initializer='he_normal',
               kernel_regularizer=l2(0.0001), activity_regularizer=l2(0.01)))
model.add(ELU(alpha=1.0))
model.add(Dropout(0.5))

model.add(Dense(2))
model.add(Activation('softmax'))

adammo = Adam(lr=0.0008, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='categorical_crossentropy', optimizer=adammo, metrics=['accuracy'])
hist = model.fit(X_train, y_train, batch_size=48, epochs=20, verbose=1, validation_data=(X_val, y_val))

【问题讨论】:

  • 你使用了太多的正则化
  • 谢谢 Nain。你能解释一下 acc 不增加的理论原因吗?我知道过多的正则化肯定会最大限度地减少损失。
  • @Estellad 添加评论为什么你对我给出的答案投了反对票。仅仅因为你对这个网络、你的初始化、你的 ELU、你任意选择的激活函数有理论上的偏好并不意味着它是正确的。很多这种情况并不常见。这就是为什么我建议采用完全不同的结构。
  • @Estellad 此外,准确性不增加的一个理论原因是因为强烈的正则化要求内核(权重)太小而无法完全适合您的网络。如果输入特征的比例不同(图像就是这种情况),这种情况尤其会发生。
  • 我没有对您的评论投反对票。应该来自其他人。

标签: deep-learning keras loss acc


【解决方案1】:

这不是缺陷,其实完全有可能!

分类cross entropy loss 不要求准确率随着损失的减少而上升。这不是 keras 或 theano 中的错误,而是网络或数据问题。

这种网络结构对于您可能尝试做的事情来说可能过于复杂。您应该删除一些正则化,仅使用 ReLu,使用更少的层,使用标准的 adam 优化器,更大的批次等。首先尝试使用 keras 的default models 之一,例如 VGG16,

如果您想查看他们的实现,可以针对不同的 VGG11 结构对其进行编辑。在这里:

def VGG_16(weights_path=None):
    model = Sequential()
    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(Flatten())
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1000, activation='softmax'))

    if weights_path:
        model.load_weights(weights_path)

    return model

你可以看到它要简单得多。它只使用了依赖(最近很流行)没有正则化,不同的卷积结构等。根据您的需要修改它!

【讨论】:

  • 感谢您的建议,Nucl3ic!我尝试了标准的 VGG16,但过滤器更少:64-128-256-512 -> 16-32-64-128。性能没有提高,与 LeNet 5 相同。所以我想我应该尝试建立自己的网络,理论上是最好的。然后我将简化我的模型。
  • 你是什么图片?
  • 我的图片都调整为96*96,单核灰度图。
  • 啊。这比大多数普通应用程序更复杂。根据您的数据集大小,我可以提供更复杂的网络,例如 ResNet 或 GoogLeNet。
  • 是的,感谢您的回复 modeitt!我现在正在尝试 ResNet。
猜你喜欢
  • 1970-01-01
  • 2019-06-03
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 2017-09-15
  • 2020-04-20
  • 1970-01-01
相关资源
最近更新 更多