Этот метод занимает две строки, но избегает сравнения каждого элемента массива с максимумом и хорошо работает в 2D. Я не знаю, что это действительно будет быстрее (не асимптотически, конечно), но я думаю, что две строки лучше, чем делать цикл for для 2D в python, и удобочитаемость может быть лучше, чем использование np.where
.
import numpy as np
# here's your example input
# note - the input must be 2D even if there's just one row
# it's easy to adapt this to the 1D case, but you'll be working with 2D arrays for this anyway
class_probs = np.array([[
8.1837177e-05, 1.0788739e-03, 4.4837892e-03, 3.4919381e-04, 7.6085329e-05,
7.6562166e-05, 5.3864717e-04, 5.4001808e-04, 3.3849746e-02, 2.9903650e-04,
]])
pred_classes = np.zeros_like(class_probs)
pred_classes[range(len(class_probs)), class_probs.argmax(-1)] = 1
print(pred_classes) # [[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]]
# and here's showing the same code works for multiple rows
class_probs = np.random.rand(100, 10)
pred_classes = np.zeros_like(class_probs)
pred_classes[range(len(class_probs)), class_probs.argmax(-1)] = 1
pred_classes
(это не ваш реальный вопрос, но вы хотели использовать функцию активации сигмоида? И не softmax? Выходные данные, которые вы получаете здесь, не являются единым распределением по 10 возможным классам (вы можете видеть, что это даже не нормализовано. Скорее, у вас есть 10 распределений, по одному для каждого класса (таким образом, вероятность того, что вход был классом 0, равна 8.1837177e-05
, а вероятность того, что он не является классом 0, равна 1 - 8.1837177e-05
). Это имеет смысл, когда выполнять классификацию по нескольким меткам (где может применяться более одной метки), но тогда вам не захочется находить класс с наибольшей вероятностью, вы будете прогнозировать все классы с вероятностью выше порогового значения (например, 0,5).