Увеличить выходные значения сигмоидного прогноза - PullRequest
2 голосов
/ 02 апреля 2019

Я создал модель Conv1D для классификации текста.

При использовании softmax / sigmoid на последнем плотном, он дает результат как

softmax => [0.98502016 0.0149798 ]
sigmoid => [0.03902826 0.00037046]

Я просто хочу, чтобы первый индекс сигмоидного результата был как минимум больше 0,8 . Просто хочу, чтобы мультиклассы имели независимые результаты. Как мне этого добиться?

Краткое описание модели:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 128, 100)          600       
_________________________________________________________________
conv1d (Conv1D)              (None, 126, 128)          38528     
_________________________________________________________________
max_pooling1d (MaxPooling1D) (None, 63, 128)           0         
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 61, 128)           49280     
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 30, 128)           0         
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 28, 128)           49280     
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 14, 128)           0         
_________________________________________________________________
flatten (Flatten)            (None, 1792)              0         
_________________________________________________________________
dense (Dense)                (None, 2)                 3586      
=================================================================
Total params: 141,274
Trainable params: 141,274
Non-trainable params: 0
_________________________________________________________________
model.add(keras.layers.Dense(num_class, activation='sigmoid'))
model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop', metrics=['acc'])

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Я согласен с комментарием @ blue-phoenox, что вы не должны использовать сигмоид с перекрестной энтропией, потому что сумма вероятностей классов не равна единице. Но если у вас есть причины для использования sigmoid, вы можете нормализовать ваш вывод по сумме векторных элементов, чтобы сделать его равным 1:

output = output/tf.reshape(tf.reduce_sum(output, 1), (-1, 1))

И вы получите:

import tensorflow as tf

output = tf.Variable([[0.03902826, 0.00037046]])
output = output/tf.reshape(tf.reduce_sum(output, 1), (-1, 1))
summedup = tf.reduce_sum(output, axis=1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(output.eval()) # [[0.9905971  0.00940284]] - new output
    print(summedup.eval()) # [1.] -  summs up to 1

Чтобы реализовать его в keras, вы можете создать подкласс tf.keras.layers.Layer следующим образом:

from tensorflow.keras import layers

class NormLayer(layers.Layer):
    def __init__(self):
        super(NormLayer, self).__init__()

    def call(self, inputs):
        return inputs / tf.reshape(tf.reduce_sum(inputs, 1), (-1, 1))

А затем используйте его в вашей Sequential() модели:

# using dummy data to illustrate
x_train = np.array([[-1.551, -1.469], [1.022, 1.664]], dtype=np.float32)
y_train = np.array([[0, 1], [1, 0]], dtype=np.int32)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units=2, activation=tf.nn.sigmoid, input_shape=(2, )))
model.add(NormLayer())

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x=x_train,
          y=y_train,
          epochs=2,
          batch_size=2)
# ...
1 голос
/ 02 апреля 2019

Sigmoid выдает выходной сигнал от 0 до 1. Если вы используете одну и ту же функцию потерь для softmax и sigmoid, то она не будет работать.Попробуйте вместо этого binary_crossentropy.И если у вас более 2 классов, я не думаю, что сигмоид - это то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...