Расчет веса на лету Keras в пользовательской функции потерь - PullRequest
2 голосов
/ 25 февраля 2020

Я реализую тип сети сегментации в кератах (с tf backend), где я хочу оценить потери для каждого изображения. Вес будет иметь ту же форму, что и целевое изображение, т.е. каждый пиксель будет по-разному взвешиваться в потере. Насколько я могу судить, keras не имеет возможности реализовать эту схему взвешивания изначально. Веса могут быть рассчитаны на основе меток, и сохранение весов на диске невозможно из-за размера набора данных. Таким образом, я начал писать свою собственную функцию потерь, которая может вычислять весовую матрицу на лету по меткам.

labels.shape == (?, 5, 101, 101). Вес можно найти в словаре на основе оси 1. Поэтому для первого элемента в пакете запись для labels[0, :, 0, 0] равна [1, 0, 0, 1, 0], я бы посмотрел это значение в словаре. Если бы метки были массивом numpy, я мог бы сделать следующее:

labels.astype(object).sum(axis=1).astype(str)

Это дало бы мне массив формы (?, 101, 101) с записями типа '10010', который я мог бы найти в словаре lookup. Я мог бы назначить weights[0, :, 0, 0] = lookup['10010']. Наконец, с заполненным тензором весов я мог бы получить свою потерю как:

keras.backend.categorical_crossentropy(labels, predictions) * keras.backend.constant(weights).

Проблема в том, что я не могу сделать keras.backend.eval(labels), чтобы получить массив numpy в моей пользовательской функции потери. При составлении модели график строится без каких-либо данных. Использование eval в этот момент вызывает ошибку InvalidArgumentError: You must feed a value for placeholder tensor. Есть ли способ сделать dtype преобразование в строку, поиск в словаре и присвоение тензора весов символически, используя операции keras?

Или есть способ, которым я мог бы обойти эту проблему и вычислить вес в другом месте в коде? Я использую keras.utils.Sequence и вызываю fit_generator на модели для обучения - также можно вернуть веса из генератора данных.

Я использую: tennflowflow 1.9.0 и keras 2.2 .4

Я рад перейти на более современные версии пакетов.

1 Ответ

0 голосов
/ 02 марта 2020

Собираюсь ответить на мой собственный вопрос здесь в случае, если у кого-то еще есть такая же проблема

tenorflow 2 имеет некоторые функции, которые весьма полезны для этой задачи:

  1. Для преобразования матрицы с плавающей точкой в ​​строки - tf.strings.as_string
  2. Для объединения строк в измерении - tf.strings.reduce_join
  3. Для поиска значений тензора в словаре с именем weight_dict
tensor_of_interest = tensor after using tf.strings.as_string and tf.strings.reduce_join

keys = tf.constant(list(weight_dict.keys()))
values = tf.constant(list(weight_dict.values()))
weight_table = tf.lookup.StaticHashTable(
   tf.lookup.KeyValueTensorInitializer(keys, values), -1
)
weights = weight_table.lookup(tensor_of_interest)

Счастливое кодирование

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