Я пытаюсь обучить сеть семантической сегментации с дисбалансом классов. Чтобы учесть это, я попытался реализовать слой InfoGainLoss и указал infogain_matrix, как было опубликовано здесь, где я вместо этого использовал 1-частоту (класс) для каждого диагонального элемента.
Однако при обучении net как точность, так и потери немедленно сходятся к 0, даже при низком уровне base_lr, и сеть помечает все как класс 0 («неизвестно»). Теперь мой вопрос заключается в том, следует ли указывать infogain_matrix, как в сообщении, которое я связал, и если да, то какие еще причины могут быть для этого необычного поведения сети (я ожидал либо потери точности 0, либо точности INF 0).

Изменить:
Поэтому, когда я запускаю Сеть со слоем SoftMaxWithLoss вместо InfoGainLoss, он сразу же начинает классифицировать все как наиболее представительный класс (class1 с 90%) и больше не меняется. Теперь я предполагаю, что я неправильно настроил lmdb для infogain_matrix. Кто-нибудь знает, нужно ли указывать dtype lmdb для уровня данных caffe (изображения и infogain_matrix хранятся как float32), хотя в документации caffe для слоя этого не сказано? Или, более того, какие типы dtypes уровень данных caffe ожидает от lmdb?
lmdbs были созданы с использованием кода, взятого / измененного из здесь , но для изображений среднее вычитание производилось заранее. Я протестировал чтение lmdb в python, и здесь мне пришлось указать dtype, поскольку в противном случае преобразование в исходные размеры матрицы вызывало ошибки.

Edit2:
Таким образом, ошибка действительно была в определении lmdb, поскольку для dtype = float данные должны быть добавлены к datum.float_data вместо datum.data, см. здесь . Теперь все в порядке, а точность и потери не такие уж и странные :)

3
A_Wild_Caffe_User 13 Июл 2017 в 10:05

1 ответ

Лучший ответ

Ошибка была в определении lmdb, так как для dtype = float данные должны быть добавлены к datum.float_data вместо datum.data (который нужно оставить пустым, чтобы caffe автоматически сканировал datum.float_data); ИСТОЧНИК < / а>

Итак, код из здесь для создания набора данных lmdb с помощью python можно изменить следующим образом:

with env.begin(write=True) as txn:
    # txn is a Transaction object
    for i in range(N):
        datum = caffe.proto.caffe_pb2.Datum()
        datum.channels = X.shape[1]
        datum.height = X.shape[2]
        datum.width = X.shape[3]
        datum.float_data.extend(X[i].astype(float).flat)
        datum.label = int(y[i])
        str_id = '{:08}'.format(i)
        # The encode is only essential in Python 3
        txn.put(str_id.encode('ascii'), datum.SerializeToString())

Дело в том, что caffe не выдает ошибок, если вы ошибочно добавляете данные с плавающей запятой в datum.data вместо datum.float_data, но это приведет к странному поведению, такому как точность и потеря, оба будут равны 0 (поскольку infogain_mat H может быть 0 наверняка классы из-за несоответствия dtype)

2
A_Wild_Caffe_User 13 Июл 2017 в 21:58