Свертка для уменьшения размерности одномерного вектора
В CNN, если выходные данные являются одномерным вектором (скажем, предварительным логическим уровнем), как можно уменьшить размерность до указанного размера, используя только свертки?
Как получить размеры фильтра / поле восприятия для выполнения такой задачи?
Я знаю, что это может быть достигнуто путем размещения полностью подключенного слоя на конце сети, но это не кажется таким элегантным.
3 ответа
Используйте идею, первоначально предложенную в документе All Convolutional Net, а затем широко использовавшуюся в начальной сети, т.е. примените свертку для уменьшения размерности.
Хитрость заключается в том, чтобы выполнить свертку с единицей filter
(1x1
для двумерной свертки, 1x1x1
для 3D и т. д.) с меньшим количеством фильтров. В настоящее время этот прием применяется постоянно для сохранения вычислений в очень глубоких сверточных сетях, поэтому его можно использовать и перед сверточными слоями. В вашем вопросе выходной тензор является одномерным (кроме размера пакета), поэтому используйте 1-D свертку с 1
размер ядра.
Вот код в программе tenorflow, который уменьшает длину тензора с 64 до 32:
# `x` shape: [batch, length] = [?, 64]
layer = tf.expand_dims(x, 2) # reshape to: [batch, channels, 1] = [?, 64, 1]
output = tf.layers.conv1d(layer, filters=32, kernel_size=1,
strides=1, padding='valid',
data_format='channels_first')
# new shape: [batch, filters, 1] = [?, 32, 1]
output = tf.squeeze(output) # reshape to: [batch, length] = [?, 32]
Как насчет одномерной свертки? Вы можете использовать шаги как в следующем:
n,w = x.shape
c = 1
x = x.reshape(n,w,c) # 1d vector with one 1 channel
x = conv1d(x, 1, 3, stride=2, pad=1) # 1 filter so output size will be (n,w/2,c)
x = x.reshape(n,w//2)
Это даст вам целочисленное деление вашей текущей размерности. Или вы могли бы иметь канал для каждого измерения для вашего вывода, а затем объединить по всей 1D области:
x = x.reshape(n,w,c)
x = conv1d(x, d, 3, pad=1) # d filters so output (n,w,d)
x = x.mean(1) # mean over 1d space so now (n,d)
Нет никаких гарантий относительно того, будет ли какой-либо из них действительно работать хорошо, но, будучи нейронной сетью, они, вероятно, ничего плохого не сломают.
Наконец, чит-ответ:
x = x.reshape(n,c,w) # (n,1,w)
x = conv1d(x, d, 1) # (n,1,d)
x = x.reshape(n,d)
У вас есть возможность добавить пул слой после свертки? Если да, то это одна из основных целей этого слоя, уменьшить вектор до более низкого размера.
В противном случае количество примененных фильтров является размерностью вашего выходного пространства.