Веса выборки для Semanti c сегментации - PullRequest
1 голос
/ 25 мая 2020

Я пытаюсь решить проблему semanti c сегментации с помощью бэкэнда Keras и Tensorflow2. Я пытаюсь пометить каждый пиксель как один из 22 классов с категориальной перекрестной энтропией. Формы моих входных и выходных данных:

Input: (None, 224, 224, 3)

Output: (None, 224, 224, 23) 22 and 1 for background

Я хотел добавить веса для каждого образца, чтобы попробовать псевдо-маркировку с моей моделью. Для выборки весов я попытался создать массив выборочных весов, который представляет собой одномерный массив и имеет длину, такую ​​же, как размер партии. Но это не удалось и выдало следующую ошибку:

weights can not be broadcast to values. values.rank=3. weights.rank=1.

Затем я попытался предоставить 3D-массив (16, 224, 224) в качестве весов выборки с размером пакета 16, и это дало следующую ошибку:

Found a sample_weight array with shape (16, 224, 224).
In order to use timestep-wise sample weights, you should specify sample_weight_mode="temporal" in compile(). 
If you just mean to use sample-wise weights, make sure your sample_weight array is 1D.

1 Ответ

0 голосов
/ 02 сентября 2020

Мне удалось решить аналогичную проблему с TF2 с несколькими выходами и использованием loss_weights в model.compile. Таким образом, окончательные потери, используемые для обучения сети, представляют собой взвешенную сумму каждой потери. В моем случае у меня было 2 класса, а не 23, поэтому вам нужно было бы изменить код для этих 23. Также обратите внимание, что слой c9 в коде имеет 3 фильтра, поэтому вам может потребоваться его увеличить.

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.optimizers import Adam
# build your CNN
inputs = Input((224, 224, 1), name='inputs')
c1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)
...
c9 = Conv2D(3, (3, 3), activation='relu',padding='same')(c9)

output_0 = Conv2D(1, (1, 1), name='class0')(c9)
output_1 = Conv2D(1, (1, 1), name='class1')(c9)

model = Model(inputs=inputs, outputs=[output_0, output_1])
model.compile(optimizer=Adam(learning_rate=0.001, name='adam'),
              loss=[BinaryCrossentropy(from_logits=True), BinaryCrossentropy(from_logits=True)],
              loss_weights=[1, 1000],
              metrics=[["accuracy"], ["accuracy", "mse"]])

Кроме того, вы можете определить pdf-файл выборки в генераторе данных, чтобы, например, вы подавали в сеть больше объектов, принадлежащих к одному классу, чем к фону. Эффект может быть аналогичен использованию функции взвешенных потерь. В конце сеть пытается минимизировать усредненное значение потерь, поэтому, если вы добавите больше выборок одного класса, на это усредненное значение потерь будет влиять именно результат для этого класса.

...