【问题标题】:Tensorflow returns 10% validation accuracy for VGG model (irrespective of number of epochs)?Tensorflow 为 VGG 模型返回 10% 的验证准确率(与 epoch 数无关)?
【发布时间】:2018-07-14 06:06:59
【问题描述】:

我正在尝试使用 tensorflow 中的 keras 包在 CIFAR-10 上训练神经网络。考虑的神经网络是VGG-16,我直接借鉴了官方的keras模型。 定义是:

def cnn_model(nb_classes=10):
# VGG-16 official keras model
img_input= Input(shape=(32,32,3))
vgg_layer= Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
vgg_layer= Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(vgg_layer)
vgg_layer= MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(vgg_layer)

# Block 2
vgg_layer= Conv2D(64, (3, 3), activation='relu', padding='same', name='block2_conv1')(vgg_layer)
vgg_layer= Conv2D(64, (3, 3), activation='relu', padding='same', name='block2_conv2')(vgg_layer)
vgg_layer= MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(vgg_layer)

# Block 3
vgg_layer= Conv2D(128, (3, 3), activation='relu', padding='same', name='block3_conv1')(vgg_layer)
vgg_layer= Conv2D(128, (3, 3), activation='relu', padding='same', name='block3_conv2')(vgg_layer)
vgg_layer= Conv2D(128, (3, 3), activation='relu', padding='same', name='block3_conv3')(vgg_layer)
vgg_layer= MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(vgg_layer)

# Block 4
vgg_layer= Conv2D(256, (3, 3), activation='relu', padding='same', name='block4_conv1')(vgg_layer)
vgg_layer= Conv2D(256, (3, 3), activation='relu', padding='same', name='block4_conv2')(vgg_layer)
vgg_layer= Conv2D(256, (3, 3), activation='relu', padding='same', name='block4_conv3')(vgg_layer)
vgg_layer= MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(vgg_layer)

# Classification block
vgg_layer= Flatten(name='flatten')(vgg_layer)
vgg_layer= Dense(1024, activation='relu', name='fc1')(vgg_layer)
vgg_layer= Dense(1024, activation='relu', name='fc2')(vgg_layer)
vgg_layer= Dense(nb_classes, activation='softmax', name='predictions')(vgg_layer)

return Model(inputs=img_input, outputs=vgg_layer)

但是在训练期间,我总是将训练和验证准确度都设为 0.1,即 10%。

validation accuracy for adv. training of model for epoch 1=  0.1
validation accuracy for adv. training of model for epoch 2=  0.1
validation accuracy for adv. training of model for epoch 3=  0.1
validation accuracy for adv. training of model for epoch 4=  0.1
validation accuracy for adv. training of model for epoch 5=  0.1

作为调试的一步,每当我用任何其他模型(例如,任何简单的 CNN 模型)替换它时,它都能很好地工作。这表明脚本的其余部分运行良好。

例如,以下 CNN 模型运行良好,在 30 个 epoch 后达到 75% 的准确率。

def cnn_model(nb_classes=10, num_hidden=1024, weight_decay= 0.0001, cap_factor=4):
model=Sequential()
input_shape = (32,32,3)
model.add(Conv2D(32*cap_factor, kernel_size=(3,3), strides=(1,1), kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer="he_normal", activation='relu', padding='same', input_shape=input_shape))
model.add(Conv2D(32*cap_factor, kernel_size=(3,3), strides=(1,1), kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer="he_normal", activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.25))

model.add(Conv2D(64*cap_factor, kernel_size=(3,3), strides=(1,1), kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer="he_normal", activation="relu", padding="same"))
model.add(Conv2D(64*cap_factor, kernel_size=(3,3), strides=(1,1), kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer="he_normal", activation="relu", padding="same"))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(num_hidden, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='softmax'))
return model

在我看来,这两个模型的定义都是正确的。然而,一个工作完美,而另一个根本不学习。我还尝试将 VGG 模型编写为顺序结构,即类似于第二个结构,但它仍然给了我 10% 的准确率。

即使模型不更新任何权重,“he_normal”初始化器仍然很容易获得比纯机会更好的准确度。似乎 tensorflow 以某种方式计算模型的输出 logits,从而导致准确性纯属偶然。

如果有人能指出我的错误,我将非常有帮助。

【问题讨论】:

  • 在最后一个卷积结束时,你会下降到 1x1,这肯定不是 vgg 的预期用途。它专为更大的 imagenet 输入而设计。
  • nb_classes 在 vgg 模型中的用处是什么?它不是函数的参数。
  • @CodesInChaos 我同意,但即使我删除了最后一两个池化层,它也显示出相同的 10% 准确度。

标签: tensorflow neural-network keras conv-neural-network vgg-net


【解决方案1】:

您的 10% 与 nr of classes = 10 高度对应。这让我认为,无论训练如何,所有类别的答案始终为“1”,这在 10 个课程上不断为您提供 10% 的准确率。

  1. 检查未训练模型的输出,如果始终为 1
  2. 如果是,请检查模型的初始权重,可能是初始化错误,梯度为零且无法收敛

【讨论】:

    猜你喜欢
    • 2018-08-07
    • 2020-10-17
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    相关资源
    最近更新 更多