0

我正在解决句子级二进制分类任务。我的数据由 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)。

我不知道发生了什么,我不知道这些网络是否比我想象的更加不同。

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

4

1 回答 1

0

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

(1) 使用 CNN 的动机是什么?它们擅长在输入值的二维数组中挑选局部特征 - 例如,如果您将黑白图片想象为整数表示灰度的二维数组,它们可能会挑选出表示边缘、角落或对角白线等事物的像素。除非您有理由期望您的数据像图片一样具有这种局部聚集的特征,并且对于输入数组中水平和垂直彼此更接近的点更相关,您可能会更好地使用密集层没有关于哪些输入特征与哪些其他特征相关的假设。从说 2 层开始,看看它会带给你什么。

(2) 假设你对架构的形状有信心,你是否尝试过降低学习率?这是在任何不能很好收敛的 NN 中尝试的第一件事。

(3) 根据任务的不同,您最好使用字典和 one-hot 编码来对您的单词进行编码,尤其是在分类相对简单且上下文没什么大不了的情况下。Word2Vec 意味着您将单词编码为数字,这对梯度下降有影响。很难说不知道你想要达到什么目标,但如果你不知道为什么使用 word2vec 是一个好主意,它可能不是......

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

于 2017-09-29T15:48:33.717 回答