ML-модель с автоматическим созданием

Это часть серии записей блога, посвященных автоматизированному созданию моделей машинного обучения и наборов данных, используемых для обучения алгоритмов. Если вам интересна предыстория, вы можете прокрутить нижнюю часть статьи, чтобы получить ссылки на предыдущие записи блога. Вы также можете перейти на страницу Использование данных SERP для построения моделей машинного обучения, чтобы получить четкое представление о том, какие автоматизированные модели машинного обучения вы можете создавать.

На предыдущей неделе мы показали, как использовать SerpApi’s Google Images Scraper API для получения чистого набора данных, чтобы уменьшить шум при обучении моделей машинного обучения, а также как автоматизировать использование параметра chips. На этой неделе мы поговорим о том, как автоматизировать создание алгоритмов для обучения моделей машинного обучения. Как и в предыдущие недели, оптимизация обучения не будет основной задачей. Цель — максимально приблизиться к автоматизированному машинному обучению.

Можно ли автоматизировать ML?

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

Этот процесс глубоко связан с интерпретируемостью работы data scientists и программных инженеров, а также эффективной визуализацией процессов обучения, нейронных сетей и метрик. Общая автоматизация ограничена из-за фундаментальной проблемы. Библиотеки, написанные для науки о данных, не оптимизированы для автоматизации этого процесса в масштабе. Существуют другие решения, такие как automl, которые ограничены своими рамками. Общего автоматизированного машинного обучения с поддержкой множества библиотек и автоматическим созданием чистых наборов данных пока не существует. Мы стремимся создать такую систему и сделать ее проектом с открытым исходным кодом для data scientists, software engineers и всех, кто интересуется этой темой.

Каковы основные 3 типа ML-моделей?

Бинарная классификация, многоклассовая классификация и регрессия — это три типа основных ML-моделей. Бинарная классификация означает модель с двумя исходами, обычно используемую в принятии решений. Многоклассовая классификация предназначена для классификации между различными помеченными объектами. Регрессия используется для предсказания будущего события с помощью регрессивных оптимизаторов.

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

Настройки модели

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

Сначала я перенес класс, отвечающий за алгоритм CNN, в отдельный файл models.py.
Это полезно для ручного добавления в будущем.

from commands import TrainCommands, TestCommands
import torch.nn as nn
import torch.nn.functional as F
from collections import OrderedDict
import torch

class CNN(nn.Module):
    def __init__(self, tc: TrainCommands | TestCommands):
        super().__init__()
        n_labels = tc.n_labels
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.flatten = nn.Flatten(start_dim=1)
        self.fc1 = nn.Linear(16*125*125, 120) # Manually calculated
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, n_labels) #unique label size

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.flatten(x)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь как мы можем написать все это, используя только ограниченные и упорядоченные переменные, которые не нарушат работу гиперпараметров? Вот тут-то и приходит на помощь функция Sequential, чтобы автоматизировать наш процесс:

class CNNSeq(nn.Module):
    def __init__(self, tc: TrainCommands | TestCommands):
        super(CNNSeq, self).__init__()
        n_labels = tc.n_labels
        self.layers = nn.Sequential(
            # First 2D convolution layer
            nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Second 2D convolution layer
            nn.Conv2d(in_channels= 6, out_channels = 16, kernel_size=5),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Linear Layers
            nn.Flatten(start_dim=1),
            nn.Linear(in_features = 16*125*125, out_features = 120),
            nn.ReLU(inplace=True),
            nn.Linear(in_features = 120, out_features = 84),
            nn.ReLU(inplace=True),
            nn.Linear(in_features = 84,out_features = n_labels)
        )

    def forward(self, x):
        x = self.layers(x)
        return x
Войти в полноэкранный режим Выход из полноэкранного режима

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

class CustomModel(nn.Module):
    def __init__(self, tc: TestCommands | TrainCommands):
        super(CustomModel, self).__init__()
        n_labels = tc.n_labels
        layer_commands = tc.model['layers']
        layer_list = []
        device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
Войти в полноэкранный режим Выйти из полноэкранного режима

Модель будет построена с помощью массива команд в TestCommands или TrainCommands. Это будет указывать моделям машинного обучения, как себя формировать.

Существует требование, чтобы набор данных использовался слой за слоем, после предварительной обработки он должен быть определенного размера. Мы сократили трудоемкую предварительную обработку, получив только чистые обучающие данные, как объяснялось в предыдущих неделях. Но это требование является обязательным при обучении модели. Размер входа предыдущих слоев в нейронной сети должен соответствовать размеру входа текущего узла, чтобы выполнить вычисление вектора. Например, конволюционный слой с выходом 5 должен быть соединен со следующим конволюционным слоем с входом 5, чтобы итерационный процесс был действительным. Для такого сценария мы будем использовать индекс слоя, имя слоя и массив слоев для автоматического вычисления таких чисел, если мы этого захотим.

