为什么2个几乎相等的Keras CNN返回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)使用CNN的动机是什么?这些善于在2D输入值阵列中挑选本地功能 - 例如,如果您想象黑白图片是整数代表灰度的二维整数阵列,他们可能会挑选代表边缘,角落或对角线白线之类的像素。除非您有理由期望您的数据像图片一样具有这样的本地群集功能,并且对于在输入阵列中水平和垂直方面都更加相关的要点更相关,您可能会与密集的图层更好地相关对于哪些输入功能与其他人相关的假设没有假设。从说2层开始,然后看看那是您的何处。

(2)假设您对建筑的形状充满信心,您是否尝试降低学习率?这是在任何不良融合的NN中尝试的第一件事。

(3)根据任务,您可能会使用字典和单件单词编码,尤其是相对简单的分类,并且上下文并不是太大的。Word2Vec表示您将单词编码为数字,这对梯度下降具有影响。不知道您要实现的目标很难说,但是如果您没有一些合理的想法,为什么使用Word2Vec是个好主意,那可能不是...

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

最新更新