Как стать автором
Обновить

Комментарии 16

аплодисменты стоя :). Мне постоянно кажется, что чинить ломающиеся зависимости в питоне, — это подольше будет, чем просто все перезапилить.
Много опечаток. Рекомендую вычитать статью.
В остальном — супер, реально крутая идея! Единственное, что меня волнует — а при сериализации/десериализации ничего не поломается? Ну, в случае, например, разных архитектур (x86 vs ARM vs что-то еще)? Я уж не говорю, что я хапнул проблем с пиклами разных версий (в рамках одной версии — все ОК)…
Какая производительность получилась? В сравнении с «обычным порошком» на CPU.
НЛО прилетело и опубликовало эту надпись здесь

Тоже пока не очень понял проблему… HDF5 переписывается в .pb на ура скриптом на коленке (ну или тем же keras_to_tensorflow.py если лень).


Дальше оно прекрасно грузится в плюсах, как-нибудь так:


if (!( status = ReadBinaryProto(env, "graph.pb", &grdef) ).ok()) goto boom;
if (!( status = session->Create(grdef) ).ok()) goto boom;
...
if (!( status = session->Run(inputs, ..., &outputs) ).ok()) goto boom;
...
return 0;
boom:
  printf("BOOM: %s \n", status.ToString());
  return -1;

Многослойные и сильно-мудреные вещи делаются вполне себе аналогично.

у меня была похожая идея, но руки так и не дошли сделать)
Это не слишком большое упрощение? ЕМНИП, у Керас в каждом типе слоя есть несколько параметров, влияющих на поведение.
И какая у этого кода производительность по сравнению с оригиналом? В питоновом варианте же сеть компилируется в формат бэкенда (по умолчанию ТензорФлоу) и далее для каждого слоя подбирается соответствующее ядро, тоже написанное на С.
А сам безель штука капризная и отказался собираться под UE4
Поясните пожалуйста, что Вы имеете ввиду под сборкой bazel под UE4?
TF довольно большая и громоздкая штуковина, а мне хотелось чего-то более легкого и производительного
Сравнение производительности в студию. Вы вероятно спутали что-то, не уж то Вам удалось написать более производительный инфиренс (на CPU?) нежели у ребят из Google?
Кстати, если говорить про CPU, то может быть и можно. По крайней мере, если чистую С-реализацию написать.
Я недавно, в неких исследовательских целях, написал на коленке инференс ResNet-34 для типа float (да, я знаю что в этой фразе несколько извращений подряд) и получил производительность где-то в 6 раз ниже, чем у аналогичного инференса на питоне. Но при этом мой вариант был чисто однопоточный и без какой-либо оптимизации, а питон бегал на трёх ядрах и уж родная библиотека явно оптимизирована по полной. Т.е. вовсе не исключено, что если добавить в мой код потоков и SIMD-ов, то он побежит бодрее оригинальной версии.
P.S. Собственно, эти соображения и побудили меня задать автору вопрос по производительности немного выше.

Есть Intel DAAL, который наверняка используется в вашем питоне, если это anaconda. Так что вряд-ли получится что-то ускорить если написать SIMDов самому.

Не совсем вас понял, если честно. Тот код, который я написал — он на чистом С, без использования ещё чего-либо, тем более питона.
> получил производительность где-то в 6 раз ниже, чем у аналогичного инференса на питоне

Я про то что код на питоне внутри тоже может использовать низкоуровневые библиотеки с оптимизациями вплоть до SIMD :).
Вы, вероятно, не очень внимательно прочитали мой первоначальный комментарий.
Код на питоне не просто может использовать SIMD-ы, очевидно, что он их использует. Я брал для сравнения обычный TensorFlow, который внизу оптимизирован весьма неплохо и весь из себя многопоточный.
Но мой код ничего этого не использует (разве что gcc что-нить без спроса векторизовал на -O3), так что, вероятно, есть задел, чтобы преодолеть эту 6-кратную разницу между моим неоптимизированным С-кодом и оптимизированным питоном.
Ок, всё верно, меня смутило про «родную библиотеку», прочитал как «стандартную» :).
Единственное, что всё-таки стоит отметить что TF можно собрать как с оптимизациями, так и без. И не известно с какой сборкой вы сравнивали свой код на Си.
Конвертировать модель Keras в TF, это как 2 байта переслать. Но идея сборки TF из исходников, особенно если надо включить все это в большой проект, действительно, выглядит мутновато. При том, что это явно избыточно: из всего TF нам нужно только inference.
Зато на страничке www.tensorflow.org/install/lang_c есть готовые бинарники библиотеки TF, собранные для Linux, Mac, Windows, в т.ч. для GPU. Забавно, что до недавнего времени файлы Windows были, но ссылки на них не было, так что об их существовании знали «не только лишь все» (с). Сейчас ссылка есть.
Использование вызовов C_API — дело весьма муторное и в 21 веке выглядит не комильфо, зато весит эта библиотечка 60 МБ и не требует зависимостей (кроме GPU, которой нужна CUDA).
Чтобы не возиться с функциями C_API, я допилил простенькую библиотеку, начатую adriankoering, получилось вот что:
        tensorflow_cc_inference::Inference cnn_(model_file_name, "ImageTensor", "SemanticPredictions");
	int64_t dims[] = {1, target_h, target_w, 3};
	auto in = tensorflow_cc_inference::Tensor<uint8_t>(
											dims, 4, my_image.data, NULL /*TestDeallocator*/, NULL);
	auto out = cnn_.Run<int64_t>(in);
	auto shape = out.Shape();
	cv::Mat res(target_h, target_w, CV_32FC1, cv::Scalar(0));
	int64_t* out_data = out.Data();
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации