为什么2几乎相同的Keras CNN返回2个完全不同的结果

时间:2017-09-29 14:49:58

标签: python nlp deep-learning keras keras-2

我正在处理句子级二进制分类任务。我的数据包含3个令牌子阵列:左上下文,核心和右上下文。

我使用 Keras 来设计卷积神经网络的几种替代方案,并验证哪一种最适合我的问题。

我是Python和Keras的新手,我决定从更简单的解决方案开始,以测试哪些更改可以改善我的指标(准确性,精确度,召回率,f1和auc-roc)。第一个简化是关于输入数据:我决定忽略上下文来创建Keras的顺序模型:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 500)               0         
_________________________________________________________________
masking_1 (Masking)          (None, 500)               0         
_________________________________________________________________
embedding_1 (Embedding)      (None, 500, 100)          64025600  
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 497, 128)          51328     
_________________________________________________________________
average_pooling1d_1 (Average (None, 62, 128)           0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 62, 128)           0         
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 61, 256)           65792     
_________________________________________________________________
dropout_2 (Dropout)          (None, 61, 256)           0         
_________________________________________________________________
conv1d_3 (Conv1D)            (None, 54, 32)            65568     
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 32)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 16)                528       
_________________________________________________________________
dropout_3 (Dropout)          (None, 16)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 34        
=================================================================

如您所见,我使用固定大小的输入,因此我应用了填充预处理。我还使用了一个带有Word2Vec模型的嵌入层。

此模型返回以下结果:

P       0.875457875
R       0.878676471
F1      0.87706422
AUC-ROC 0.906102654

我希望实现如何通过Lambda图层在CNN中选择输入数据的子数组。我使用以下Lambda图层定义:

Lambda(lambda x: x[:, 1], output_shape=(500,))(input)

这是我新CNN的摘要(你可以看到它与之前几乎相同):

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 3, 500)            0         
_________________________________________________________________
lambda_1 (Lambda)            (None, 500)               0         
_________________________________________________________________
masking_1 (Masking)          (None, 500)               0         
_________________________________________________________________
embedding_1 (Embedding)      (None, 500, 100)          64025600  
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 497, 128)          51328     
_________________________________________________________________
average_pooling1d_1 (Average (None, 62, 128)           0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 62, 128)           0         
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 61, 256)           65792     
_________________________________________________________________
dropout_2 (Dropout)          (None, 61, 256)           0         
_________________________________________________________________
conv1d_3 (Conv1D)            (None, 54, 32)            65568     
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 32)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 16)                528       
_________________________________________________________________
dropout_3 (Dropout)          (None, 16)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 34        
=================================================================

但结果令人厌恶,因为准确度停留在 60%,显然,精确度,召回率和f1对于第一个模型结果来说太低(<0.10)。

我不知道发生了什么,我也不知道这些网络是否与我的想法有所不同。

关于这个问题的任何线索?

1 个答案:

答案 0 :(得分:0)

两个初步问题(我会发表评论,但还没有足够的代表):

(1)使用CNN的动机是什么?这些擅长选择二维输入值数组中的局部特征 - 例如,如果你想象一个黑白图片作为整数的二维数组,其中整数代表灰度,他们可能会挑出一堆表示边缘,角落或对角白线等的像素。除非您有理由期望您的数据(如图片)具有此类本地群集功能,并且对于在输入阵列中水平和垂直方向彼此更近的点更为相关,您可能会更好地使用密集层没有关于哪些输入特征与哪些输入特征相关的假设。首先说两层,看看它在哪里。

(2)假设您对建筑的形状充满信心,您是否尝试降低学习率?这是第一个在任何NN中尝试的东西,它没有很好地收敛。

(3)根据任务的不同,你可能会更好地使用字典和单热编码来表达你的单词,特别是如果它的分类和上下文相对简单并不是太大的话题。 Word2Vec意味着您将单词编码为数字,这对渐变下降有影响。很难说不知道你想要实现什么,但是如果你没有一些合理的想法,为什么使用word2vec是一个好主意,它可能不是......

This link很好地解释了CNN与密集层之间的区别,因此可以帮助您判断。