Почему этот простой классификатор классов keras 3 предсказывает только один класс вместо других классов?

#keras #deep-learning

#keras #глубокое обучение

Вопрос:

Я пытаюсь создать простой классификатор глубокого обучения 3 класса, используя keras следующим образом:

 clf = Sequential()
clf.add(Dense(20, activation='relu', input_dim=NUM_OF_FEATURES))
clf.add(Dense(10, activation='relu'))
clf.add(Dense(3, activation='relu'))
clf.add(Dense(1, activation='softmax'))


# Model Compilation
clf.compile(optimizer = 'adam',
             loss = 'categorical_crossentropy',
             metrics = ['accuracy'])

# Training the model
clf.fit(X_train,
         y_train,
         epochs=10,
         batch_size=16,
         validation_data=(X_val, y_val))
  

Как после обучения при прогнозировании он всегда предсказывает только один и тот же класс (класс 1) из 3 классов.

Моя сетевая архитектура неверна?

Я новичок в глубоком обучении и ИИ.

Комментарии:

1. Пожалуйста, укажите часть вашего кода, в которой вы компилируете свою модель.

2. @Chicodelarosa обновлено, спасибо

Ответ №1:

Если вы хотите, чтобы сеть классифицировала три класса, ваш последний плотный слой должен иметь три выходных узла. В примере последний плотный слой имеет один выходной узел.

 clf = Sequential()
clf.add(Dense(20, activation='relu', input_dim=NUM_OF_FEATURES))
clf.add(Dense(10, activation='relu'))
clf.add(Dense(3, activation='relu'))
clf.add(Dense(3, activation='softmax'))
  

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

Что касается функции потерь, если вы хотите использовать перекрестную энтропию, у вас есть выбор между разреженной категориальной перекрестной энтропией и категориальной перекрестной энтропией. Последний ожидает, что метки истинности будут закодированы с одним горячим кодом (вы можете использовать tf.one_hot для этого). Другими словами, форма меток совпадает с формой выходных данных сети. С другой стороны, разреженная категориальная перекрестная энтропия ожидает метки с рангом N-1, где N — ранг выходных данных нейронной сети. Другими словами, это метки перед одноразовым кодированием.

Когда модель используется для вывода, предсказанные значения классов могут быть получены с помощью argmax последнего измерения прогнозов.

 predictions = clf.predict(x)
classes = predictions.argmax(-1)
  

Комментарии:

1. Но с последним плотным слоем с выводом 3 выдает следующую ошибку: ValueError: Shapes (None, 1) and (None, 3) are incompatible

2. Это может быть связано с вашей функцией потерь. Ваши значения для y_train целых чисел 0, 1 и 2? Если это так, вы должны использовать sparse_categorical_crossentropy для своей функции потерь. categorical_crossentropy ожидается, что метки с кодировкой «один горячий», тогда sparse_categorical_crossentropy как ожидается, что метки с кодировкой «не один горячий».

3. что лучше? sparse_categorical_crossentropy или categorical_crossentropy ?

4. Они вычисляют одни и те же потери (т. Е. Перекрестную энтропию), но ожидают меток в разных формах. categorical_crossentropy ожидается, что метки с кодировкой «один горячий» (2D в вашем случае) и sparse_categorical_crossentropy ожидается, что метки с кодировкой «не один горячий» (1D в вашем случае).

5. хорошо, но sparse_categorical_crossentropy выдает матрицу значений с плавающей запятой (array([[0.7737731 , 0.19874486, 0.02748196], [0.86113244, 0.12877706, 0.01009052], [0.9258943 , 0.07132111, 0.00278455], ..., [0.8239085 , 0.15966693, 0.01642458], [0.80182225, 0.1772431 , 0.02093465], [0.9042275 , 0.0910617 , 0.00471088]], dtype=float32)) . Я хотел получить предсказанные метки классов как 0, 1 или 2.