Как реализовать пиксельную классификацию для маркировки сцены в TensorFlow?

Я работаю над глубокой обучающей моделью, используя Google TensorFlow. Модель должна использоваться для сегментов и ярлыков.

  • Я использую набор SiftFlow dataset, который имеет 33 семантических классов и изображений с 256x256 пикселей.
  • В результате на моем конечном слое с использованием свертки и деконволюции я прихожу к следующему тензору (массиву) [256, 256, 33].
  • Далее я хотел бы примените Softmax и сравните результаты с семантической меткой размера [256, 256].

Вопросы: Должен ли я применять среднее усреднение или argmax к моему последнему слою, чтобы его форма становилась [256, 256,1], а затем пробивала каждый пиксель и классифицировала, как если бы я классифицировал экземпляры 256x256? Если да, то как, если нет, какие другие варианты?

Ответы

Ответ 1

Чтобы применить softmax и использовать кросс-энтропийную потерю, вы должны сохранить неповрежденный конечный вывод вашей сети размера batch_size x 256 x 256 x 33. Поэтому вы не может использовать среднее усреднение или argmax, потому что это разрушит вероятность вывода вашей сети.

Вам нужно пройти через все batch_size x 256 x 256 пикселей и применить к этому пикселю кросс-энтропийную потерю. Это легко сделать с помощью встроенной функции tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels).

Некоторые предупреждения из документа перед применением кода ниже:

  • ПРЕДУПРЕЖДЕНИЕ. Этот op ожидает немасштабированных логинов, так как он выполняет softmax на входах внутри для повышения эффективности. Не вызывайте этот op с выходом softmax, так как это приведет к неправильным результатам.
  • и должна иметь форму [batch_size, num_classes] и dtype (либо float32, либо float64).
  • метки должны иметь форму [batch_size] и dtype int64.

Хитрость заключается в использовании batch_size * 256 * 256 в качестве размера партии, требуемого функцией. Мы преобразуем logits и labels в этот формат. Вот код, который я использую:

inputs = tf.placeholder(tf.float32, [batch_size, 256, 256, 3])  # input images
logits = inference(inputs)  # your outputs of shape [batch_size, 256, 256, 33] (no final softmax !!)
labels = tf.placeholder(tf.float32, [batch_size, 256, 256])  # your labels of shape [batch_size, 256, 256] and type int64

reshaped_logits = tf.reshape(logits, [-1, 33])  # shape [batch_size*256*256, 33]
reshaped_labels = tf.reshape(labels, [-1])  # shape [batch_size*256*256]
loss = sparse_softmax_cross_entropy_with_logits(reshaped_logits, reshaped_labels)

Затем вы можете применить оптимизатор к этой ошибке.


Обновление: v0.10

Документация tf.sparse_softmax_cross_entropy_with_logits показывает, что теперь она принимает любую форму для logits, поэтому нет необходимости изменять тензоры ( спасибо @chillinger):

inputs = tf.placeholder(tf.float32, [batch_size, 256, 256, 3])  # input images
logits = inference(inputs)  # your outputs of shape [batch_size, 256, 256, 33] (no final softmax !!)
labels = tf.placeholder(tf.float32, [batch_size, 256, 256])  # your labels of shape [batch_size, 256, 256] and type int64

loss = sparse_softmax_cross_entropy_with_logits(logits, labels)