【问题标题】:Training and Testing accuracy not increasing for a CNN followed by a RNN for signature verificationCNN 后跟 RNN 进行签名验证的训练和测试精度没有增加
【发布时间】:2019-09-21 18:25:34
【问题描述】:

我目前正在处理在线签名验证。数据集具有 (x, 7) 的可变形状,其中 x 是一个人用来签署其签名的点数。我有以下型号:

    model = Sequential()
    #CNN
    model.add(Conv1D(filters=64, kernel_size=3, activation='sigmoid', input_shape=(None, 7)))
    model.add(MaxPooling1D(pool_size=3))
    model.add(Conv1D(filters=64, kernel_size=2, activation='sigmoid'))

    #RNN
    model.add(Masking(mask_value=0.0))
    model.add(LSTM(8))
    model.add(Dense(2, activation='softmax'))

    opt = Adam(lr=0.0001)
    model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
    model.summary()

    print(model.fit(x_train, y_train, epochs=100, verbose=2, batch_size=50))

    score, accuracy = model.evaluate(x_test,y_test, verbose=2)
    print(score, accuracy)

我知道这可能不是最好的模型,但这是我第一次构建神经网络。我必须使用 CNN 和 RNN,因为这是我的荣誉项目所必需的。目前,我达到了 0.5142 作为最高训练准确率和 0.54 测试准确率。我尝试过增加 epoch 的数量、更改激活函数、添加更多层、移动层、更改学习率和更改优化器。

请分享一些关于更改我的模型或数据集的建议。任何帮助深表感谢。

【问题讨论】:

    标签: python keras conv-neural-network recurrent-neural-network


    【解决方案1】:

    对于 CNN-RNN,一些有希望的尝试:

    • Conv1D 层activation='relu'kernel_initializer='he_normal'
    • LSTM 层activation='tanh'recurrent_dropout=.1, .2, .3
    • 优化器Nadamlr=2e-4(Nadam 的性能可能明显优于所有其他 RNN 优化器)
    • batch_size:降低它。除非你总共有200+批次,否则设置batch_size=32;较小的批大小可以更好地利用优化器的随机机制,并且可以提高泛化能力
    • 辍学:紧随第二个Conv1D 之后,使用率.1, .2 - 或者,在第一个Conv1D 之后,使用率.25, .3,但如果您使用SqueezeExcite(见下文),否则 MaxPooling 将无法正常工作
    • SqueezeExcite:显示可在各种任务中提高所有 CNN 性能;您可以在下面使用 Keras 实现
    • BatchNormalization:虽然您的模型不大,但它仍然很深,并且可能会在第二个之后立即受益于一个 BN 层 Conv1D
    • L2 权重衰减:在 first Conv1D,防止它记住输入;试试1e-5, 1e-4,例如kernel_regularizer=l2(1e-4) # from keras.regularizers import l2
    • 预处理:确保所有数据均已标准化(或时间序列标准化),并且每个 epoch 都对批次进行打乱
    def SqueezeExcite(_input):
        filters = _input._keras_shape[-1]
    
        se = GlobalAveragePooling1D()(_input)
        se = Reshape((1, filters))(se)
        se = Dense(filters//16,activation='relu',   
                   kernel_initializer='he_normal', use_bias=False)(se)
        se = Dense(filters,    activation='sigmoid',
                   kernel_initializer='he_normal', use_bias=False)(se)
    
        return multiply([_input, se])
    
    # Example usage
    x = Conv1D(filters=64, kernel_size=4, activation='relu', kernel_initializer='he_normal')(x)
    x = SqueezeExcite(x) # place after EACH Conv1D
    

    【讨论】:

    • 感谢您的帮助。我已经实现了上述所有内容(除了 SqueezeExcite,因为我在理解该做什么时遇到了问题)。但我仍然有相同的结果。
    • @AbigailLeahSingh 您的完整训练数据集大小和完整验证数据集大小是多少?
    • 我正在使用 SVC 数据集。这不是一个非常大的数据集;只有 1200 个签名,因此我只将其拆分为训练集和测试集。出于结果的目的,我将它们分成 60-40、70-30 和 75-25。
    • @AbigailLeahSingh 1200 个签名,所以每个“签名”都有(1,7) 的形状,对吗?如果是这样,你的数据集对于深度学习来说太小了——你最好使用支持向量机等“浅层”方法(或获取更大的数据集)。 -- 如果您坚持,请显着减小模型大小,这样您的参数就不会超过约 10,000 个。另外,我推荐Model API 而不是 Sequential,因为它更灵活、更直观——上面的SqueezeExcite 就是为此编写的。
    • 每个签名的形状为 (n, 7),因为每个人为每个签名取 n 分。这就是我使用变量输入(无,7)的原因。我确实有另一个可以使用的数据集:SigComp2009,每个签名的形状都为 (n, 5)。这有一个包含 1906 个签名的训练集和一个包含 1552 个签名的测试集。如果我要使用这个数据集,它会更有效吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多