Убыток за бинарную разреженность - PullRequest
1 голос
/ 11 января 2020

У меня есть двоичные изображения (как показано ниже) на выходе моего net. Мне нужно, чтобы '1' были дальше друг от друга (не связаны), чтобы они образовывали разреженное двоичное изображение (без белых пятен). Что-то вроде шума соли и перца. Я ищу способ определить потери (в pytorch), которые бы наказывали sh на основе плотности единиц.

Спасибо.

I Binary Image

1 Ответ

2 голосов
/ 12 января 2020

Это зависит от того, как вы генерируете указанное изображение. Поскольку нейронные сети должны обучаться путем обратного распространения, я уверен, что ваше двоичное изображение не является прямым выходом вашей нейронной сети (ie не то, к чему вы применяете потери), потому что градиент не может пройти через двоичный файл (дискретные) переменные. Я подозреваю, что вы делаете что-то вроде попиксельной двоичной кросс-энтропии или подобного, а затем пороговое значение.

Я предполагаю, что ваш код работает так: вы плотно регрессируете вещественные числа, а затем применяете пороговое значение, вероятно, используя sigmoid для отображения от [-inf, inf] до [0, 1]. Если это так, вы можете сделать следующее. Создайте ядро ​​свертки, которое будет 0 в центре и 1 в другом месте, размером, связанным с тем, насколько велики вы хотите, чтобы ваши "промежутки" невелики.

kernel = [
    [1, 1, 1, 1, 1]
    [1, 1, 1, 1, 1]
    [1, 1, 0, 1, 1]
    [1, 1, 1, 1, 1]
    [1, 1, 1, 1, 1]
]

Затем вы применяете sigmoid к ваш действительный выходной результат в squa sh это в [0, 1]:

squashed = torch.sigmoid(nn_output)

, затем вы сворачиваете squashed с kernel, что дает вам ослабленное число ненулевых соседей.

neighborhood = nn.functional.conv2d(squashed, kernel, padding=2)

и ваша потеря будет произведена как значение каждого пикселя в squashed с соответствующим значением в neighborhood:

sparsity_loss = (squashed * neighborhood).mean()

Если вы думаете, что эта потеря применяется к вашему двоичному файлу image, для данного пикселя p это будет 1, если и только если оба p и хотя бы один из его соседей имеют значения 1 и 0 в противном случае. Поскольку мы применяем его к недвоичным числам в диапазоне [0, 1], это будет дифференцируемой аппроксимацией этого.

Обратите внимание, что я пропустил некоторые детали из кода выше (например, правильное изменение формы * 1035) * для работы с nn.functional.conv2d).

...