Проект состоит из нескольких частей - RESTful сервер для взаимодействия с нейронными сетями, нейронная сеть LeNet и простой клиент для общения с сервером и его тестирования.
Полный список всех необходимых для работы пакетов:
- Для Python3.5: decorator, Flask v1.0.2, Flask-HTTPAuth v3.2.4, gevent v1.3.7, h5py, Keras v2.2.4, numpy, pillow, requests, tensorflow[-gpu].
- Для Ubuntu: python3.5-dev, python3-pip, python3-tk, net-tools.
Если вы используете Ubuntu 16.04 или выше, для установки всех пакетов можно воспользоваться install_packages.sh
(проверено в Ubuntu 16.04). По умолчанию будет установлен TensorFlow для CPU. Если у вас есть видеокарта nvidia, вы можете установить TensorFlowGPU. Для этого необходимо при запуске install_packages.sh
передать параметр gpu
. Например:
./install_packages.sh gpu
Docker-образ
Вы так же можете собрать docker-образ моего проекта с помощью Dockerfile либо загрузить уже собранный образ из моего Google Drive.
Установка Docker и сборка образа
Если вы используете Ubuntu 16.04 или выше, для установки docker-engine можно воспользоваться install_docker.sh
. После установки, проверьте статус docker с помощью команды:
sudo systemctl status docker
Результат должен быть примерно такой:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Чцв 2018-11-22 03:01:32 +03; 14h ago
Docs: https://docs.docker.com
Main PID: 1183 (dockerd)
Tasks: 24
Memory: 349.8M
CPU: 2min 3.238s
CGroup: /system.slice/docker.service
├─1183 /usr/bin/dockerd -H fd://
└─1220 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0
Затем вам необходимо в терминале перейти в папку, куда вы клонировали данный репозиторий (или скачали и распаковали его) и выполнить:
sudo docker build -t nn_server:v0.1 .
Где -t
- запуск терминала, .
- директория, из которой вызывается docker build
(точка - значит в текущей директории находятся все файлы для образа), nn_server:v0.1
- метка образа и его версия.
После успешного выполнения данной операции вы можете вывести список имеющихся образов, выполнив:
sudo docker images
В полученном списке вы увидите наш образ - nn_server:v0.1
.
Запуск docker-образа
Если вы загрузили уже собранный образ из моего Google Drive, то перед запуском вам необходимо его сначала распаковать. Это можно сделать так (находясь в папке со скачанным .tar архивом):
sudo docker load < nn_server.tar
или
sudo docker load --input nn_server.tar
Убедиться в том, что образ успешно распакован, вы можете выполнив sudo docker images
.
Теперь образ готов к запуску. Для этого необходимо выполнить:
sudo docker run -ti --rm -p 5000:5000 nn_server:v0.1 python3 nn_server.py
Где -t
- запуск терминала, -i
- интерактивный режим, --rm
- удалить контейнер после завершения его работы, -p 5000:5000
- пробросить все подключения на порт 5000
к машине-хосту в контейнер на порт 5000
(вы так же можете явно указать другой адрес, к которому нужно будет подключиться извне: -p 127.0.0.1:5000:5000
).
В результате запустится RESTful-сервер и можно к нему обращаться по указанному в терминале адресу (если вы не указали другой при запуске образа).
Данный сервер предоставляет REST-api для взаимодействия с нейронными сетями. На данный момент имеется только одна сеть - LeNet для классификации рукописных цифр.
Сервер реализован с помощью Flask, а многопоточный режим (production-версия) с помощью gevent.pywsgi.WSGIServer. Также сервер имеет ограничение на размер принимаемых данных в теле запроса равное 16 Мб. Реализация находится в модуле nn_server.py
.
Запустить WSGI сервер можно выполнив run_nn_server.sh
(запуск без аргументов командной строки) или python3 nn_server.py
.
Сервер поддерживает аргументы командной строки, которые немного упрощают его запуск. Аргументы имеют следующую структуру: [ключ(-и)] [адрес:порт]
.
Возможные ключи:
-d
- запуск тестового Flask сервера (если ключ не указывать - будет запущен WSGI сервер)-s
- запуск сервера с поддержкой https (используется самоподписанный сертификат, получен с помощью openssl)
Допустимые варианты адрес:порт
:
host:port
- запуск на указанномhost
иport
localaddr:port
- запуск с автоопределением адреса машины в локальной сети и указаннымport
host:0
илиlocaladdr:0
- еслиport = 0
, то будет выбран любой доступный порт автоматически
Список возможных комбинаций аргументов командной строки и их описание:
- без аргументов - запуск WSGI сервера с автоопределением адреса машины в локальной сети и портом
5000
. Например:python3 rest_server.py
host:port
- запуск WSGI сервера на указанномhost
иport
. Например:python3 nn_server.py 192.168.2.102:5000
-d
- запуск тестового Flask сервера на127.0.0.1:5000
. Например:python3 nn_server.py -d
-d host:port
- запуск тестового Flask сервера на указанномhost
иport
. Например:python3 nn_server.py -d 192.168.2.102:5000
-d localaddr:port
- запуск тестового Flask сервера с автоопределением адреса машины в локальной сети и портомport
. Например:python3 nn_server.py -d localaddr:5000
-s
- запуск WSGI сервера с поддержкой https, автоопределением адреса машины в локальной сети и портом5000
. Например:python3 nn_server.py -s
-s host:port
- запуск WSGI сервера с поддержкой https на указанномhost
иport
. Например:python3 nn_server.py -s 192.168.2.102:5000
-s -d
- запуск тестового Flask сервера с поддержкой https на127.0.0.1:5000
. Например:python3 nn_server.py -s -d
-s -d host:port
- запуск тестового Flask сервера с поддержкой https на указанномhost
иport
. Например:python3 nn_server.py -s -d 192.168.2.102:5000
-s -d localaddr:port
- запуск тестового Flask сервера с поддержкой https, автоопределением адреса машины в локальной сети и портомport
. Например:python3 nn_server.py -s -d localaddr:5000
Сервер может сам выбрать доступный порт, для этого нужно указать в host:port
или localaddr:port
порт 0
(например: python3 nn_server.py -d localaddr:0
).
Всего поддерживается 5 запросов:
- GET-запрос на
/list_nn
вернёт информацию об имеющихся нейронных сетях и их адресах - GET-запрос на
/lenet/about
вернёт информацию о сети LeNet - GET-запрос на
/lenet/train
запустит обучение сети в фоне (т.е. в отдельном потоке) на наборе рукописных цифр MNIST (передать в URL параметрtraining_sample=mnist
) или на предварительно созданном наборе данныхdata/training_sample.npz
(передать в URL параметрtraining_sample=other
) (после запуска, на запросы 3, 4 и 5 сервер будет отвечать ошибкой с пояснением, что сеть на данный момент обучается и недоступна для использования) - GET-запрос на
/lenet/train/status
вернёт последний результат обучения сети LeNet (точность классификации и дата последнего обучения) - POST-запрос на
/lenet/classify
принимает .jpg/.png/.bmp/.tiff файл и возвращает распознанную цифру в виде строки
Описание сервера
- Сервер имеет базовую http-авторизацию. Т.е. для получения доступа к серверу надо в каждом запросе добавить заголовок, содержащий логин:пароль, закодированный с помощью
base64
(логин:test_nn
, пароль:lenet
). Пример на python:
import requests
import base64
auth = base64.b64encode('test_nn:lenet'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
Выглядеть это будет так:
Authorization: Basic dGVzdF9ubjpsZW5ldA==
- В запросе на запуск обучения сети (который под номером 3) сервер ожидает параметр
training_sample
в URL запроса. Данный параметр определят используемую обучающую выборку:training_sample=mnist
- использовать в качестве обучающей выборки набор рукописных цифр MNIST,training_sample=other
- использовать предварительно созданную обучающую выборкуdata/training_sample.npz
из своих данных (с помощьюlenet.py -c
). Пример на python:
# Отправка запроса серверу
response = requests.post('http://' + addr + '/lenet/train?training_sample=mnist', headers=headers, json=data)
# Разбор ответа
data = response.json()
number = data.get('number')
print(number)
- В запросе на классификацию (который под номером 5) сервер ожидает .jpg/.png/.bmp/.tiff файл (цветной либо чёрно-белый, размером от 28х28 пикселей) с изображением рукописной цифры (цифра должна быть на светлом (в идеале - белом) фоне, примеры можно найти в
images/*.jpg
), который передаётся в json с помощью кодировкиbase64
(т.е. открывается .jpg/.png/.bmp/.tiff файл, читается в массив байт, потом кодирутесяbase64
, полученный массив декодируется из байтовой формы в строкуutf-8
и помещается в json), в python это выглядит так:
# Формирование запроса
auth = base64.b64encode('test_nn:lenet'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
with open('images/1.jpg', 'rb') as f_image:
img_data = f_image.read()
data = base64.b64encode(data)
data = {'image' : data.decode()}
# Отправка запроса серверу
response = requests.post('http://' + addr + '/lenet/classify', headers=headers, json=data)
# Разбор ответа
data = response.json()
number = data.get('number')
print(number)
Передаваемые данные в каждом запросе
Все передаваемые данные обёрнуты в json (в том числе и ответы с ошибками).
- Сервер передаёт клиенту:
{
'text' : ['LeNet url:/lenet',
'Сеть1 url:/сеть1',
'Сеть2 url:/сеть2']
}
- Сервер передаёт клиенту:
{
'text' : 'Описание сети LeNet'
}
- Сервер передаёт клиенту:
{
'text' : 'Запущено обучение сети.'
}
- Сервер передаёт клиенту:
{
'accuracy' : '99.32',
'datetime' : '2018-11-21 17:39:08'
}
- Клиент в теле запроса должен отправить:
{
'image' : '/9j/4AAQSkZJRgABAQE...'
}
Сервер ему передаст:
{
'number' : '1'
}
В случае возникновения ошибки, сервер передаст клиенту, например (код ответа 401):
{
'error': 'Unauthorized access.'
}
Переопределены следующие коды ответов: 400, 401, 404, 405, 406, 415, 500.
Примеры запросов
- GET-запрос на
/list_nn
Пример запроса, который формирует python-requests
:
GET /list_nn HTTP/1.1
Host: 192.168.2.83:5000
Connection: keep-alive
Accept-Encoding: gzip, deflate
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: python-requests/2.9.1
Пример запроса, который формирует curl (curl -v -u test_nn:lenet -i http://192.168.2.83:5000/list_nn
):
GET /list_nn HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: curl/7.47.0
В обоих случаях сервер ответил:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 21 Nov 2018 15:13:21 GMT
{
'text' : ['LeNet url:/lenet',
'Сеть1 url:/сеть1',
'Сеть2 url:/сеть2']
}
- GET-запрос на
/lenet/about
Пример запроса, который формирует python-requests
:
GET /lenet/about HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: python-requests/2.9.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Пример запроса, который формирует curl (curl -v -u test_nn:lenet -i http://192.168.2.83:5000/lenet/about
):
GET /lenet/about HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: curl/7.47.0
В обоих случаях сервер ответил:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 21 Nov 2018 15:43:06 GMT
{
'text' : 'Описание сети LeNet'
}
- GET-запрос на
/lenet/train
Пример запроса, который формирует python-requests
:
GET /lenet/train?training_sample=mnist HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: python-requests/2.9.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Пример запроса, который формирует curl (curl -v -u test_nn:lenet -i http://192.168.2.83:5000/lenet/train?training_sample=other
):
GET /lenet/train?training_sample=other HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: curl/7.47.0
В обоих случаях сервер ответил:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 21 Nov 2018 15:43:06 GMT
{
'text' : 'Запущено обучение сети.'
}
- GET-запрос на
/lenet/train/status
Пример запроса, который формирует python-requests
:
GET /lenet/train/status HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: python-requests/2.9.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Пример запроса, который формирует curl (curl -v -u test_nn:lenet -i http://192.168.2.83:5000/lenet/train/status
):
GET /lenet/train/status HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdF9ubjpsZW5ldA==
User-Agent: curl/7.47.0
В обоих случаях сервер ответил:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 21 Nov 2018 15:43:06 GMT
{
'accuracy' : '99.32',
'datetime' : '2018-11-21 17:39:08'
}
- POST-запрос на
/lenet/classify
Пример запроса, который формирует python-requests
:
POST /lenet/classify HTTP/1.1
Host: 192.168.2.83:5000
User-Agent: python-requests/2.9.1
Accept: */*
Content-Length: 10739
Connection: keep-alive
Content-Type: application/json
Authorization: Basic dGVzdGJvdDp0ZXN0
Accept-Encoding: gzip, deflate
{
'image' : '/9j/4AAQSkZJRgABAQE...'
}
Пример запроса, который формирует curl (curl -v -u test_nn:lenet -i -H "Content-Type: application/json" -X POST -d '{'image' : '/9j/4AAQSkZJRgABAQE...'}' http://192.168.2.83:5000/lenet/classify
):
POST /lenet/classify HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 10739
{
'image' : '/9j/4AAQSkZJRgABAQE...'
}
Сервер ответил:
HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json
{
'number' : '1'
}
Сеть LeNet - это свёрточная нейронная сеть (convolutional neural network, CNN), была представлена в 1998 году французским исследователем Яном Лекуном (Yann LeCun) для решения задачи классификации изображений (так же может использоваться для распознавания звуковых образов и др.). Данная модель сети состоит из трёх типов слоёв: свёрточные (convolutional) слои, субдискретизирующие (subsampling, подвыборка) слои и слои "обычной" нейронной сети – перцептрона.
Первые два типа слоёв (convolutional и subsampling), чередуясь между собой, формируют входной вектор признаков для многослойного перцептрона.
Свёрточный слой реализует идею так называемых локальных рецептивных полей, т.е. каждый выходной нейрон соединен только с определённой (небольшой) областью входной матрицы и таким образом моделирует некоторые особенности человеческого зрения. Своё название свёрточная сеть получила по названию операции – свёртка, она часто используется для обработки изображений. Неформально эту операцию можно описать следующим образом – окном размера ядра g (например, 5х5) проходим с заданным шагом (обычно 1) всё изображение, на каждом шаге поэлементно умножаем содержимое окна на ядро g, результат суммируется и записывается в матрицу результата. При этом в зависимости от метода обработки краёв исходной матрицы результат может быть меньше исходного изображения (valid), такого же размера (same) или большего размера (full).
Субдискретизирующие (subsampling) слои выполняют уменьшение размера входной карты признаков (обычно в 2 раза). Это можно делать разными способами, в данной реализации используется метод выбора максимального элемента (max-pooling) - вся карта признаков разделяется на ячейки 2х2 элемента, из которых выбираются максимальные по значению. Использование этого слоя позволяет улучшить распознавание образцов с изменённым масштабом (уменьшенных или увеличенных).
В моей реализации, сеть LeNet используется для классификации рукописных цифр. В текущем варианте обучена на наборе данных MNIST. Cостоит из 7 слоёв:
- Входной слой: матрица изображения
- Слой свертки: 75 карт признаков, ядро свертки 5х5, функция активации
ReLU
- Слой подвыборки (субдискретизации): размер окна 2х2, метод наибольшего значения
- Слой свертки: 100 карт признаков, ядро свертки 5х5, функция активации
ReLU
- Слой подвыборки (субдискретизации): размер пула 2х2, метод наибольшего значения
- Полносвязный слой: 500 нейронов, преобразует двумерный результат работы сети в одномерный, функция активации
ReLU
- Полносвязный выходной слой: 10 нейронов, которые соответствуют классам рукописных цифр от 0 до 9, функция активации
SoftMax
При обучении ипользовался оптимизаторadam
и метод вычисления значения функции потериcategorical_crossentropy
. Проблема переобучения решается с помощью промежуточных слоёвDropout
. Точность классификации после 10 эпох обучения варьируется от 99.3% до 99.7%.
Реализация находится в модуле lenet.py
. Он представляет собой класс LeNet
с тремя public-методами: train()
, classify()
и create_training_sample()
. Модель обученной сети и её веса находятся в data/lenet_model.json
и data/lenet_weights.h5
. Набор данных для обучения - в data/mnist.npz
и/или data/training_sample.npz
.
Так же данный класс поддерживает создание обучающей выборки на основе любых изображений цифр. Реализация находится в методе create_training_sample()
.
Изображения должны быть в формате .jpg/.png/.bmp/.tiff, цветные и/или чёрно-белые, размером от 28х28 пикселей. На одном изображении может быть только одна цифра на светлом (в идеале - белом) фоне (примеры можно найти в images/*.jpg
). Каждое изображение в своём имени должно содержать метку класса (т.е. цифру, которая на изображении; метка определяется по первому символу в названии). Например: 0_1399.jpg
- на изображении цифра 0; 7_81491.jpg
- на изображении цифра 7.
При создании обучающей выборки над каждым изображением выполняются следующие преобразования (которые так же выполняются для изображения, которое передаётся в параметрах методу classify()
):
- конвертирование в чёрно-белое;
- обрезание всех светлых/белых рамок/полос так, что бы цифра занимала полностью всё изображение;
- выранивание длины и ширины (по максимальному из них);
- добавление белой рамки шириной 3 пикселя;
- уменьшение размера до 28х28 пикселей (как у изображений из набора данных MNIST)
- инвертирование цвета.
Для удобства создания своей обучающей выборки, модуль lenet.py
поддерживает аргументы командной строки (так же вы можете просто импортировать его в свой код на python и легко использовать). Список возможных комбинаций аргументов командной строки и их описание:
- без аргументов - запуск обучения сети на обучающей выборке MNIST. Например:
python3 lenet.py
training_sample.npz
- запуск обучения сети на обучающей выборкеtraining_sample.npz
. Например:python3 lenet.py data/training_sample.npz
-c
- создать обучающую выборку на основе изображений изdata/source_images
. Например:python3 lenet.py -c
-c my_data/images
- создать обучающую выборку на основе изображений изmy_data/images
. Например:python3 lenet.py -c my_data/images
-c training_sample.npz
- создать обучающую выборку на основе изображений изdata/source_images
и сохранить вtraining_sample.npz
. Например:python3 lenet.py -c training_sample.npz
-c my_data/images training_sample.npz
- создать обучающую выборку на основе изображений изmy_data/images
и сохранить вtraining_sample.npz
. Например:python3 lenet.py -c my_data/images training_sample.npz
Это простой клиент, использующий пакет requests для отправки запросов серверу и получения ответов. Для своей работы требует только установленного python3 и пакета requests. Если вы используете Ubuntu 16.04 или выше, для установки этих пакетов можно воспользоваться install_packages_client.sh
(он будет полезен, если вы запускаете сервер из docker-образа или на другом копьютере, что бы не устанавливать полный набор пакетов, которые требует сервер). Реализация находится в модуле nn_client.py
.
Данный клиент можно использовать двумя способами:
- Как самостоятельное консольное приложение.
- В составе другого приложения из кода python.
Использование клиента как самостоятельное консольное приложение
В этом варианте клиент можно запустить, выполнив в терминале python3 nn_client.py
и после этого выбрав нужный пункт из предложенного меню. Так же клиент поддерживает аргументы командной строки. Они имеют следующую структуру:
[host:port] [имя_сети операция_над_сетью]
Возможные значения аргумента имя_сети
:
list_nn
- получить список имеющихся нейронных сетей и их адресаlenet
- использовать сеть LeNet, которая предназначена для классификации рукописных цифр
Возможные значения аргумента операция_над_сетью
:
classify
- классифирует изображение (или другой объект, в случае появления новых нейронных сетей в составе сервера), если сеть это поддерживаетstatus
- получить статус сети (точность работы и дату последнего обучения)about
- получить информацию о сетиtrain
- запустить обучение сети (при этом на большинство запросов к этой сети сервер будет отвечать ошибкой, что сеть на данный момент недоступна, пока не закончится процесс обучения)
Список возможных комбинаций аргументов командной строки и их описание:
- без аргументов - запуск с автоопределением адреса машины в локальной сети и портом
5000
. Например:python3 nn_client.py
host:port
- запуск с подключением к указанномуhost
иport
. Например:python3 nn_client.py 192.168.2.102:5000
host:port list_nn
- получить список имеющихся нейронных сетей и их адреса. Например:python3 nn_client.py 192.168.2.102:5000 list_nn
host:port lenet classify
- классифицировать изображение с цифрой с помощью сети LeNet (будет предложено выбрать цифру из каталогаimages
). Например:python3 nn_client.py 192.168.2.102:5000 lenet classify
host:port lenet classify image.jpg
- классифицировать изображение из файлаimage.jpg/.png/.bmp/.tiff
с помощью сети LeNet. Например:python3 nn_client.py 192.168.2.102:5000 lenet classify my_folder/my_number.jpg
host:port lenet status
- получить статус сети LeNet. Например:python3 nn_client.py 192.168.2.102:5000 lenet status
host:port lenet about
- получить информацию о сети LeNet. Например:python3 nn_client.py 192.168.2.102:5000 lenet status
host:port lenet train
- запустить обучение сети LeNet на наборе данных MNIST. Например:python3 nn_client.py 192.168.2.102:5000 lenet train
host:port lenet train other
- запустить обучение сети LeNet на предварительно созданном наборе данных. Например:python3 nn_client.py 192.168.2.102:5000 lenet train other
list_nn
- получить список имеющихся нейронных сетей и их адреса. Например:python3 nn_client.py list_nn
lenet classify
- классифицировать изображение с цифрой с помощью сети LeNet (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet classify
lenet classify image.jpg
- классифицироватьimage.jpg/.png/.bmp/.tiff
с помощью сети LeNet (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet classify my_folder/my_number.jpg
lenet status
- получить статус сети LeNet (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet status
lenet about
- получить информацию о сети LeNet (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet about
lenet train
- запустить обучение сети LeNet на наборе данных MNIST (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet train
lenet train other
- запустить обучение сети LeNet на предварительно созданном наборе данных (host
определяется автоматически,port = 5000
). Например:python3 nn_client.py lenet train other
Использование клиента в составе другого приложения из кода python
Для этого необходимо импортировать из модуля nn_client.py
функцию access_to_nn_server()
и вызвать её из своего кода в необходимом месте. Функция имеет вид:
access_to_nn_server(host, port, name_nn, type_operation, login=None, password=None, https=False, data=None)
Описание аргументов:
host
- адрес хоста сервераport
- порт сервераname_nn
- имя запрашиваемой нейронной сетиtype_operation
- тип операции над сетьюlogin
- логин для подключения к серверу (если не задавать, используетсяtest_nn
)password
- пароль для подключения к серверу (если не задавать, используетсяlenet
)https
-True
, что бы включить режим httpsdata
- передаваемые данные для нейронной сети (например, бинарная строка с изображением)- возвращает строку с ответом сервера, либо строку с ошибкой (начинается с
[E]
), либоlist
со списком сетей и их адресами при запросеlist_nn
, либоtuple
с точностью обучения сети в % и датой последнего обучения при запросеlenet status
Поддерживаемые значения для name_nn
:
list_nn
- получить список имеющихся нейронных сетей и их адресаlenet
- действия над сетью LeNet
Поддерживаемые значения для type_operation
:
classify
- классифицировать изображениеstatus
- получить статус сети (точность классификации и дата последнего обучения)train
- запустить обучение сети (LeNet: на наборе данных MNIST или своём предварительно созданном наборе данных)about
- получить информацию о сети
data
должна содержать:
- Для
lenet classify
- изображение.jpg/.png/.bmp/.tiff
с рукописной цифрой в виде бинарной строки - Для
lenet train
- значениеmnist
(набор данных MNIST) илиother
(свой предварительно созданный набор данных) для выбора соответствующей обучающей выборки - В остальных случаях
data
не используется
Пример использования (подробнее можете посмотреть в nn_client.py
в функции main()
):
name_nn = 'lenet'
type_operation = 'classify'
number_image = '1'
data = None
if type_operation == 'classify': # Если выбрана классификация, будет загружено изображение цифры 1
img_path = 'images/' + number_image + '.jpg'
with open(img_path, 'rb') as f_image:
data = f_image.read()
try:
result = access_to_nn_server('127.0.0.1', '5000', name_nn, type_operation, data=data)
except requests.exceptions.RequestException as e: # Если возникла ошибка при отправке/получении запроса/ответа
print('\n[E] ' + str(e) + '\n')
return
if isinstance(result, tuple): # Если был запрос на статус сети
print('Результат обработки запроса: точность классификации %s%%, дата последнего обучения %s' % (result[0], result[1]))
elif isinstance(result, list): # Если был запрос на список имеющихся сетей
print('Результат обработки запроса: %s' % result)
elif result.find('[E]') != -1: # Если сервер вернул ошибку либо переданы некорректные данные
print(result)
else:
print('Результат запроса: ' + result)
Если у вас возникнут вопросы, можете написать мне: vladsklim@gmail.com