Ответ 1
Я думаю, что вы на правильном пути в целом.
Для "странных" результатов свертки я думаю, что ошибка, возможно, следующая:
Рассмотрим двумерную свертку
и пусть bottom[1]
форма (num, channels, height, width)
,
так как свертка в caffe
выполняется как умножение на две матрицы, weight
(представляющие ядра свертки) и col_buffer
(реорганизованные из свернутых данных), а weight
имеет строки num_out
и channels / this->group_ * kernel_h * kernel_w
, col_buffer
имеет столбцы channels / this->group_ * kernel_h * kernel_w
и столбцы height_out * width_out
, так что weight
blob динамического уровня свертки, форма bottom[0]
должна быть лучше (num, num_out, channels/group, kernel_h, kernel_w)
для удовлетворения
bottom[0]->count(1) == num_out * channels / this->group_ * kernel_h * kernel_w
в котором num_out
- это число динамических карт выходных характеристик свертки.
Это означает, что для выполнения функции свертки
this->forward_cpu_gemm(bottom_data + n * bottom[1]->count(1)
, bottom[0]->cpu_data() + n * bottom[0]->count(1)
, top_data + n * this->top_dim_);
работайте правильно, вы должны убедиться, что
bottom[0]->shape(0) == bottom[1]->shape(0) == num
bottom[0]->count(1) == num_out * channels / this->group_ * kernel_h * kernel_w
Таким образом, возможно, что простое сверточное ядро 4-мерного np.ones((1,1,3,3))
, которое вы использовали, может не удовлетворять указанному выше условию и приводить к неправильным результатам свертки.
Надеюсь, что это ясно и поможет вам.
########## Обновление 1, 10 октября 2016 года, время в Пекине ##########
Я добавляю динамический уровень свертки здесь, но без unit test. Этот слой не нарушает рабочий процесс caffe и только изменяет некоторые частные члены класса BaseConvolution для защиты.
Используемые файлы:
include/caffe/layers/dyn_conv_layer.hpp,base_conv_layer.hpp
src/caffe/layers/dyn_conv_layer.cpp(cu)
Он растет почти одинаково со слоем свертки в caffe
, и различия в основном следующие:
- Отмените функцию
LayerSetUp()
, чтобы инициализироватьthis->kernel_dim_
,this->weight_offset_
и т.д. правильно для свертки и игнорировать инициализациюthis->blobs_
, используемую слоем Convolution, чтобы содержать вес и смещение; - Отмените функцию
Reshape()
, чтобы проверить, чтоbottom[1]
как контейнер ядра имеет правильную форму для свертки.
Поскольку у меня нет времени на его тестирование, могут быть ошибки, и я буду очень рад видеть ваши отзывы.
########## Обновление 2, 12 октября 2016 года, по пекинскому времени ##########
Я обновил тестовый пример динамическая свертка только сейчас. Причастный файл src/caffe/test/test_dyn_convolution_layer.cpp
. Кажется, что это нормально, но, возможно, нужно провести более тщательные тесты.
Вы можете создать этот caffe cd $CAFFE_ROOT/build && ccmake ..
, cmake -DBUILD_only_tests="dyn_convolution_layer" ..
и make runtest
, чтобы проверить его.