def autosize(layer_name, index, layer_commands):
  for k in reversed(range(0,len(layer_commands))):
    layer = layer_commands[k]
    if k < index and layer['name'] == layer_name :
      value = [val for key, val in layer.items() if "out" in key][-1]
      return value

Вход в полноэкранный режим Выход из полноэкранного режима

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

Мы будем использовать функцию eval языка Python для создания модели с помощью команд обучения:

for i in range(0, len(layer_commands)):
  layer = layer_commands[i]
  layer_name = layer['name']
  string_operation = "nn.{}(".format(layer_name)
  for j in range(1,len(layer.keys())):
    key = list(layer.keys())[j]
    if layer[key] == "n_labels":
      string_operation = string_operation + "{}={},".format(key, n_labels)
    elif layer[key] == "auto":
      value = autosize(layer_name, i, layer_commands)
      string_operation = string_operation + "{}={},".format(key, value)
    else:
      string_operation = string_operation + "{}={},".format(key, layer[key])
  string_operation = string_operation[0:-1] + ").to(device)"
  operation = eval(string_operation)
  layer_list.append(operation)

self.layers = nn.Sequential(*layer_list).to(device)
Войти в полноэкранный режим Выйти из полноэкранного режима

Это создаст тот же класс, который мы назвали CNNSeq непосредственно перед началом процесса машинного обучения.

Наконец, мы вызываем функцию, отвечающую за итерационный процесс:

def forward(self, x):
  x = self.layers(x)
  return x
Войти в полноэкранный режим Выход из полноэкранного режима

Как автоматизировать процесс машинного обучения?

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

Для этого процесса мы будем использовать конечные точки /train и /test.

Если вы запросите конечную точку /train со следующим словарем (оптимизация не действует):

