Как извлечь вес из слоя softmax? - PullRequest
0 голосов
/ 18 мая 2018

У меня проблемы с пониманием формы вывода матрицы весов в Керасе.

У меня есть простой BiLSTM, подобный следующему:

model = Sequential()
model.add(Embedding(vocab_size, embedding_size, input_length=55, weights=[pretrained_weights])) 
model.add(Bidirectional(LSTM(units=embedding_size)))
model.add(Dense(5926, activation='softmax')) # number of classes

print(model.summary())

weights = model.layers[-1].get_weights()
print(weights)
print(len(weights))
print(weights[0][0].shape)
print(weights[0][0])

for e in zip(model.layers[-1].trainable_weights, model.layers[-1].get_weights()):
    print('Param %s:\n%s' % (e[0],e[1]))

model.compile(loss='categorical_crossentropy',
          optimizer = RMSprop(lr=0.0005),
          metrics=['accuracy'])

model.fit(np.array(X_train), np.array(y_train), epochs=100, validation_data=(np.array(X_val), np.array(y_val)))

Если я печатаю форму последнеговеса слоев, я получаю это:

Param <tf.Variable 'dense_14/kernel:0' shape=(200, 5926) dtype=float32_ref>:

, поэтому форма (200, 5926).

Это число нейронов в моей сети по количеству классов.Я хотел бы найти способ извлечения весов, связанных с каждым прогнозом, потому что тогда мне нужно обновить матрицу весов.

Мой тестовый набор состоит из моих 680 предложений, где у меня есть 1 метка на предложение.Прогнозы имеют следующую форму:

predictions = model.predict(np.array(X_test))
# shape predictions = (680, 5926)

Есть ли способ извлечь из слоя softmax весовые коэффициенты для каждого прогноза (с формой = (680,5926)? Как:

predictions = [probability_class_1, probability_class_2,......, probability_class_5926] 
weights = [weight_class_1, weight_class_2, ......., weight_class_5926]

1 Ответ

0 голосов
/ 18 мая 2018

Вам, вероятно, следует использовать второй ввод с масками, указывающими, какие глаголы для каких предложений, и выполнить простое поэлементное умножение:

sentenceInputs = Input((sentenceLength,))
desiredVerbs = Input((5926,))

sentenceOutputs = Embedding(vocab_size, embedding_size, input_length=55, weights=[pretrained_weights])(sentenceInputs)
sentenceOutputs = Bidirectional(LSTM(units=embedding_size))(sentenceOutputs)

sentenceOuptuts = Dense(5926)(sentenceOutputs)
selectedOutputs = Multiply()([sentenceOutputs, desiredVerbs])
selectedOutputs = Activation('softmax')(selectedOutputs)

model = Model([sentenceInputs,desiredVerbs], selectedOutputs)

Теперь создайте массив с нужными глаголами:

desired = np.zeros((X_train.shape[0], 5926))

#for each sentence, make the desired verbs be one:
desired[sentenceIndex, verbIndex] = 1.

#now, how you're going to do this is up to you

#if they're the same for all sentences:
verbs = [selectedVerbIndex1, selectedVerbIndex2, ...... ]
for verbIndex in verbs:
    desired[:, verbIndex] = 1.

И подходит для обоих входов:

model.fit([np.array(X_train), desired], np.array(y_train), ......)

Использование параметра class_weight в fit:

Вы можете попробовать использовать свою оригинальную модель (непредложение выше) и используйте параметр class_weight в методе fit.

Хотя это будет немного по-другому.Вы не сможете выбирать глаголы при прогнозировании, только во время тренировки.Вы не сможете выбрать разные глаголы для разных предложений.Другие глаголы никогда не будут обучаться (может быть, модель с Dense(5) будет более интересной?)

Я также не очень уверен, можно ли здесь иметь нулевые веса.

verbWeights = { i: 0. for i in range(5926) }

desiredVerbs = [verbIndex1, verbIndex2, .... ]
for verb in desiredVerbs:
    verbWeights[verb] = 1.

model.fit(X_train, y_train, class_weight = desiredVerbs, ....)
...