Реализована двухслойная полносвязная нейронная сеть для распознавания цифр из базы MNIST.
Входной слой - изображение из базы MNIST
Скрытый слой - функция активации ReLU
Выходной слой - функция активации Softmax
Функция ошибки - кросс-энтропия
Математическая модель нейрона имеет следующий вид:
Где - функция активации, - смещение, - вес, - вход.
Для удобства выкладок сделаем некоторое преобразование. Внесем смещение в сумму с новым значением синапса . Тогда модель нейрона можно записать в следующем виде:
Входные данные нормируются, представляются как матрицы и вектора.
Инициализация весов осуществляется с использованием метода Ксавье.
На скрытом слое будем использовать ReLU:
На выходе будем использовать функцию Softmax:
Её производные:
В качестве функции ошибки рассмотрим кросс-энтропию:
Где y - выход сети, u - ожидаемый выход, v - выход скрытого слоя, x - вход сети, M - число нейронов на выходном слое, K - число нейронов на скрытом слое, N - число нейронов на входе сети, - веса выходного слоя, - веса скрытого слоя.
Первый множитель - это производная Softmax по аргументу. Она может принимать два значения, это зависит от слагаемого, по которому мы берем производную. Если он в числителе: . Если в знаменателе: .
Вынесем из суммы слагаемое, которое соответствует производной по числителю Softmax. Учтем, что .
Отлично, мы нашли производную функции ошибки по выходному слою.
Второй множитель - производная ReLU.
Нашли производную функции ошибки по скрытому слою.
На вход принимаем нормированные изображения в форме вектора. Для каждого нейрона скрытого слоя вычисляем взвешенную сумму по всем входным нейронам и вычисляем функцию активации ReLU.
После этого результат работы скрытого слоя умножаем на веса и пропускаем через функцию активации Softmax.
Выходной слой даёт вектор значений достоверности.
- Прямой проход по сети
Сеть обучается заданное число эпох. Эпоха - полный проход по тестовой выборке. Внутри эпохи набор тестовых данных делится на пакеты.
- Инициализация весов
- Каждую эпоху
- Перемешиваем выборку
- Делим выборку на пакеты и для каждого пакета
- Коррекция весов по алгоритму обратного распространения
tensorflow - основа для Keras
keras - фреймворк для сравнения реализаций
numpy - для работы с векторами и матрицами
datetime - для замера времени работы
Функции для чтения данных MNIST из пакета keras и нормировки данных.
get_MNIST_Keras - вернет матрично-векторные данных MNIST normalized_MNIST - нормирует данные
Содержит реализацию аналогичной сети, но средствами фреймворка.
fit_and_test_net_on_MNIST(hidden_size, batch_size, num_epochs, lr) - обучает сеть по заданным параметрам, собирает метрики
Содержит собственную реализацию сети.
Класс NeuralNetwork - реализация сети.
- forward(X) - прямое распространение со входом Х
- predict(X, Y) - прямое распространение со входом Х, считает функцию потерь по Y
- fit(X, Y, batch_size, number_epochs) - тренировка сети с заданными параметрами
fit_and_test_net_on_MNIST(hidden_size, batch_size, num_epochs, lr) - - обучает сеть по заданным параметрам, собирает метрики
Парсит аргументы командной строки, запускает нужную сеть или сравнивает их.
Параметры скрипта:
- net_type - выбор реализации сети для запуска: 'my', 'keras'
- hidden_size - число узлов на скрытом слое
- lr - скорость обучения
- batch_size - размер пачки
- number_epochs - число эпох
- compare_nets - флаг для сравнения двух реализаций на указанных параметрах
Пример командной строки для запуска:
python main.py --net_type my --hidden_size 256 --lr 0.1 --batch_size 128 --number_epochs 20 --compare_nets
Была реализована полносвязная двухслойная нейронная сеть с алгоритмом обратного распространения ошибки. Реализация сравнивалась с аналогичной сетью из фреймворка Keras.
- hidden_size = 30
- lr = 0.1
- batch_size = 128
- number_epochs = 20
Командная строка:
python main.py --net_type my --hidden_size 30 --lr 0.1 --batch_size 128 --number_epochs 20 --compare_nets
Time(s) | Test accuracy(%) | Test loss | Train accuracy(%) | Train loss | |
---|---|---|---|---|---|
my_net | 25.023557 | 0.9648 | 0.122476 | 0.974233 | 0.090380 |
keras_net | 20.960236 | 0.965699 | 0.114408 | 0.975350 | 0.086029 |
- hidden_size = 128
- lr = 0.1
- batch_size = 128
- number_epochs = 20
Командная строка:
python main.py --net_type my --hidden_size 128 --lr 0.1 --batch_size 128 --number_epochs 20 --compare_nets
Time(s) | Test accuracy(%) | Test loss | Train accuracy(%) | Train loss | |
---|---|---|---|---|---|
my_net | 41.901075 | 0.9756 | 0.078803 | 0.988916 | 0.044473 |
keras_net | 26.540353 | 0.976100 | 0.077987 | 0.988150 | 0.046889 |
- hidden_size = 256
- lr = 0.1
- batch_size = 128
- number_epochs = 20
Командная строка:
python main.py --net_type my --hidden_size 256 --lr 0.1 --batch_size 128 --number_epochs 20 --compare_nets
Time(s) | Test accuracy(%) | Test loss | Train accuracy(%) | Train loss | |
---|---|---|---|---|---|
my_net | 64.535192 | 0.978000 | 0.071693 | 0.991483 | 0.036636 |
keras_net | 33.041822 | 0.976999 | 0.075315 | 0.989810 | 0.041615 |
- hidden_size = 300
- lr = 0.1
- batch_size = 128
- number_epochs = 20
Командная строка:
python main.py --net_type my --hidden_size 300 --lr 0.1 --batch_size 128 --number_epochs 20 --compare_nets
Time(s) | Test accuracy(%) | Test loss | Train accuracy(%) | Train loss | |
---|---|---|---|---|---|
my_net | 107.717036 | 0.978200 | 0.070821 | 0.992 | 0.036216 |
keras_net | 40.644219 | 0.978299 | 0.072413 | 0.990450 | 0.040741 |