{
  "model_name": "american_dog_species",
  "criterion": {
    "name": "CrossEntropyLoss"
  },
  "optimizer": {
    "name": "SGD",
    "lr": 0.1,
    "momentum": 0.9
  },
  "batch_size": 4,
  "n_epoch": 100,
  "n_labels": 0,
  "image_ops": [
    {
      "resize": {
        "size": [
          500,
          500
        ],
        "resample": "Image.ANTIALIAS"
      }
    },
    {
      "convert": {
        "mode": "'RGB'"
      }
    }
  ],
  "transform": {
    "ToTensor": true,
    "Normalize": {
      "mean": [
        0.5,
        0.5,
        0.5
      ],
      "std": [
        0.5,
        0.5,
        0.5
      ]
    }
  },
  "target_transform": {
    "ToTensor": true
  },
  "label_names": [
    "American Hairless Terrier imagesize:500x500",
    "Alaskan Malamute imagesize:500x500",
    "American Eskimo Dog imagesize:500x500",
    "Australian Shepherd imagesize:500x500",
    "Boston Terrier imagesize:500x500",
    "Boykin Spaniel imagesize:500x500",
    "Chesapeake Bay Retriever imagesize:500x500",
    "Catahoula Leopard Dog imagesize:500x500",
    "Toy Fox Terrier imagesize:500x500"
  ],
  "model": {
    "name": "",
    "layers": [
      {
        "name": "Conv2d",
        "in_channels": 3,
        "out_channels": 6,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Conv2d",
        "in_channels": "auto",
        "out_channels": 16,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Conv2d",
        "in_channels": "auto",
        "out_channels": 32,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Flatten",
        "start_dim": 1
      },
      {
        "name": "Linear",
        "in_features": 111392,
        "out_features": 120
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "Linear",
        "in_features": "auto",
        "out_features": 84
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "Linear",
        "in_features": "auto",
        "out_features": "n_labels"
      }
    ]
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Будет создана модель глубокого обучения с именем american_dog_species, с критерием CrossEntropyLoss, с оптимизатором SGD, со скоростью обучения и импульсом оптимизатора 0.1 и 0.9 соответственно. В каждом интервале будет получено 4 изображения из набора данных изображений, алгоритмы будут обучены 100 раз с заданными операциями над изображениями и тензорными преобразованиями. Для построения модели будет использоваться словарь слоев, а в качестве данных — имена меток.

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

Теперь, чтобы протестировать модель машинного обучения и проверить, способна ли она классифицировать набор данных, нам нужно отправить запрос на конечную точку /test со следующим словарем:

{
  "ids": [],
  "limit": 200,
  "label_names": [
    "American Hairless Terrier imagesize:500x500",
    "Alaskan Malamute imagesize:500x500",
    "American Eskimo Dog imagesize:500x500",
    "Australian Shepherd imagesize:500x500",
    "Boston Terrier imagesize:500x500",
    "Boykin Spaniel imagesize:500x500",
    "Chesapeake Bay Retriever imagesize:500x500",
    "Catahoula Leopard Dog imagesize:500x500",
    "Toy Fox Terrier imagesize:500x500"
  ],
  "n_labels": 0,
  "criterion": {
    "name": "CrossEntropyLoss"
  },
  "model_name": "american_dog_species.pt",
  "image_ops": [
    {
      "resize": {
        "size": [
          500,
          500
        ],
        "resample": "Image.ANTIALIAS"
      }
    },
    {
      "convert": {
        "mode": "'RGB'"
      }
    }
  ],
  "transform": {
    "ToTensor": true,
    "Normalize": {
      "mean": [
        0.5,
        0.5,
        0.5
      ],
      "std": [
        0.5,
        0.5,
        0.5
      ]
    }
  },
  "target_transform": {
    "ToTensor": true
  },
  "model": {
    "name": "",
    "layers": [
      {
        "name": "Conv2d",
        "in_channels": 3,
        "out_channels": 6,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Conv2d",
        "in_channels": "auto",
        "out_channels": 16,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Conv2d",
        "in_channels": "auto",
        "out_channels": 32,
        "kernel_size": 5
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "MaxPool2d",
        "kernel_size": 2,
        "stride": 2
      },
      {
        "name": "Flatten",
        "start_dim": 1
      },
      {
        "name": "Linear",
        "in_features": 111392,
        "out_features": 120
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "Linear",
        "in_features": "auto",
        "out_features": 84
      },
      {
        "name": "ReLU",
        "inplace": true
      },
      {
        "name": "Linear",
        "in_features": "auto",
        "out_features": "n_labels"
      }
    ]
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Это создаст тот же алгоритм машинного обучения, который мы обучали, чтобы дать нам результат проверки. Как я уже упоминал, я не проводил никакой оптимизации гиперпараметров, поэтому результаты проверки не будут иметь для нас никакого применения.

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

@app.post("/train/")
def train(tc: TrainCommands):
  if tc.model['name'] != None and tc.model['name'] != "":
    model = eval(tc.model['name'])
  else:
    model = CustomModel

  trainer = Train(tc, model, CustomImageDataLoader, CustomImageDataset, ImagesDataBase)
  trainer.train()
  model = None
  try:
    torch.cuda.empty_cache()
  except:
    pass
  return {"status": "Success"}

@app.post("/test")
def test(tc: TestCommands):
  if tc.model['name'] != None and tc.model['name'] != "":
    model = eval(tc.model['name'])
  else:
    model = CustomModel
  tester = Test(tc, CustomImageDataset, ImagesDataBase, model)
  accuracy = tester.test_accuracy()
  model = None
  try:
    torch.cuda.empty_cache()
  except:
    pass
  return {"status": "Success","accuracy": "{}".format(accuracy)}
Войти в полноэкранный режим Выход из полноэкранного режима

Мы также удалим модель в GPU, чтобы сэкономить время между каждым процессом машинного обучения. Также вы можете добавить модель вручную внутри models.py и вызвать ее по имени, опустив словарь слоев в автоматическом процессе машинного обучения.

Вы можете заметить, что вместо того, чтобы ходить туда-сюда с кодом Python, пытаясь оптимизировать модель машинного обучения, вы можете легко настроить количество слоев, гиперпараметры, выбор модели и получить результат по производительности модели. Это особенно хорошая практика для общих моделей машинного обучения. Это может сократить время, необходимое для поиска нейронной архитектуры, подготовки данных, использования новых данных и разработки модели, оптимизации гиперпараметров без каких-либо уступок. Кроме того, вы можете легко увеличивать или уменьшать масштаб отбора признаков без создания трудоемкого рабочего процесса.

Заключение

Я благодарен читателям за внимание, а Brilliant People of SerpApi за то, что они сделали эти серии статей возможными. В следующие недели мы рассмотрим визуализацию данных процесса обучения на фронтенде, добавим недостающие детали, такие как возможность поддержки трансферного обучения и интерпретации временных рядов. Мы также обсудим возможные аспекты инженерии функций и метаобучения для глубоких нейронных сетей, которые могут открыть путь к искусственному интеллекту с большим количеством реальных примеров использования. Мы также обсудим, как реализовать поддержку других библиотек, таких как tensorflow, мощный scikit-learn (a.k.a. sklearn), возможность интеграции с облачными сервисами, такими как Microsoft Azure. Мы также автоматизируем некоторые модели машинного обучения для решения небольших реальных задач в здравоохранении.

Ссылки на предыдущие записи блога
Как обучить масштабируемый классификатор с помощью FastAPI и SerpApi?
Автоматическое обучение с помощью FastAPI, Pytorch и SerpApi
Создание базы данных N1QL меченых изображений с использованием Couchbase, FastAPI и SerpApi
Использование настраиваемого словаря для автоматического обучения сети с помощью FastApi, PyTorch и SerpApi
Расширение возможностей обучения с помощью данных SERP
Автоматическое обучение в масштабе
ML-модель с автоматическим созданием

Оцените статью
devanswers.ru
Добавить комментарий