содержание
Подробное объяснение Conv2DTranspose в Keras
Подробное объяснение параметров ConvTranspose2d в pytorch
принцип
Чтобы объяснить, что такое деконволюция, вы должны сначала понять, что такое свертка.
Давайте сначала поговорим о свертке: для изображения A установите его высоту и ширину как Высота, Ширина и количество каналов как Каналы. Затем мы используем ядро свертки (ядро * ядро) для выполнения свертки, (ядро свертки здесь задано квадратным, фактический прямоугольник тоже можно уподобить, поверьте, это не составит труда), размер шага шаг (то же самое, не различать направления высоты и ширины), делать отступы. B получается после свертки.
Повторение вышесказанного означает использование операции свертки для превращения A в B.
Тогда, исходя из этой предпосылки,Обратная свертка должна превратить B в A.
Итак, как указать параметры ядра свертки и что они означают?
Что касается операции свертки, я не буду много говорить и не буду объяснять ее здесь. И мы должны быть более осведомлены о том, как получить новый размер изображения из формата входного размера изображения и т. д. Возможно, некоторые люди знакомы с использованием карт функций для замены изображений.
Для операции деконволюции установка ядра свертки такая же, как и для операции свертки. Например: учитывая карту функций x и введите настройки ядра свертки. Мы просто хотим получить карту признаков y и свернуть ее с входным ядром свертки, а затем получить карту признаков x,Здесь нам нужна карта признаков y.
Всем должно быть понятно, почему я перевел это наДеконволюцияНу давай же.
Если вы не понимаете, ничего страшного, вы можете увидеть следующий пример.
Например:
Выше приведена операция свертки.
Наша карта входных признаков: x: 44channels_in,channels_in указывает количество каналов
Настройки ядра свертки: без заполнения, размер ядра 3*3, шаг 1,
Выходная карта объектов — это y, 2*2*channels_out, channels_out — это также количество каналов.
Входом операции деконволюции является карта признаков y, а ядро свертки установлено, как указано выше. Требуется указанная выше карта функций x.
Вот иллюстрация соответствующей деконволюции. Описание обобщения будет дано позже.
Формула расчета
shape:
Вход: (N,C_in,H_in,W_in)
Выход: (N,C_out,H_out,W_out)
H_{out}=(H_{in}-1)*stride[0]-2* padding[0]+kernel_size[0]+output_padding[0]
W_{out}=(W_{in}-1)*stride[1]-2* padding[1]+kernel_size[1]+output_padding[1]
Входная карта объектов: 3 × 3
Входные параметры ядра свертки: ядро 3 × 3, шаг 2, заполнение 1,output_padding равен 1
Новая карта признаков A’: (3-1)×2-2+3+1=6.
Таким образом, размер выходной карты объектов: 6×6.
Таким образом, карта объектов удваивается.
Подробное объяснение Conv2DTranspose в Keras
tf.keras.layers.Conv2DTranspose(
filters, kernel_size, strides=(1, 1), padding='valid',
output_padding=None, data_format=None, dilation_rate=(1, 1), activation=None,
use_bias=True, kernel_initializer='glorot_uniform',
bias_initializer='zeros', kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, **kwargs
)
параметр:
- фильтры: целое число, размер выходного пространства (т.е. количество фильтров в свертке).
- kernel_size: кортеж или список из двух положительных целых чисел, указывающих пространственное измерение фильтра; может быть одним целым числом, чтобы указать одно и то же значение для всех пространственных измерений.
- шаги: кортеж или список из 2 положительных целых чисел, определяющих шаги свертки; может быть одним целым числом, чтобы указать одно и то же значение для всех пространственных измерений.
- padding: может быть «действительным» или «таким же» (без учета регистра).
- output_padding: целое число или кортеж/список из 2 целых чисел, указывающих количество отступов по высоте и ширине выходного тензора. Может быть одним целым числом, указывающим одно и то же значение для всех пространственных измерений. Величина выходного заполнения в заданном измерении должна быть меньше шага в том же измерении. Если установлено значение «Нет» (по умолчанию), форма вывода будет выведена.
- data_format: строка, которая может быть channel_last (по умолчанию) илиchannels_first, представляющая порядок измерений во входных данных.channels_last соответствует входным данным с формой (пакет, высота, ширина, каналы), аchannels_first соответствует входным данным с формой (пакет , каналы) , высота, ширина) ввод.
- dilation_rate: целое число или кортеж/список из 2 целых чисел, указывающих скорость расширения, используемую для расширения свертки. Может быть одним целым числом, указывающим одно и то же значение для всех пространственных измерений. В настоящее время указание любого значения dilation_rate != 1 несовместимо с указанием любого значения шага != 1.
- активация: функция активации, установите для нее значение «Нет», чтобы сохранить линейную активацию.
- use_bias: логическое значение, указывающее, использует ли слой смещение.
- kernel_initializer: Инициализатор для сверточных ядер.
- bias_initializer: инициализатор для вектора смещения, если нет, будет использоваться инициализатор по умолчанию.
- Kernel_Regularizer: необязательный регуляризатор, сворачивающий ядро.
- bia_regularizer: необязательный регуляризатор для вектора смещения.
- activity_regularizer: необязательная функция регуляризатора для вывода.
- kernel_constraint: необязательная проекционная функция, применяемая к ядру после обновления оптимизатором (например, для реализации нормальных ограничений или ограничений значений для весов слоев); эта функция должна принимать в качестве входных данных непроецированные переменные и должна возвращать проецируемые переменные (должны иметь одинаковые shape); небезопасно использовать ограничения при выполнении асинхронного распределенного обучения.
- bias_constraint: необязательная проекционная функция, применяемая к смещению после обновления оптимизатором.
пример
def get_model():
inputs = Input(shape=(64, 64, 3))
conv_1 = Conv2D(1, (3, 3), strides=(1, 1), padding='same')(inputs)
act_1 = Activation('relu')(conv_1)
conv_2 = Conv2D(64, (3, 3), strides=(1, 1), padding='same')(act_1)
act_2 = Activation('relu')(conv_2)
deconv_1 = Conv2DTranspose(64, (3, 3), strides=(1, 1), padding='same')(act_2)
act_3 = Activation('relu')(deconv_1)
merge_1 = concatenate([act_3, act_1], axis=3)
deconv_2 = Conv2DTranspose(1, (3, 3), strides=(1, 1), padding='same')(merge_1)
act_4 = Activation('relu')(deconv_2)
model = Model(inputs=[inputs], outputs=[act_4])
model.compile(optimizer='adadelta', loss=dice_coef_loss, metrics=[dice_coef])
return model
Подробное объяснение параметров ConvTranspose2d в pytorch
class torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True)
инструкция
stride
: Управляет размером шага вычисления коэффициента корреляции.
dilation
: используется для управления расстоянием между точками ядра, подробно описанными вздесь
groups
: управляет связью между входом и выходом:group=1
, выход - это свертка всех входов;group=2
, что эквивалентно наличию двух сверточных слоев рядом друг с другом, каждый сверточный слой вычисляет половину входного канала и создает выход, который составляет половину выходного канала, а затем объединяет два выхода.
параметрkernel_size
,stride
,padding
,dilation
тип данных: может бытьint
Тип данных, в это время значения высоты и ширины свертки совпадают; это также может бытьtuple
массив (содержит дваint
тип данных), первыйint
представление данныхheight
стоимость второгоint
Данные типа представляют собой значение ширины.
Уведомление
Из-за размера ядра данные для последних столбцов ввода могут быть потеряны. Потому что вход и выход не полностью взаимосвязаны. Следовательно, пользователь может сделать соответствующее заполнение (padding
действовать).
параметр:
- in_channels(
int
) – количество каналов входного сигнала - out_channels(
int
) – количество каналов, полученных сверткой - kerner_size(
int
ortuple
) - размер ядра свертки - stride(
int
ortuple
,optional
) - шаг свертки - padding(
int
ortuple
,optional
) - количество слоев, чтобы добавить 0 к каждому ребру ввода - output_padding(
int
ortuple
,optional
) - количество слоев, чтобы добавить 0 к каждому краю вывода - dilation(
int
ortuple
,optional
) – расстояние между элементами ядра - groups(
int
,optional
) – количество заблокированных соединений с входных каналов на выходные каналы - bias(
bool
,optional
) - еслиbias=True
, добавить смещение
пример
Применение ConvTranspose2d в UNet:
import torch.nn as nn
import torch
from torch import autograd
#把常用的2个卷积操作简单封装下
class DoubleConv(nn.Module):
def __init__(self, in_ch, out_ch):
super(DoubleConv, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch), #添加了BN层
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True)
)
def forward(self, input):
return self.conv(input)
class Unet(nn.Module):
def __init__(self, in_ch, out_ch):
super(Unet, self).__init__()
self.conv1 = DoubleConv(in_ch, 64)
self.pool1 = nn.MaxPool2d(2)
self.conv2 = DoubleConv(64, 128)
self.pool2 = nn.MaxPool2d(2)
self.conv3 = DoubleConv(128, 256)
self.pool3 = nn.MaxPool2d(2)
self.conv4 = DoubleConv(256, 512)
self.pool4 = nn.MaxPool2d(2)
self.conv5 = DoubleConv(512, 1024)
# 逆卷积,也可以使用上采样(保证k=stride,stride即上采样倍数)
self.up6 = nn.ConvTranspose2d(1024, 512, 2, stride=2)
self.conv6 = DoubleConv(1024, 512)
self.up7 = nn.ConvTranspose2d(512, 256, 2, stride=2)
self.conv7 = DoubleConv(512, 256)
self.up8 = nn.ConvTranspose2d(256, 128, 2, stride=2)
self.conv8 = DoubleConv(256, 128)
self.up9 = nn.ConvTranspose2d(128, 64, 2, stride=2)
self.conv9 = DoubleConv(128, 64)
self.conv10 = nn.Conv2d(64, out_ch, 1)
def forward(self, x):
c1 = self.conv1(x)
p1 = self.pool1(c1)
c2 = self.conv2(p1)
p2 = self.pool2(c2)
c3 = self.conv3(p2)
p3 = self.pool3(c3)
c4 = self.conv4(p3)
p4 = self.pool4(c4)
c5 = self.conv5(p4)
up_6 = self.up6(c5)
merge6 = torch.cat([up_6, c4], dim=1)
c6 = self.conv6(merge6)
up_7 = self.up7(c6)
merge7 = torch.cat([up_7, c3], dim=1)
c7 = self.conv7(merge7)
up_8 = self.up8(c7)
merge8 = torch.cat([up_8, c2], dim=1)
c8 = self.conv8(merge8)
up_9 = self.up9(c8)
merge9 = torch.cat([up_9, c1], dim=1)
c9 = self.conv9(merge9)
c10 = self.conv10(c9)
out = nn.Sigmoid()(c10)
return out
недостаток
В сверхразрешении на основе CNN в последнем слое часто используются слои деконверсии с шагом> 1, что может вызвать шум шахматной доски. Как показано ниже
конкретная причина
Черная сетка вверху представляет собой определенный пиксель в исходном изображении, а белая — шаг в транспонированной свертке, который обычно заполнен 0. Следующий слой — это изображение, сгенерированное deconv. Видно, что когда шаг не может делить размер, появляется эффект шахматной доски (конечно, даже если он кратен, его нельзя полностью устранить).
Как этого избежать?
Общий алгоритм интерполяции (NN или билинейный) используется для того, чтобы сначала увеличить изображение до целевого разрешения, а затем использовать обычную конверсию для выполнения вычислений вместо слоя деконверсии.
окончательный эффект
Ссылаться на:
Шум шахматной доски, вызванный слоем деконволюции (транспонированная свертка) в глубоком обучении
блог my.cn на.com/sunny-li/afraid/…
Принцип ConvTranspose2d, как глубокая сеть выполняет повышающую дискретизацию?