Может ли кто-нибудь четко объяснить разницу между 1D, 2D и 3D свертками в сверточных нейронных сетях (в глубоком обучении) с использованием примеров?
127
Может ли кто-нибудь четко объяснить разницу между 1D, 2D и 3D свертками в сверточных нейронных сетях (в глубоком обучении) с использованием примеров?
Хочу пояснить картинкой из C3D .
Короче говоря, направление свертки и форма вывода важны!
↑↑↑↑↑ 1D Convolutions - Базовая ↑↑↑↑↑
import tensorflow as tf
import numpy as np
sess = tf.Session()
ones_1d = np.ones(5)
weight_1d = np.ones(3)
strides_1d = 1
in_1d = tf.constant(ones_1d, dtype=tf.float32)
filter_1d = tf.constant(weight_1d, dtype=tf.float32)
in_width = int(in_1d.shape[0])
filter_width = int(filter_1d.shape[0])
input_1d = tf.reshape(in_1d, [1, in_width, 1])
kernel_1d = tf.reshape(filter_1d, [filter_width, 1, 1])
output_1d = tf.squeeze(tf.nn.conv1d(input_1d, kernel_1d, strides_1d, padding='SAME'))
print sess.run(output_1d)
↑↑↑↑↑ 2D Convolutions - Basic ↑↑↑↑↑
ones_2d = np.ones((5,5))
weight_2d = np.ones((3,3))
strides_2d = [1, 1, 1, 1]
in_2d = tf.constant(ones_2d, dtype=tf.float32)
filter_2d = tf.constant(weight_2d, dtype=tf.float32)
in_width = int(in_2d.shape[0])
in_height = int(in_2d.shape[1])
filter_width = int(filter_2d.shape[0])
filter_height = int(filter_2d.shape[1])
input_2d = tf.reshape(in_2d, [1, in_height, in_width, 1])
kernel_2d = tf.reshape(filter_2d, [filter_height, filter_width, 1, 1])
output_2d = tf.squeeze(tf.nn.conv2d(input_2d, kernel_2d, strides=strides_2d, padding='SAME'))
print sess.run(output_2d)
↑↑↑↑↑ 3D Convolutions - Базовая ↑↑↑↑↑
ones_3d = np.ones((5,5,5))
weight_3d = np.ones((3,3,3))
strides_3d = [1, 1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_3d = tf.constant(weight_3d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
in_depth = int(in_3d.shape[2])
filter_width = int(filter_3d.shape[0])
filter_height = int(filter_3d.shape[1])
filter_depth = int(filter_3d.shape[2])
input_3d = tf.reshape(in_3d, [1, in_depth, in_height, in_width, 1])
kernel_3d = tf.reshape(filter_3d, [filter_depth, filter_height, filter_width, 1, 1])
output_3d = tf.squeeze(tf.nn.conv3d(input_3d, kernel_3d, strides=strides_3d, padding='SAME'))
print sess.run(output_3d)
↑↑↑↑↑ 2D-свертки с 3D-вводом - LeNet, VGG, ..., ↑↑↑↑↑
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
ones_3d = np.ones((5,5,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae with in_channels
weight_3d = np.ones((3,3,in_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_3d = tf.constant(weight_3d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_3d.shape[0])
filter_height = int(filter_3d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_3d = tf.reshape(filter_3d, [filter_height, filter_width, in_channels, 1])
output_2d = tf.squeeze(tf.nn.conv2d(input_3d, kernel_3d, strides=strides_2d, padding='SAME'))
print sess.run(output_2d)
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
out_channels = 64 # 128, 256, ...
ones_3d = np.ones((5,5,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae x number of filters = 4D
weight_4d = np.ones((3,3,in_channels, out_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_4d = tf.constant(weight_4d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_4d.shape[0])
filter_height = int(filter_4d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_4d = tf.reshape(filter_4d, [filter_height, filter_width, in_channels, out_channels])
#output stacked shape is 3D = 2D x N matrix
output_3d = tf.nn.conv2d(input_3d, kernel_4d, strides=strides_2d, padding='SAME')
print sess.run(output_3d)
↑↑↑↑↑ Бонус 1x1 в CNN - GoogLeNet, ..., ↑↑↑↑↑
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
out_channels = 64 # 128, 256, ...
ones_3d = np.ones((1,1,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae x number of filters = 4D
weight_4d = np.ones((3,3,in_channels, out_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_4d = tf.constant(weight_4d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_4d.shape[0])
filter_height = int(filter_4d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_4d = tf.reshape(filter_4d, [filter_height, filter_width, in_channels, out_channels])
#output stacked shape is 3D = 2D x N matrix
output_3d = tf.nn.conv2d(input_3d, kernel_4d, strides=strides_2d, padding='SAME')
print sess.run(output_3d)
- Исходная ссылка: ССЫЛКА
- Автор: Мартин Гёрнер
- Twitter: @martin_gorner
- Google +: plus.google.com/+MartinGorne
↑↑↑↑↑ 1D свертки с входом 1D ↑↑↑↑↑
↑↑↑↑↑ 1D свертки с двумерным вводом ↑↑↑↑↑
in_channels = 32 # 3, 32, 64, 128, ...
out_channels = 64 # 3, 32, 64, 128, ...
ones_4d = np.ones((5,5,5,in_channels))
weight_5d = np.ones((3,3,3,in_channels,out_channels))
strides_3d = [1, 1, 1, 1, 1]
in_4d = tf.constant(ones_4d, dtype=tf.float32)
filter_5d = tf.constant(weight_5d, dtype=tf.float32)
in_width = int(in_4d.shape[0])
in_height = int(in_4d.shape[1])
in_depth = int(in_4d.shape[2])
filter_width = int(filter_5d.shape[0])
filter_height = int(filter_5d.shape[1])
filter_depth = int(filter_5d.shape[2])
input_4d = tf.reshape(in_4d, [1, in_depth, in_height, in_width, in_channels])
kernel_5d = tf.reshape(filter_5d, [filter_depth, filter_height, filter_width, in_channels, out_channels])
output_4d = tf.nn.conv3d(input_4d, kernel_5d, strides=strides_3d, padding='SAME')
print sess.run(output_4d)
sess.close()
1
, затем → для строки1+stride
. Сама свертка инвариантна к сдвигу, так почему же направление свертки имеет значение?После ответа от @runhani я добавляю еще несколько деталей, чтобы сделать объяснение немного более ясным, и попытаюсь объяснить это немного подробнее (и, конечно, с примерами из TF1 и TF2).
Одна из основных дополнительных составляющих, которые я включаю:
tf.Variable
1D свертка
Вот как можно сделать одномерную свертку с использованием TF 1 и TF 2.
И, чтобы быть конкретным, мои данные имеют следующие формы:
[batch size, width, in channels]
(например1, 5, 1
)[width, in channels, out channels]
(например5, 1, 4
)[batch size, width, out_channels]
(например1, 5, 4
)Пример TF1
Пример TF2
С TF2 гораздо меньше работы, так как TF2 не нужен
Session
иvariable_initializer
например.Как это могло бы выглядеть в реальной жизни?
Итак, давайте разберемся, что это делает, на примере сглаживания сигнала. Слева вы получили оригинал, а справа вы получили результат Convolution 1D, который имеет 3 выходных канала.
Что означают несколько каналов?
Множественные каналы - это в основном множественные функциональные представления входа. В этом примере у вас есть три представления, полученные с помощью трех разных фильтров. Первый канал - это равновзвешенный сглаживающий фильтр. Второй - это фильтр, который взвешивает середину фильтра больше, чем границы. Последний фильтр работает противоположно второму. Таким образом, вы можете увидеть, как эти разные фильтры вызывают разные эффекты.
Приложения глубокого обучения одномерной свертки
1D свертка успешно использовалась для задачи классификации предложений .
2D свертка
Переход к 2D-свертке. Если вы занимаетесь глубоким обучением, шансы, что вы не сталкивались с двумерной сверткой,… ну, почти ноль. Он используется в CNN для классификации изображений, обнаружения объектов и т. Д., А также в задачах НЛП, связанных с изображениями (например, генерация подписи к изображениям).
Давайте попробуем пример, у меня есть ядро свертки со следующими фильтрами:
И, чтобы быть конкретным, мои данные имеют следующие формы:
[batch_size, height, width, 1]
(например1, 340, 371, 1
)[height, width, in channels, out channels]
(например3, 3, 1, 3
)[batch_size, height, width, out_channels]
(например1, 340, 371, 3
)Пример TF1,
Пример TF2
Как это могло бы выглядеть в реальной жизни?
Здесь вы можете увидеть результат, полученный с помощью приведенного выше кода. Первое изображение является оригинальным и идет по часовой стрелке, у вас есть выходы 1-го фильтра, 2-го фильтра и 3-го фильтра.
Что означают несколько каналов?
В контексте двумерной свертки гораздо легче понять, что означают эти множественные каналы. Допустим, вы делаете распознавание лиц. Вы можете представить себе (это очень нереалистичное упрощение, но передает суть), каждый фильтр представляет глаз, рот, нос и т. Д. Таким образом, каждая карта функций будет двоичным представлением того, присутствует ли эта функция на изображении, которое вы предоставили. , Не думаю, что нужно подчеркивать, что для модели распознавания лиц это очень ценные функции. Больше информации в этой статье .
Это иллюстрация того, что я пытаюсь сформулировать.
Приложения глубокого обучения 2D-свертки
Двумерная свертка очень распространена в сфере глубокого обучения.
CNN (сверточные нейронные сети) используют операцию двумерной свертки почти для всех задач компьютерного зрения (например, для классификации изображений, обнаружения объектов, классификации видео).
3D свертка
Теперь становится все труднее проиллюстрировать, что происходит, по мере увеличения количества измерений. Но с хорошим пониманием того, как работает свертка 1D и 2D, очень просто обобщить это понимание до свертки 3D. Итак, начнем.
И, чтобы быть конкретным, мои данные имеют следующие формы:
[batch size, height, width, depth, in channels]
(например1, 200, 200, 200, 1
)[height, width, depth, in channels, out channels]
(например5, 5, 5, 1, 3
)[batch size, width, height, width, depth, out_channels]
(например1, 200, 200, 2000, 3
)Пример TF1
Пример TF2
Приложения для глубокого обучения 3D-свертки
Трехмерная свертка использовалась при разработке приложений машинного обучения с использованием данных LIDAR (Light Detection and Ranging), которые по своей природе являются трехмерными.
Что ... больше жаргона ?: Шаг и отступы
Хорошо, ты почти у цели. Так что держись. Посмотрим, что такое stride и padding. Если задуматься, они довольно интуитивны.
Если вы перейдете через коридор, вы доберетесь туда быстрее, сделав меньше шагов. Но это также означает, что вы наблюдали меньше окружающих, чем если бы вы шли через комнату. Давайте теперь подкрепим наше понимание красивой картинкой! Давайте разберемся с этим с помощью 2D-свертки.
Понимание шага
Когда вы используете,
tf.nn.conv2d
например, вам нужно установить его как вектор из 4 элементов. Нет причин пугаться этого. Он просто содержит шаги в следующем порядке.2D свертка -
[batch stride, height stride, width stride, channel stride]
. Здесь пакетный шаг и шаг канала вы просто установили на один (я внедрял модели глубокого обучения в течение 5 лет, и мне никогда не приходилось настраивать их ни на что, кроме одного). Таким образом, у вас остается только 2 шага.3D свертка -
[batch stride, height stride, width stride, depth stride, channel stride]
. Здесь вы беспокоитесь только о шагах высоты / ширины / глубины.Понимание заполнения
Теперь вы замечаете, что независимо от того, насколько мал ваш шаг (т.е. 1), во время свертки происходит неизбежное уменьшение размеров (например, ширина равна 3 после свертки изображения шириной 4 единицы). Это нежелательно, особенно при построении нейронных сетей с глубокой сверткой. Здесь на помощь приходит набивка. Есть два наиболее часто используемых типа заполнения.
SAME
иVALID
Ниже вы можете увидеть разницу.
Последнее слово : если вам очень любопытно, возможно, вам интересно. Мы просто сбросили бомбу на автоматическое уменьшение размеров и теперь говорим о разных успехах. Но самое лучшее в шаге - это то, что вы контролируете, когда, где и как уменьшаются размеры.
источник
CNN 1D, 2D или 3D относится к направлению свертки, а не к измерению входа или фильтра.
Для 1-канального входа CNN2D равно CNN1D: длина ядра = длина входа. (1 направление конв.)
источник
Таким образом, в 1D CNN ядро движется в одном направлении. Входные и выходные данные 1D CNN двумерны. В основном используется для данных временных рядов.
В 2D CNN ядро движется в 2 направлениях. Входные и выходные данные 2D CNN трехмерны. В основном используется для данных изображения.
В 3D CNN ядро движется в трех направлениях. Входные и выходные данные 3D CNN четырехмерны. В основном используется для данных 3D-изображений (МРТ, КТ).
Вы можете найти более подробную информацию здесь: https://medium.com/@xzz201920/conv1d-conv2d-and-conv3d-8a59182c4d6
источник