# Учебный проект, посвященный сжатию изображений при помощи нейронных сетей

Данный простой кодек сжимает изображения размером 128x128 при помощи свёрточных нейронных сетей, квантования и адаптивного арифметического кодирования.
В папке ./train/ находятся изображения, которые были использованы для обучения сети, в папке ./test/ находятся изображения для демонстрации результатов.

Структура кодера:
1. Слой 1. Принимает x размером 128x128x3. Выполняет свёртку 7x7, ReLu, MaxPooling2D 2x2. На выходе вектор y1 размером 64x64x128.
2. Слой 2. Принимает y1. Выполняет свёртку 5x5, ReLu, MaxPooling2D 2x2. На выходе вектор y2 размером 32x32x32.
3. Слой 3. Принимает y2. Выполняет свёртку 3x3, ReLu, MaxPooling2D 2x2. На выходе вектор y3 размером 16x16x16.
4. Вычисление максимума y_{max} = \max_i{y^i_3}.
5. Квантование x_i = \left\lfloor clip(y^i_3/y_{max},[0,1))\cdot 2^b\right\rfloor, в результате которого x_i \in \{0,1,...,2^{b}-1\}.
6. Сжатие {x_i} при помощи адаптивного арифметического кодера (ААК) из [1].

Структура декодера:
1. Декодирование {x_i} при помощи АAК из [1].
2. \hat y^i_3 = y_{max}\cdot\left(\frac{x_i}{2^{b}}+\frac{1}{2^{b+1}}\right)
3. Слой 1. Принимает \hat y_3. Свёртка 3\times 3, ReLu. На выходе  \hat y_2 размером 32x32x16.
4. Слой 2. Принимает \hat y_2. Свёртка 5\times 5, ReLu. На выходе  \hat y_1 размером 64x64x32.
4. Слой 3. Принимает \hat y_1. Свёртка 7\times 7, ReLu. На выходе  изображение \hat x размером 128x128x3.

На следующем примере показан случай, когда при обучении к вектору y_3 не прибавляется шум, соразмерный квантованию с шагом 2^3. Как можно заметить, это приводит
к появлению артефактов.
![Обучения без добавления шума. Epoch=3000](./doc/AI_Epoch3000_NoNoise.png)

На следующем примере показан случай, когда при обучении к вектору y_3 добавляется шум, соразмерный квантованию с шагом 2^3. Как можно заметить, в большей степени 
артефакты устранились, что привело к тому, что данная простейшая модель выигрывает у JPEG по качеству на высоких степенях сжатия.
![Обучения c добавлением шума. Epoch=3000](./doc/AI_Epoch3000_Noisebt3.png)

ААК из [1] реализован на языке Си и подключается к коду как библиотека. Для сборки модуля необходимо выполнить команды, которые находятся в файле
EntropyCompile.bat

[1] Ian H. Witten, Radford M. Neal, and John G. Cleary, “Arithmetic coding for data compression,” Commun. ACM, vol. 30, no. 6, pp. 520–540, jun
1987.