#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.