В этой статье я хочу дать вам представление (конечно, есть много других способов) того, как вы можете создавать и развертывать модели машинного обучения и использовать их в качестве веб-API.

Как новичок, я хотел подойти к небольшому проекту, который имеет следующие ограничения:

  • Шаг 1: Создайте модель CNN, используя keras с бэкендом tensorflow, и используйте ее для прогнозирования категорий.
  • Шаг 2. Создайте небольшое веб-приложение с использованием ядра react и asp .net, которое использует и предоставляет API прогнозирования.

Шаг 1: Создайте модель CNN

Моим технологическим стеком для этого был python, использующий keras с бэкендом tensorflow. Хорошая поддержка сообщества и интуитивно понятный функциональный API от keras сделали этот стек разумным выбором.

Шаг 1.1: Получите и обработайте данные

Есть много наборов данных от kaggle, я использовал набор данных примерно с 10 категориями (собака, кошка, самолет…), состоящий из изображений 32 на 32 на 3 (r, g, b).

Чтобы прочитать и обработать изображения и их классификацию, чтобы они были готовы к использованию во время обучения, вы можете использовать утилиту ImageDataGenerator от keras и pandas (ознакомьтесь с pd в коде ниже).

datagen = ImageDataGenerator(rescale=1./255)
df = pd.read_csv(r"./data/trainLabels.csv")
train_generator = datagen.flow_from_dataframe(dataframe=df, directory="./data/train/train", x_col="id", y_col="label", has_ext=False, class_mode="categorical", target_size=(32, 32), batch_size=32)

Файл trainLabels.csv содержит 2 столбца: один — имя изображения для обучения, а второй — классификация.

id,label       
1,frog
2,truck
3,truck
4,deer

Шаг 1.2: Определите модель

Затем вы можете определить модель (размер входных данных должен соответствовать целевому размеру, определенному в методе фрейма flow_from_data выше, с необходимыми каналами).

Ниже представлена ​​небольшая модель с приемлемой точностью. Чтобы найти хорошую модель, существуют методологии экспериментов, которые вы можете исследовать, например, применяя тактики для улучшения смещения и дисперсии, включая выборку гиперпараметров, сравнение результатов путем параллельного запуска нескольких моделей или ухода за моделью.

X_input = Input((32, 32, 3))
X = ZeroPadding2D((3, 3))(X_input)
X = Conv2D(32, (7, 7), strides=(1, 1), name='conv0')(X)
X = BatchNormalization(axis=3, name='bn0')(X)
X = Activation('relu')(X)
X = MaxPooling2D((2, 2), name='max_pool')(X)
X = Flatten()(X)
X = Dense(10, activation='softmax', name='fc')(X)
model = Model(inputs=X_input, outputs=X, name='Recogn')
steps = train_generator.n//train_generator.batch_size
model.compile(optimizer="adam", loss='categorical_crossentropy', metrics=["accuracy"])
model.fit_generator(generator=train_generator, steps_per_epoch=steps, epochs=1)

Пожалуйста, посмотрите метод fit_generator, как он сочетается с генератором поездов сверху и как легко обрабатывать и отправлять данные.

Шаг 1.3. Тренируйтесь в Google Colab.

Я также провел обучение в одной эпохе, вы можете проверить, работает ли модель на вашем компьютере, но если у вас уже нет первоклассного оборудования, вы должны запустить обучение на платформе Google Colab со средой выполнения GPU (для использования TPU вам нужно больше кода , пожалуйста, изучите, если интересно).

Примечание. Я не продвигаю colab, но это, кажется, единственный жизнеспособный и бесплатный вариант. Пожалуйста, оставьте комментарий, если вы знаете о других платформах.

Для этого я сделал следующее:

  • Я создал папку моделей в базе кода.
  • Я создал папку записных книжек вместе с записной книжкой, в которую я импортировал свою модель из папки моделей и вставил метод подгонки.
  • Кодовая база была отправлена ​​на github.
  • Colab позволяет интегрироваться с github, чтобы я мог загрузить загруженную записную книжку и запустить обучение. Colab позволяет использовать диск Google, как если бы это был локальный диск, поэтому вам нужно поместить туда обучающие изображения. Также он сохраняет обученную модель на Google Диске. Путь к гугл-диску прост (/content/drive/My Drive/), но сначала его нужно смонтировать:
from google.colab import drive
drive.mount('/content/drive')

Для сохранения модели поместите эту ячейку в конец:

model.save("/content/drive/My Drive/model.h5")

Вы можете подумать о том, как организовать свой код, чтобы эффективно проводить эксперименты с моделями с использованием платформы colab.

Шаг 2. Развертывание

Теперь у вас есть файл model.h5, который вы можете использовать для предсказания категории, в которой находится изображение.

Шаг 2.1: Подготовка базы кода

  • Добавьте папку App в корень проекта. В папку приложения поместите файлы model.h5 и main.py. В файле main.py вы напишете метод обслуживания предсказания. Пожалуйста, также добавьте код, который считывает модель и включает флягу, но я оставлю это на ваше усмотрение.
@app.route("/predict", methods=["POST", "GET"])
def predict():
  data = {"prediction": 0}
  if flask.request.method == "POST":
  if flask.request.files.get("image"):
  # gets the file storage stream
    img_stream = flask.request.files['image'].read()
    np_img = np.fromstring(img_stream, np.uint8)
    cv_img = cv2.imdecode(np_img, cv2.IMREAD_UNCHANGED)
    img = np.reshape(cv_img, [1, 32, 32, 3])
  with graph.as_default():
    data["prediction"] = np.asscalar(np.argmax(model.predict(img)))
return flask.jsonify(data)

Код считывает изображение из запроса, масштабирует и преобразует его в соответствии с тем, что требуется для входных данных модели, а затем передает его методу прогнозирования.

Но flask не для производства.

Шаг 2.2: Добавление Dockerfile

Чтобы сделать приведенный выше код готовым к производству, вам нужно, так сказать, обернуть его в (обычно) nginx и многое другое. Это довольно легко сделать с помощью докера. Я нашел образ докера, который уже содержит nginx, но, конечно, он не единственный.

Файл докера должен выглядеть примерно так:

FROM joelogan/keras-tensorflow-flask-uwsgi-nginx-docker
RUN pip install --upgrade keras
RUN pip install pandas
RUN pip install opencv-python
COPY ./app /app

В моем случае мне нужно было обновить keras, установить pandas и opencv, затем я скопировал папку приложения в образ. Папка приложения содержит файл model.h5, который мы сохранили после обучения, и файл main.py с методом прогнозирования.

Шаг 2.3. Создайте автоматизированный конвейер сборки с помощью Azure DevOps.

Я использовал Azure DevOps для извлечения проекта из github и использовал задачу сборки и отправки образа Docker, которая использует Dockerfile из проекта. Вы также можете попробовать другие платформы CI.

Что я хочу получить, так это то, что когда я отправляю код в github, на dockerhub создается новый тег образа докера, и он готов к запуску на сервере. Я думаю, что dockerhub также имеет функцию автоматической сборки непосредственно из github, но я хотел поиграть с DevOps.

Примечание. Если вы используете мое описание конвейера github-azuredevops-dockerhub, будьте осторожны с именем образа, определенным в конвейере сборки azure devops. Имя репозитория должно быть dockerhubusername/dockerhubreponame, но по умолчанию это имя репозитория из github.

Шаг 2.4. Запустите образ докера на сервере

После создания образа докера на dockerhub вы можете использовать любой сервер с установленным докером для запуска докера на порту 80 (или другом). Пожалуйста, проверьте, не заблокирован ли порт брандмауэром. Образ можно предоставить непосредственно из dockerhub, но не забудьте выполнить вход в Docker, если репозиторий является частным.

docker run -d --name mycontainer -p 80:80 myimage

Пробовал на убунту, работает нормально. В основном вы используете server_dns_or_ip/predict и отправляете изображение в запросе (вы можете попробовать это с помощью приложения postman).

Шаг 2.5. Запустите функцию прогнозирования из ядра asp .net.

Я хотел создать небольшое демонстрационное приложение, используя ядро ​​​​React и Asp Net. Итак, что я сделал, так это обернул вызов контейнера докеров, предсказанный на предыдущем шаге, в методе API asp .net core. Затем я использую этот метод дальше в приложении реакции, а не напрямую в nginx. Это потому, что я хочу использовать уже знакомое ядро ​​.net для дальнейшего развития и использования его инфраструктуры.

Однако вы можете задаться вопросом, как можно обеспечить безопасность для доступа к методу прогнозирования и ограничить его только основным клиентом .net.

Для этого вы можете защитить сокет докера с помощью сертификатов, а также ограничить IP-адреса, которые могут получить доступ к серверу, на котором работает контейнер nginx, только теми, которые принадлежат вашему основному серверу .net.

Последние мысли

Не стесняйтесь спрашивать подробности, и я постараюсь помочь, если смогу.