TensorFlow UDF
Применение TensorFlow графов вычислений.
TensorFlow::InitSession(
String, -- путь к сериализованному в protobuf формате графу вычислений, единственный обязательный аргумент
Bool?, -- EnableMKLDNN, включение MKLDNN https://01.org/mkl-dnn
Bool?, -- MKLCBWRCompatible, включение совместимости с SSE2 для MKL https://software.intel.com/en-us/mkl
Bool?, -- MKLDNNUseWeightsAsGiven, по умолчанию false
Bool?, -- AllowSoftPlacement, по умолчанию true
Int32?, -- IntraOpParallelismThreads, по умолчанию 0
Int32?, -- InterOpParallelismThreads, по умолчанию 0
) -> Resource<TensorFlow.Session> -- указатель на TensorFlow сессию с проинициализированным
-- графом вычислений
TensorFlow::RunBatch(
Resource<TensorFlow.Session>, -- результат TensorFlow::InitSession
List<Struct<
PassThrough:* -- произвольные данные, которые пропускаются через функцию без изменений
*:* -- имена остальных полей соответствуют именам входов графа вычислений, которые
-- будут переданы в TensorFlow, а их типы данных — соответствующим формам тензоров;
-- примитивный тип данных соответствует скалярному тензору, список — вектору,
-- матрицы на данный момент не поддерживаются.
>>,
Type<Struct<*:*>>, -- описание выходов графа, которые необходимо вычислить по аналогии со входами
List<String>?, -- TargetNodeNames, опциональный список имен узлов графа, которые нужно вычислить,
-- но не возвращать
Uint32?, -- BatchSize, по умолчанию 128
Uint32?, -- MinVectorSize, по умолчанию 1, позволяет выроврять входные вектора до указанной длины,
-- если на входе они имеют разную длину <= указанной.
-- Если не выставлен, длины векторов батча выравниваются до максимальной в рамках батча.
) -> List<Struct<
PassThrough:* -- переданное в аргумент PassThrough без изменений,
*:* -- остальные поля соответствуют типу данных, указанному в третьем аргументе
>> -- результат
TensorFlow::RunBatch
является достаточно сложной полиморфной функцией, предназначенной для выполнения в PROCESS. Настоятельно рекомендуется ознакомиться с примером ниже.
Пример использования
Задача: угадать пол владельца заданного адреса электронной почты с помощью TensorFlow и предварительно обученной нейронной сети LSTM.
Пример данных входной таблицы emails_sample
|
uid |
"ayse.betul@list.ru" |
8401912741484409541 |
"gkorchigina@advisegroup.ru" |
7443540151492739379 |
"derunova@hyva.ru" |
1206408241455208802 |
"n.tohtaeva@apex-realty.ru" |
8401934471495213920 |
"danya_kuzya11@topservice.od.ua" |
9354031741499148496 |
"e.a.abrosimova@hyva.ru" |
1206415791497489033 |
"muratguney@tut.by" |
84019341499566593 |
"juriy647@zakrepi.ru" |
7443595151476837533 |
"inginiringstroy@bodo.ua" |
120641461502424396 |
"homuncule@fenixrostov.ru" |
8401933951498412781 |
"vetal1984@72.ru" |
7443588691497078993 |
"botagoz@game-forest.com" |
1206414471493466146 |
"kent2010@etvp.perm.ru" |
8401933051457890411 |
"gordeeva@lider-exp.ru" |
7443585201492797494 |
"a.vakish@tut.by" |
1206414051498009965 |
"d.volia.pinsk@b-urist.ru" |
8401932351484247832 |
"juravleva.e@rambler.ru" |
7443577411470618706 |
"hr.pers.specialist7@prizyvanet.ru" |
1206412411504975868 |
"sales106@belydom.ru" |
8401929831460458776 |
"r.zinatullin@smum.biz" |
7443574961501375635 |
"dpm.spec.delivery.rent2@mgllojistik.com" |
1206412411502352831 |
"ekaterina@rc.yartel.ru" |
8401921921456190987 |
"alex.krause@aktivdengi.com" |
7443572251501358851 |
"acc.invest.other@smpvo.ru" |
1206412411498937658 |
"turris.secretary-r@n-h-s.ru" |
8401916371502363695 |
PRAGMA yt.DataSizePerJob = "128M"; -- поскольку это вычисление достаточно трудоемкое,
-- будем запрашивать небольшой размер данных на задание
PRAGMA file("email.pb", "<путь к сериализованному графу вычислений>");
$session = TensorFlow::InitSession(
FilePath("email.pb") -- путь к определению графа TensorFlow
);
PRAGMA library("char_table.sql"); -- считываем прикрепленный файл как источник для импорта
IMPORT char_table SYMBOLS $char_to_float; -- импортируем лямбду из библиотеки, которая преобразует символы
-- электронной почты таким же образом, как это было сделано
-- во время обучения модели
--лямбда-функция для предобработки адресов электронной почты
$email_to_float_vector = ($email) -> {
$cut = FIND($email, "@"); -- оставляем только логин
$cut = MIN_OF($cut, 20u) ?? 20u;
$email = SUBSTRING($email, 0, $cut); -- обрезаем слишком длинные логины
$email_bytes = String::ToByteList($email); -- преобразуем строку в список байтов
RETURN ListFlatMap($email_bytes, $char_to_float); -- применяем лямбду
};
$input = (
SELECT
$email_to_float_vector(email) AS input_1, -- имя столбца должно совпадать с именем
-- входа графа TensorFlow
TableRow() AS PassThrough -- специальное имя столбца, чтобы передать
-- любые данные в batch-режиме TensorFlow;
-- в данном примере передается целая входная строка
FROM emails_sample);
--------------------------------------------------------------------------------
-- Соглашения между TensorFlow и YQL:
-- - имя входного столбца должно совпадать с именем входного графа, а его тип должен
-- соответствовать форме тензора и типу данных;
-- - поддерживаемые типы данных: Float, Double, Int32, Int64, Uint8, Bool;
-- - List<> означает вектор, в то время как скаляр, матрицы и другие формы
-- пока не поддерживаются;
-- - у модели в этом примере только один вход, но их может быть много;
-- - те же правила применяются и к выходному графу;
-- - столбец PassThrough в настоящее время является обязательным, но может стать
-- опциональным в будущем.
--------------------------------------------------------------------------------
$processed = (PROCESS $input
USING TensorFlow::RunBatch( -- Apply TensorFlow graph in batches
$session,
TableRows(), -- специальное имя для итератора по строкам таблицы
-- описание вывода графа для вычисления
Struct<network_output:List<Float>>,
-- каждый элемент структуры представляет один из выходных данных графа;
-- имя каждого элемента должно соответствовать имени, которое использовалось
-- во время процесса обучения;
-- соответствие между тензорами и типами данных YQL такое же, как и у входных данных
ListCreate(String), -- TargetNodeNames
128, -- BatchSize
20 -- MinVectorSize
));
SELECT
network_output[0] ?? 0.0f AS score, -- результат попытки угадать пол по электронной почте:
-- - близко к 0.0 — "женский"
-- - близко к 1.0 — "мужской"
-- - близко к 0.5 — "трудно определить"
PassThrough.email AS email, -- исходная электронная почта
PassThrough.uid AS uid -- отдельный столбец для дополнительных входных данных
FROM $processed;