В настоящее время я пытаюсь реализовать свой собственный уровень потерь в caffe, и, пытаясь сделать это, я использую другие слои в качестве эталона. Одна вещь, которая озадачивает меня, однако, это использование top[0]->cpu_diff()
в Backward_cpu
, Я буду использовать EuclideanLossLayer
в качестве ссылки. Вот мои вопросы
Насколько я понимаю, что top[0]->cpu_diff()
содержит производную ошибки от следующего уровня, но что, если нет другого уровня, как он инициализируется? так как он используется в EuclideanLossLayer
без выполнения каких-либо проверок:
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
Опять же, в EuclideanLossLayer
, производная от ошибки по активациям рассчитывается с использованием следующего фрагмента кода:
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();
caffe_cpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
diff_.cpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_cpu_diff()); // b
Если мое первое предположение верно, и top[0]->cpu_diff()
действительно содержит производную ошибки для уровня выше, почему мы используем только первый элемент, т.е. top[0]->cpu_diff()[0]
в отличие от умножения на весь вектор, т.е. top[0]->cpu_diff()
?
Для слоев потерь следующего слоя не существует, и поэтому верхний блок различий технически не определен и не используется — но Caffe использует это предварительно выделенное пространство для хранения несвязанных данных: Caffe поддерживает умножение слоев потерь с определенным пользователем весом (loss_weight в прототипе ), эта информация (одно скалярное число с плавающей запятой) хранится в первом элементе массива diff верхнего двоичного объекта. Вот почему в каждом слое потерь вы увидите, что они умножаются на эту величину для поддержки этой функциональности. Это объясняется в Учебник Кафе о слое потерь.
Этот вес обычно используется для добавления вспомогательных потерь в сеть. Вы можете прочитать больше об этом в Google Идти глубже с конвульсиями или в Глубоко контролируемые сети.