nn-report/chapters/02_choose.tex

99 lines
6.0 KiB
TeX
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\chapter*{Выбор архитектуры нейронной сети}
\addcontentsline{toc}{chapter}{Выбор архитектуры нейронной сети} % Добавляем введение в оглавление
\section{Super Resolution Convolutional Neural Network (SRCNN)}
Использование сверточных нейронных сетей для данной работы является стандартом, поэтому и начать стоит с нее. Super Resolution Convolutional Neural Network\cite{DongLHT15} является одним из популярных решений для данной задачи. Архитектура сверточной нейронной сети (рис. \ref{fig:screenshot001})представлена в виде 3 слоев, входного слоя с 3 входами для каждого цвета и 64 фичами, после которых идет один скрытый сверточный слой и один выходной слой. В данном случае, первый слой извлекает набор фич из изображения, в то время, как второй слой нелинейно размечает данные фичи на патчи с высоким разрешением, а последний слой комбинирует предсказания с оценкой окружающих патчей и отдает на выход изображение с повышенным разрешением.
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\linewidth]{screenshot001}
\caption{Архитектура нейронной сети SRCNN \cite{DongLHT15}}
\label{fig:screenshot001}
\end{figure}
Стоит отметить, что в данной архитектуре входное изображение уже должно быть нужного разрешения, увеличивая вычислительную сложность нейронной сети. Что является потенциальным решающим фактором в пользу более продвинутых реализаций методов повышения разрешения.
\begin{lstlisting}[
style=compactpython,
caption=Протестированная реализация SRCNN,
label={lst:SRCNN}
]
class SimpleSuperResolutionNet(nn.Module):
def __init__(self, kernel_size=3, n_feats=64, colors=3):
super(SimpleSuperResolutionNet, self).__init__()
self.conv = nn.Conv2d(
colors, n_feats, kernel_size=kernel_size, padding=kernel_size//2)
half_feats = n_feats//2
self.conv2 = nn.Conv2d(
n_feats, half_feats, kernel_size=kernel_size, padding=kernel_size//2)
self.conv3 = nn.Conv2d(
half_feats, colors, kernel_size=kernel_size, padding=kernel_size//2)
def forward(self, x):
x = torch.relu(self.conv(x))
x = torch.relu(self.conv2(x))
x = self.conv3(x)
return x
\end{lstlisting}
Можно увидеть в листинге \ref{lst:SRCNN}, что размер ядра был выбран отличным от представленных в работе, связано это с тем, что при обучении на наших тестовых данных, одинаковое ядро показало лучшие результаты, в сравнении с оригинальными.
\section{Fast Super Resolution Convolutional Neural Network (FSRCNN)}
sdada
\section{Enhanced Deep Super Resolution (EDSR)}
Некоторым продвижением в задаче повышения разрешения можно считать применение в сверточных нейронных сетях остаточных блоков.\cite{he2016deep} В ключевой реализации \cite{LimSKNL17} была предложена архитектура состоящая из большого количества скрытых остаточных блоков (рис. \ref{fig:resblockedsr}), после начального входного слоя.
% TODO: \usepackage{graphicx} required
\begin{figure}[h!]
\centering
\includegraphics[width=0.2\linewidth]{res_block_edsr}
\caption[Структура остаточного блока в сети EDSR]{}
\label{fig:resblockedsr}
\end{figure}
В отличии от стандартных остаточных блоков, использованных в ResNet \cite{HeZRS15}, в EDSR из остаточного блока удален блок пакетной нормализации, так как данный блок может быть нежелательным в данной задаче
% TODO: \usepackage{graphicx} required
\begin{figure}[h!]
\centering
\includegraphics[width=0.6\linewidth]{edsr_arch}
\caption[Архитектура нейронной сети EDSR \cite{LimSKNL17}]{}
\label{fig:edsrarch}
\end{figure}
Были проверены две реализации: "state-of-the-art", предоставленная авторами статьи, уже предобученная модель, а также своя реализация по образу и подобию предоставленной авторами.
Сеть состояла из 8 остаточных блоков, в каждом из которых было по 64 фичи, с ядром размера 3х3, и значением множителя 0.1
\begin{lstlisting}[
style=compactpython,
caption=Структура остаточного блока,
label={lst:ResBlock}
]
class ResidualBlock(nn.Module):
def __init__(self, n_feats, kernel_size, bias=True, bn=False, act=nn.ReLU(True), res_scale=1.0):
super(ResidualBlock, self).__init__()
m = []
for i in range(2):
m.append(nn.Conv2d(n_feats, n_feats, kernel_size,
padding=(kernel_size//2), bias=bias))
if bn:
m.append(nn.BatchNorm2d(n_feats))
if i == 0:
m.append(act)
self.body = nn.Sequential(*m)
self.res_scale = res_scale
def forward(self, x):
res = self.body(x).mul(self.res_scale)
res += x
return res
\end{lstlisting}