Я хочу расширить выход сети до двух выходов в этом коде
def tag_dataset(self, dataset, model):
"""Tag data with numerical values"""
correctLabels = []
predLabels = []
for i, data in enumerate(dataset):
tokens, casing, char, labels = data
tokens = np.asarray([tokens])
casing = np.asarray([casing])
char = np.asarray([char])
pred = model.predict([tokens, casing, char], verbose=False)[0]
pred = pred.argmax(axis=-1)
correctLabels.append(labels)
predLabels.append(pred)
return predLabels, correctLabels
def buildModel(self):
"""Model layers"""
# character input
character_input = Input(shape=(None, 52,), name="Character_input")
embed_char_out = TimeDistributed(
Embedding(len(self.char2Idx), 30, embeddings_initializer=RandomUniform(minval=-0.5, maxval=0.5)), name="Character_embedding")(
character_input)
dropout = Dropout(self.dropout)(embed_char_out)
# CNN
conv1d_out = TimeDistributed(Conv1D(kernel_size=self.conv_size, filters=30, padding='same', activation='tanh', strides=1), name="Convolution")(dropout)
maxpool_out = TimeDistributed(MaxPooling1D(52), name="Maxpool")(conv1d_out)
char = TimeDistributed(Flatten(), name="Flatten")(maxpool_out)
char = Dropout(self.dropout)(char)
# word-level input
words_input = Input(shape=(None,), dtype='int32', name='words_input')
words = Embedding(input_dim=self.wordEmbeddings.shape[0], output_dim=self.wordEmbeddings.shape[1], weights=[self.wordEmbeddings],
trainable=False)(words_input)
# case-info input
casing_input = Input(shape=(None,), dtype='int32', name='casing_input')
casing = Embedding(output_dim=self.caseEmbeddings.shape[1], input_dim=self.caseEmbeddings.shape[0], weights=[self.caseEmbeddings],
trainable=False)(casing_input)
# concat & BLSTM
output = concatenate([words, casing, char])
output = Bidirectional(LSTM(self.lstm_state_size,
return_sequences=True,
dropout=self.dropout, # on input to each LSTM block
recurrent_dropout=self.dropout_recurrent # on recurrent input signal
), name="BLSTM")(output)
output1 = TimeDistributed(Dense(len(self.label2Idx), activation='softmax'),name="Softmax_layer1")(output)
output2 = TimeDistributed(Dense(len(self.label2Idx), activation='softmax'),name="Softmax_layer2")(output) #This line is added
# set up model
self.model = Model(inputs=[words_input, casing_input, character_input], outputs= [output1, output2])
self.model.compile(loss='sparse_categorical_crossentropy', loss_weights=[0.5, 0.5], optimizer=self.optimizer)
self.init_weights = self.model.get_weights()
plot_model(self.model, to_file='model.png')
print("Model built. Saved model.png\n")
def train(self):
"""Default training"""
self.f1_test_history = []
self.f1_dev_history = []
for epoch in range(self.epochs):
print("Epoch {}/{}".format(epoch, self.epochs))
for i,batch in enumerate(iterate_minibatches(self.train_batch,self.train_batch_len)):
labels, tokens, casing, char = batch
self.model.train_on_batch([tokens, casing, char], [labels, labels] )
# compute F1 scores
predLabels, correctLabels = self.tag_dataset(self.test_batch, self.model)
pre_test, rec_test, f1_test = compute_f1(predLabels, correctLabels, self.idx2Label)
Исходный код в https://github.com/mxhofer/Named-Entity-Recognition-BidirectionalLSTM-CNN-CoNLL.git.
Достаточно просто добавить этот плотный слой для получения двух выходов? Я добавил этот плотный слой, но он выдает ошибку для `compute_f1 ', которая определяется как
def compute_f1(predictions, correct, idx2Label):
label_pred = []
for sentence in predictions:
label_pred.append([idx2Label[element] for element in sentence])
label_correct = []
for sentence in correct:
label_correct.append([idx2Label[element] for element in sentence])
# print("predictions ", len(label_pred))
# print("correct labels ", len(label_correct))
prec = compute_precision(label_pred, label_correct)
rec = compute_precision(label_correct, label_pred)
f1 = 0
if (rec + prec) > 0:
f1 = 2.0 * prec * rec / (prec + rec);
return prec, rec, f1
ошибка:
in train
pre_test, rec_test, f1_test = compute_f1(predLabels, correctLabels, self.idx2Label)
File "...", line 10, in compute_f1
label_pred.append([idx2Label[element] for element in sentence])
File "...", line 10, in <listcomp>
label_pred.append([idx2Label[element] for element in sentence])
TypeError: unhashable type: 'numpy.ndarray'