我想使用Keras训练序列标记模型以进行实体识别。
目前,我的模型看起来像这样:
model = Sequential()
model.add(Embedding(max_features, 32, input_length=maxlen,mask_zero=True))
model.add(Bidirectional(LSTM(64,return_sequences=True)))
model.add(Bidirectional(LSTM(64,return_sequences=True)))
model.add(TimeDistributedDense(512, activation='softmax'))
model.add(TimeDistributedDense(256, activation='softmax'))
model.add(TimeDistributedDense(2, activation='softmax'))
model.compile('rmsprop', 'categorical_crossentropy', metrics=['accuracy'])
model.summary()
我的输出是一个热编码。鉴于序列大小不固定,我填写了输入和输出,如下所示:
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
y_train = sequence.pad_sequences(y_train, maxlen=maxlen)
因此,我的输出如下所示:
[[0,0],...,[0,0],[1,0],... [0,1] ......,[1,0]]
我的输入如下:
[0,0,0,0,0,0,... 37188,21618,36414,420]
我正在使用categorical_crossentropy
和rmsprop
优化器。
我遇到的问题是我的课程非常不平衡。 98%的令牌不是实体,因此我的模型将所有内容归类为非实体。
我尝试使用class_weight
来平衡类,但我不知道如何为每个类指定权重,因为我使用的是单热编码。我尝试按如下方式提供课程重量字典而没有任何运气:
model.compile('rmsprop', 'categorical_crossentropy', metrics=['accuracy'],class_weights={1 : 0.999999999999999999, 2:0.000000000000000001, 0: 0.000000000000000001})
另一位用户似乎在Keras: class weights (class_weight) for one-hot encoding中遇到了类似的问题,但解决方案并不清楚。也不像那篇文章,在我的情况下,我的输出是三维的([N_Samples, N_tokes, N_Classes]
)因为我需要每个标记一个向量。
使用class_weight
似乎不适合采用立体输出:https://github.com/fchollet/keras/issues/3653
但是,我没有找到使用sample_weights
的文档。
提前感谢您的帮助。