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

## Описание работы кодека
Данный простой кодек сжимает изображения размером 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

## Описание задания к лабораторной работе
Улучшить учебный кодек так, чтобы он:
- либо на том же сжатии показывал лучшее субъективное визуальное качество; 
- либо на том же сжатии обеспечивал выигрыш по PSNR от 0.1 дБ и выше;
- либо при том же уровне качества обеспечивал от 3\% выигрыша по bpp.

Можно улучшать следующие модули:
- Арифметический кодер (учесть возможную память источника, оценка вероятностей); 
- Квантование (векторное квантование, использовать другую модель шума при обучении и т.д.);
- Нейронная сеть (количество слоёв, функции активации, связи между слоями и т.д.).

Требования к реализации:
- Результаты должны быть продемонстрированы на изображениях из папки ./test/
- При обучении должны использоваться только изображения из папки ./train/

На почту eabelyaev@itmo.ru прислать отчет в виде презентации в pdf формате, который включает в себя:
- ФИО студента, номер группы.
- Описание предложенной модификации и результаты.
- Ссылку на репозиторий с исходным кодом кодека и инструкцию по запуску.

## Литература
[1] Ian H. Witten, Radford M. Neal, and John G. Cleary, “Arithmetic coding for data compression,” Commun. ACM, 1987.