Мы уже писали полносвязную сеть на Питоне своими руками. Давайте теперь поэкспериментируем с таким видом сети в библиотеке Keras. Как всегда будем работать с базой MNIST, распознавать рукописные цифры.
Однослойная сеть.

Давайте для разогрева создадим однослойную сеть . Число входящих нейронов 748 ( изображение цифр 28х28 пикселей), число выходящих 10 ( количество классификаторов от 0 до 9)
from keras.datasets import mnist
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense
import matplotlib.pyplot as plt
Загружаем данные и приводим их к значениям от 0 — 1.
(x_rain, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype("float32")
x_test = x_test.astype("float32")
# В базе для каждого пикселя хранится значение яркости от 0 до 255.
x_train /= 255
x_test /= 255
keras.utils.to_categorical(y, num_classes=None, dtype=’float32′) . Преобразует вектор класса (целые числа) в двоичную матрицу классов.
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
Создаем слой
model = Sequential()
model.add(Dense(output_dim=10, input_dim=784, activation='softmax'))
input_dim=784
— число входных нейронов слоя.output_dim=10
— число выходных нейронов.activation='softmax'
— функция активации.
Собираем модель сети:
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
loss='categorical_crossentropy'
— Функция потерь.optimizer='adam'
— Оптимизатор весов .
Запускаем обучение сети. Пройдемся по базе десять раз ( эпохи) .
history = model.fit(x_train, y_train, epochs=10, verbose=2, validation_data=(x_test, y_test))
x_train, y_train
— входные данные, картинка и ответepochs=10
— число эпох обучения (сколько раз сеть продеться по данным полностью)validation_data=(x_test, y_test)
— данные для тестирования сети.verbose=2
— одна строка за эпоху. Лог обучения.
Да, еще добавим всяких там графиков )
Метод
fit()
возвращает историю обучения.
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

Я удивлен, мы получили очень не плохой результат — 92.96 % точность распознавания. Вот так легко сделать нейросеть на Keras )))
Сеть с одним скрытым слоем. Перцептро́н, или персептрон.
Давайте добавим один скрытый слой и соберем модель классической полносвязной сети.

model = Sequential()
model.add(Dense(output_dim=350, input_dim=784, activation='relu'))
model.add(Dense(output_dim=10, activation='softmax'))
Скрытый слой у нас содержит 350 нейронов. Заметьте что нам не надо во вотром слое указывать число входящих связей, библиотека сама учитывает это в модели сети. Функция активации ReLu
(rectified linear unit) — это просто замена отрицательных элементов нулем f(x) = max(0, s)
. Softmax
— это обобщение логистической функции для многомерного случая. Функция преобразует вектор , полученные вектора представлены вещественным числом в интервале [0,1] и сумма координат равна 1.
Посмотреть структуру сети можно методом:
print(model.summary())

Сразу видно, сеть работает намного лучше . Есть даже эффект переобучения. То есть последующие этапы обучения уже начинают ухудшать результат.

Давайте попробуем еще функцию активации Сигмоиду :
model = Sequential()
model.add(Dense(output_dim=350, input_dim=784, activation='sigmoid'))
model.add(Dense(output_dim=10, activation='softmax'))

Добавим еще слой с 200 нейронами, получиться сеть с двумя скрытыми слоями.
model = Sequential()
model.add(Dense(output_dim=350, input_dim=784, activation='sigmoid'))
model.add(Dense(output_dim=200, activation='sigmoid'))
model.add(Dense(output_dim=10, activation='softmax'))

Для борьбы с переобучение сети можно попробовать добавить слой Dropout(). Dropout (в русскоязычных источниках — “метод прореживания”, “метод исключения” или просто “дропаут”). Сети для обучения получаются с помощью исключения из сети (dropping out) нейронов с вероятностью p, таким образом, вероятность того, что нейрон останется в сети, составляет q=1−p. “Исключение” нейрона означает, что при любых входных данных или параметрах он возвращает 0.
model = Sequential()
model.add(Dense(output_dim=350, input_dim=784, activation='sigmoid'))
model.add(Dropout(rate=0.2))
model.add(Dense(output_dim=200, activation='sigmoid'))
model.add(Dense(output_dim=10, activation='softmax'))
Явно дропаут пошел на пользу )))

Безуспешно пытаюсь понять как работать с keras, sklearn один и тот же датасет удачно обрабатывает, а с этой библиотекай ни как не могу поднять до 100 процентов, вот например https://colab.research.google.com/drive/1_JT83JRLLDT0jG2ObrrFUj2EjKSVdzx5?usp=sharing
С sklearn к сожалению не сталкивался. На сколько я читал, нейросеть не может достичь 100% точности ( во всяком случае на тестовых данных). Если брать градиентный спуск, он стремиться к 0, но некогда не даст 0 ошибки или как то так. Какую бы вы не взяли функцию ошибки, она будет стремиться минимизации ошибки, но не достигнет 0. Я не силен в математике.
P.s. Нашел тут данные, на обучающем наборе можно набрать accuracy
1, но ошибка все равно будет не 0. https://arxiv.org/pdf/1805.01890.pdf . Попробуйте увеличить число эпох или сделать больше нейронов в сети.