lasagne - Как его Conv2DDNNLayer работает с четным размером фильтра в "том же" режиме?
На https://lasagne.readthedocs.io/en/latest/modules/layers/dnn.html
это говорит, для lasagne.layers.dnn.Conv2DDNNLayer,
"одинаковые" прокладки с половиной размера фильтра (с округлением вниз) с обеих сторон. Когда шаг =1, это приводит к выходному размеру, равному входному размеру. Даже размер фильтра не поддерживается.
Тем не менее, я вижу, что кто-то использует фильтр четного размера с "тем же" режимом.
Это второе место в конкурсе по выявлению диабетической ретинопатии Kaggle.
https://www.kaggle.com/c/diabetic-retinopathy-detection/discussion/15617
исходный код: https://github.com/sveitser/kaggle_diabetic
Обратите внимание, что в configs / c_128_4x4_32.py:
они создают слои свертки, как это:
(Conv2DLayer, cp(n, stride=(2, 2)))
где
from config import Config
from data import BALANCE_WEIGHTS
from layers import *
# -----SKIPPED SOME CODES HERE-----
def cp(num_filters, *args, **kwargs):
args = {
'num_filters': num_filters,
'filter_size': (4, 4),
}
args.update(kwargs)
return conv_params(**args)
n = 32
и в layer.py:
# -----SKIPPED SOME CODES HERE-----
try:
import lasagne.layers.dnn
Conv2DLayer = lasagne.layers.dnn.Conv2DDNNLayer
MaxPool2DLayer = lasagne.layers.dnn.MaxPool2DDNNLayer
Pool2DLayer = lasagne.layers.dnn.Pool2DDNNLayer
print("using CUDNN backend")
except ImportError:
print("failed to load CUDNN backend")
try:
import lasagne.layers.cuda_convnet
Conv2DLayer = lasagne.layers.cuda_convnet.Conv2DCCLayer
Pool2DLayer = lasagne.layers.cuda_convnet.Pool2DLayer
MaxPool2DLayer = lasagne.layers.cuda_convnet.MaxPool2DCCLayer
print("using CUDAConvNet backend")
except ImportError as exc:
print("failed to load CUDAConvNet backend")
Conv2DLayer = lasagne.layers.conv.Conv2DLayer
MaxPool2DLayer = lasagne.layers.pool.MaxPool2DLayer
Pool2DLayer = MaxPool2DLayer
print("using CPU backend")
# -----SKIPPED SOME CODES HERE-----
def conv_params(num_filters, filter_size=(3, 3), border_mode='same',nonlinearity=leaky_rectify, W=init.Orthogonal(gain=1.0),b=init.Constant(0.05), untie_biases=True,**kwargs):
args = {
'num_filters': num_filters,
'filter_size': filter_size,
'border_mode': border_mode,
'nonlinearity': nonlinearity,
'W': W,
'b': b,
'untie_biases': untie_biases,
}
args.update(kwargs)
return args
Это показывает, что они использовали фильтр четного размера (4x4) с "тем же" режимом, и это как-то работало.
Поскольку я изучаю их решение и пытаюсь сделать его версию с тензорным потоком, для меня важно знать, что сделала эта функция, независимо от того, "работала ли она как задумано".
Эта проблема также связана с их сетевой моделью, или, более конкретно, сетью B в их отчете ( https://github.com/sveitser/kaggle_diabetic/blob/master/doc/report.pdf), где слой свертки с фильтром 4x4 и размер шага 1 в "том же" режиме дал выход 56x56 с входом 57x57 (чистый B, уровень 7). На самом деле, именно здесь я впервые заметил эту проблему. Та же настройка (шаг 1, фильтр 4x4,"тот же" режим) в тензорном потоке приведет к выходу 57x57 вместо 56x56.
Итак, что в этом случае будет делать Conv2DDNNLayer?
Изменить: дополнительная информация: я заметил, что в кодах выше ((Conv2DLayer, cp(n, stride=(2, 2)))
), переменная не прошла pad
в Conv2DDNNLayer. Вместо этого border_mode
передается в него, и он был установлен на "то же самое", как по умолчанию в conv_params
, Однако я не нашел border_mode
в документации Conv2DDNNLayer.
Кто-нибудь знает где это border_mode
происходит от?
Поведает ли Conv2DDNNLayer по-разному, если он установлен в "тот же" режим border_mode
вместо pad
?
Редактировать 2: я сейчас использую обходной путь, который в тензорном потоке, я вручную дополняю изображения 1 пикселем по 0 с каждой стороны, а затем применяю фильтр 4x4 в "действительном" режиме. Это получит выход 56x56, но я не знаю, будет ли это так же, как будет вести себя Conv2DDNNLayer.