CNN 后跟用于签名验证的 RNN 的训练和测试准确性不会增加
Training and Testing accuracy not increasing for a CNN followed by a RNN for signature verification
我目前正在进行在线签名验证。数据集具有 (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 的数量、改变激活函数、添加更多层、移动层、改变学习率和改变优化器。
请分享一些关于更改我的模型或数据集的建议。任何帮助深表感谢。
对于 CNN-RNN,一些有前途的尝试:
- Conv1D 层:
activation='relu'
,kernel_initializer='he_normal'
- LSTM层:
activation='tanh'
,以及recurrent_dropout=.1, .2, .3
- 优化器:
Nadam
,lr=2e-4
(Nadam 可能明显优于所有其他 RNN 优化器)
- batch_size:降低它。除非你总共有200+个批次,否则设置
batch_size=32
;较低的批量大小更好地利用了优化器的随机机制,并且可以提高泛化能力
- Dropout:在第二个
Conv1D
之后,比率为 .1, .2
- 或者,在第一个 Conv1D
之后,比率为 .25, .3
,但是 仅 如果你使用 SqueezeExcite(见下文),否则 MaxPooling
也不会工作
- SqueezeExcite:显示可增强 CNN 在各种任务中的性能;您可以在下面使用 Keras 实现
- BatchNormalization:虽然你的模型不大,但它仍然很深,可能会在第二个之后受益于一个 BN 层
Conv1D
- L2 weight decay:在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
我目前正在进行在线签名验证。数据集具有 (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 的数量、改变激活函数、添加更多层、移动层、改变学习率和改变优化器。
请分享一些关于更改我的模型或数据集的建议。任何帮助深表感谢。
对于 CNN-RNN,一些有前途的尝试:
- Conv1D 层:
activation='relu'
,kernel_initializer='he_normal'
- LSTM层:
activation='tanh'
,以及recurrent_dropout=.1, .2, .3
- 优化器:
Nadam
,lr=2e-4
(Nadam 可能明显优于所有其他 RNN 优化器) - batch_size:降低它。除非你总共有200+个批次,否则设置
batch_size=32
;较低的批量大小更好地利用了优化器的随机机制,并且可以提高泛化能力 - Dropout:在第二个
Conv1D
之后,比率为.1, .2
- 或者,在第一个Conv1D
之后,比率为.25, .3
,但是 仅 如果你使用 SqueezeExcite(见下文),否则MaxPooling
也不会工作 - SqueezeExcite:显示可增强 CNN 在各种任务中的性能;您可以在下面使用 Keras 实现
- BatchNormalization:虽然你的模型不大,但它仍然很深,可能会在第二个之后受益于一个 BN 层
Conv1D
- L2 weight decay:在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