Пример. Создание и развертывание пользовательского навыка с помощью конструктора Машинного обучения Azure (архив)
Этот пример архивирован и не поддерживается. В ней объясняется, как использовать конструктор Машинного обучения Azure — это простой интерактивный холст для создания моделей машинного обучения для таких задач, как регрессия и классификация. Для вызова модели, созданной конструктором в конвейере обогащения Когнитивного поиска, необходимо выполнить несколько дополнительных действий. В этом примере показано, как создать простую модель регрессии для прогнозирования цены автомобиля и вызова конечной точки вывода в качестве навыка AML.
Для создания модели, которая прогнозирует цену автомобиля на основе различных функций, следуйте инструкциям из учебника Регрессия. Прогноз стоимости автомобилей (расширенный) на странице с примерами конвейеров и наборов данных.
Важно!
В результате развертывания модели путем выполнения процесса вывода в режиме реального времени будет создана допустимая конечная точка, но не та, которую можно использовать с навыком AML в Когнитивном поиске.
Регистрация модели и скачивание ресурсов
После обучения модели зарегистрируйте обученную модель и выполните действия по скачиванию всех файлов в папке trained_model_outputs
или скачайте только файлы score.py
и conda_env.yml
с веб-страницы артефактов модели. Измените скрипт оценки, прежде чем развертывать модель в качестве конечной точки вывода в режиме реального времени.
Изменение скрипта оценки для использования с Когнитивным поиском
Конвейеры обогащения Когнитивного поиска работают с одним документом и создают запрос, содержащий входные данные для одного прогноза. Скачанный файл score.py
принимает список записей и возвращает список прогнозов в виде сериализованной строки JSON. Вам нужно внести два изменения в score.py
:
- изменение скрипта для работы с одной входной записью, а не со списком;
- изменение скрипта для возврата объекта JSON с одним свойством — прогнозируемой ценой.
Откройте скачанный score.py
и измените функциюrun(data)
. Сейчас функция настроена на ожидание следующих входных данных, как описано в файле _samples.json
модели.
[
{
"symboling": 2,
"make": "mitsubishi",
"fuel-type": "gas",
"aspiration": "std",
"num-of-doors": "two",
"body-style": "hatchback",
"drive-wheels": "fwd",
"engine-location": "front",
"wheel-base": 93.7,
"length": 157.3,
"width": 64.4,
"height": 50.8,
"curb-weight": 1944,
"engine-type": "ohc",
"num-of-cylinders": "four",
"engine-size": 92,
"fuel-system": "2bbl",
"bore": 2.97,
"stroke": 3.23,
"compression-ratio": 9.4,
"horsepower": 68.0,
"peak-rpm": 5500.0,
"city-mpg": 31,
"highway-mpg": 38,
"price": 6189.0
},
{
"symboling": 0,
"make": "toyota",
"fuel-type": "gas",
"aspiration": "std",
"num-of-doors": "four",
"body-style": "wagon",
"drive-wheels": "fwd",
"engine-location": "front",
"wheel-base": 95.7,
"length": 169.7,
"width": 63.6,
"height": 59.1,
"curb-weight": 2280,
"engine-type": "ohc",
"num-of-cylinders": "four",
"engine-size": 92,
"fuel-system": "2bbl",
"bore": 3.05,
"stroke": 3.03,
"compression-ratio": 9.0,
"horsepower": 62.0,
"peak-rpm": 4800.0,
"city-mpg": 31,
"highway-mpg": 37,
"price": 6918.0
},
{
"symboling": 1,
"make": "honda",
"fuel-type": "gas",
"aspiration": "std",
"num-of-doors": "two",
"body-style": "sedan",
"drive-wheels": "fwd",
"engine-location": "front",
"wheel-base": 96.5,
"length": 169.1,
"width": 66.0,
"height": 51.0,
"curb-weight": 2293,
"engine-type": "ohc",
"num-of-cylinders": "four",
"engine-size": 110,
"fuel-system": "2bbl",
"bore": 3.15,
"stroke": 3.58,
"compression-ratio": 9.1,
"horsepower": 100.0,
"peak-rpm": 5500.0,
"city-mpg": 25,
"highway-mpg": 31,
"price": 10345.0
}
]
Изменения гарантируют, что модель может принять входные данные, созданные Когнитивным поиском во время индексирования, то есть единственную запись.
{
"symboling": 2,
"make": "mitsubishi",
"fuel-type": "gas",
"aspiration": "std",
"num-of-doors": "two",
"body-style": "hatchback",
"drive-wheels": "fwd",
"engine-location": "front",
"wheel-base": 93.7,
"length": 157.3,
"width": 64.4,
"height": 50.8,
"curb-weight": 1944,
"engine-type": "ohc",
"num-of-cylinders": "four",
"engine-size": 92,
"fuel-system": "2bbl",
"bore": 2.97,
"stroke": 3.23,
"compression-ratio": 9.4,
"horsepower": 68.0,
"peak-rpm": 5500.0,
"city-mpg": 31,
"highway-mpg": 38,
"price": 6189.0
}
Замените строки с 27 по 30 следующим кодом
for key, val in data.items():
input_entry[key].append(decode_nan(val))
Кроме того, необходимо изменить выходные данные, создаваемые скриптом из строки в объект JSON. Измените оператор return (строка 37) в исходном файле:
output = result.data_frame.values.tolist()
return {
"predicted_price": output[0][-1]
}
Ниже вы видите обновленную функцию run
с изменениями в формате входных данных и прогнозируемыми выходными данными, которые принимают одну запись в качестве входных данных и возвращают объект JSON с прогнозируемой ценой.
def run(data):
data = json.loads(data)
input_entry = defaultdict(list)
# data is now a JSON object not a list of JSON objects
for key, val in data.items():
input_entry[key].append(decode_nan(val))
data_frame_directory = create_dfd_from_dict(input_entry, schema_data)
score_module = ScoreModelModule()
result, = score_module.run(
learner=model,
test_data=DataTable.from_dfd(data_frame_directory),
append_or_result_only=True)
#return json.dumps({"result": result.data_frame.values.tolist()})
output = result.data_frame.values.tolist()
# return the last column of the the first row of the dataframe
return {
"predicted_price": output[0][-1]
}
Регистрация и развертывание модели
После сохранения изменений можно зарегистрировать модель на портале. Выберите модель для регистрации и укажите допустимое имя. Для платформы модели выберите Other
, для имени платформы — Custom
, а для версии платформы — 1.0
. Выберите параметр Upload folder
, а также папку с обновленными файлами score.py
и conda_env.yaml
.
Выберите модель и действие Deploy
. На этапе развертывания предполагается, что у вас есть готовый к работе кластер вывода AKS. В Когнитивном поиске экземпляры контейнеров сейчас не поддерживаются.
- Укажите допустимое имя конечной точки.
- Выберите тип вычисления
Azure Kubernetes Service
. - Выберите имя вычисления для кластера вывода.
- Переведите переключатель
enable authentication
в положение "Вкл.". - Выберите
Key-based authentication
в качестве типа. - Выберите обновленный файл
score.py
дляentry script file
. - Выберите для
conda_env.yaml
conda dependencies file
- Нажмите кнопку развертывания, чтобы развернуть новую конечную точку.
Интеграция с Когнитивным поиском
Чтобы интегрировать только что созданную конечную точку с Когнитивным поиском, сделайте следующее:
- Добавьте файл JSON, содержащий одну запись автомобиля, в контейнер BLOB-объектов.
- Настройте конвейер обогащения СИ с помощью мастера импорта данных. Обязательно выберите
JSON
в качествеparsing mode
. - На вкладке
Add Enrichments
выберите один навыкExtract people names
в качестве заполнителя. - Добавьте новое поле в индекс с именем
predicted_price
типаEdm.Double
, а также задайте для свойства "Возможно извлечение" значение true. - Завершите процесс импорта данных.
Добавление навыка AML в набор навыков
Из списка наборов навыков выберите созданный набор навыков. Теперь вы можете изменить набор навыков и заменить навык идентификации людей навыком AML для прогнозирования цен.
На вкладке определения набора навыков (JSON) из раскрывающегося списка навыков выберите Azure Machine Learning (AML)
. Выберите рабочую область, чтобы навык AML смог обнаружить конечную точку. Рабочая область и служба поиска должны быть в одной подписке Azure.
Выберите конечную точку, созданную в этом учебнике ранее.
Убедитесь, что навык заполнен сведениями об URI и проверке подлинности, настроенными при развертывании конечной точки. Скопируйте шаблон навыка и замените навык в наборе навыков.
Измените навык следующим образом:
- Задайте допустимое имя.
- Добавьте описание.
- Задайте для degreesOfParallelism значение 1.
- Задайте для контекста значение
/document
. - Задайте для входных данных все необходимые входные данные. Пример определения навыка см. ниже.
- Задайте для выходных данных захват возвращенной прогнозируемой цены.
{
"@odata.type": "#Microsoft.Skills.Custom.AmlSkill",
"name": "AMLdemo",
"description": "AML Designer demo",
"context": "/document",
"uri": "Your AML endpoint",
"key": "Your AML endpoint key",
"resourceId": null,
"region": null,
"timeout": "PT30S",
"degreeOfParallelism": 1,
"inputs": [
{
"name": "symboling",
"source": "/document/symboling"
},
{
"name": "make",
"source": "/document/make"
},
{
"name": "fuel-type",
"source": "/document/fuel-type"
},
{
"name": "aspiration",
"source": "/document/aspiration"
},
{
"name": "num-of-doors",
"source": "/document/num-of-doors"
},
{
"name": "body-style",
"source": "/document/body-style"
},
{
"name": "drive-wheels",
"source": "/document/drive-wheels"
},
{
"name": "engine-location",
"source": "/document/engine-location"
},
{
"name": "wheel-base",
"source": "/document/wheel-base"
},
{
"name": "length",
"source": "/document/length"
},
{
"name": "width",
"source": "/document/width"
},
{
"name": "height",
"source": "/document/height"
},
{
"name": "curb-weight",
"source": "/document/curb-weight"
},
{
"name": "engine-type",
"source": "/document/engine-type"
},
{
"name": "num-of-cylinders",
"source": "/document/num-of-cylinders"
},
{
"name": "engine-size",
"source": "/document/engine-size"
},
{
"name": "fuel-system",
"source": "/document/fuel-system"
},
{
"name": "bore",
"source": "/document/bore"
},
{
"name": "stroke",
"source": "/document/stroke"
},
{
"name": "compression-ratio",
"source": "/document/compression-ratio"
},
{
"name": "horsepower",
"source": "/document/horsepower"
},
{
"name": "peak-rpm",
"source": "/document/peak-rpm"
},
{
"name": "city-mpg",
"source": "/document/city-mpg"
},
{
"name": "highway-mpg",
"source": "/document/highway-mpg"
},
{
"name": "price",
"source": "/document/price"
}
],
"outputs": [
{
"name": "predicted_price",
"targetName": "predicted_price"
}
]
}
Обновление сопоставлений полей выходных данных индексатора
Сопоставления полей выходных данных индексатора определяют, какие обогащения сохраняются в индексе. Замените раздел сопоставления полей выходных данных индексатора представленным ниже фрагментом:
"outputFieldMappings": [
{
"sourceFieldName": "/document/predicted_price",
"targetFieldName": "predicted_price"
}
]
Теперь вы можете запустить индексатор и проверить, заполнено ли свойство predicted_price
в индексе результатом выходных данных навыка AML.