Jump to content
Compvision.ru

Pechkin80

Пользователи
  • Content count

    60
  • Joined

  • Last visited

  • Days Won

    1

Pechkin80 last won the day on May 3

Pechkin80 had the most liked content!

Community Reputation

2 Новичек

About Pechkin80

  • Rank
    Эксперт

Recent Profile Visitors

275 profile views
  1. А вот так почти сработало, только понять бы в чём разница с предыдущем вариантом. const auto size1 = 1; const auto size2 = 192; const auto size3 = 512; const auto size4 = 1; Tensor inputTensor1(DT_FLOAT, TensorShape({size1, size2, size3, size4})); //заполнение тензоров-входных данных for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.tensor<float, 4>()(0, i1, j1, 0) = 128.; } } Теперь с GPU воевать придёться: UPDATE: В предыдущем сообщении была ошибка: вместо auto intensor = graph_def.node(1).attr().at("shape"); надо: auto intensor = graph_def.node(1).attr().at("value");
  2. Пока забил вручную: Но я не врублюсь какой размерности тензор создавать. В питоне было [-1, 192, 512, 1], а в плюсах const auto size1 = 0; const auto size2 = 192; const auto size3 = 512; const auto size4 = 1; Tensor inputTensor1(DT_FLOAT, TensorShape({size1, size2, size3, size4})); если создать с размерностью (0, 192, 512, 1) то при такой иннициаллизации: for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.matrix<float>()(i1, j1) = 128; } } я получаю ошибку времени выполнения : А при такой иннициаллизации: for (int i1 = 0; i1 < size2; i1++) { for (int j1 = 0; j1 < size3; j1++) { inputTensor1.matrix<float>()(0, i1, j1, 0) = 128; } } такую на этапе компиляции: Вообщем очень сильно плаваю в ситуации, поэто и хотел задавать размерность на автомате чтоб меньше ошибаться. UPDATE: Я на самом деле вроде придумал как определять размерность и если я прав, то всё очень грустно, потомучто тензор в файле записан одномерным. auto intensor = graph_def.node(1).attr().at("value"); Tensor tmp_tensor; bool result = tmp_tensor.FromProto(intensor); int num_dimensions = tmp_tensor.shape().dims(); std::cerr << num_dimensions << std::endl; for(int ii_dim = 0; ii_dim < num_dimensions; ii_dim++) { std::cerr << "i" << tmp_tensor.shape().dim_size(ii_dim) << std::endl; } Потомучто я имею на любом узле num_dimensions равное единице.
  3. А C API можно миксить с С++ API ? Вот тут интересные рассуждения.
  4. Размер тензора вроде можно узнать, но мне надо конвертировать Node графа в тензор прежде и я без понятия как это сделать. Да я конечно могу сам забить размер, но както дико ненадёжное реение получается от таких кастылей. Второй вариант это всёже както сохранять аттрибуты в модели. Функция simple_save это както же делает. В любом случае спасибо. Мне важно знать как делают другие.
  5. Замарозку делал вот так: def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True): """ Freezes the state of a session into a pruned computation graph. Creates a new computation graph where variable nodes are replaced by constants taking their current value in the session. The new graph will be pruned so subgraphs that are not necessary to compute the requested outputs are removed. @param session The TensorFlow session to be frozen. @param keep_var_names A list of variable names that should not be frozen, or None to freeze all the variables in the graph. @param output_names Names of the relevant graph outputs. @param clear_devices Remove the device directives from the graph for better portability. @return The frozen graph definition. """ graph = session.graph with graph.as_default(): freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or [])) output_names = output_names or [] output_names += [v.op.name for v in tf.global_variables()] # Graph -> GraphDef ProtoBuf input_graph_def = graph.as_graph_def() if clear_devices: for node in input_graph_def.node: node.device = "" frozen_graph = convert_variables_to_constants(session, input_graph_def, output_names, freeze_var_names) return frozen_graph frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs]) tf.train.write_graph(frozen_graph, "model", "tf_model.pb", as_text=False)
  6. Более подробно расписал в новой теме.
  7. Когда у меня была незамароженная модель я без труда определял размерность входного и выходного узла графа загруженной модели вот таким образом: using namespace std; using namespace tensorflow; using namespace tensorflow::ops; cout << "Step1" << endl; GraphDef graph_def(true); Session* session; SessionOptions sopt; Status status = NewSession(sopt, &session); if (!status.ok()) { std::cerr << "tf error: " << status.ToString() << "\n"; } const string export_dir = "/home/user/MyBuild/build_tftest2/models"; SavedModelBundle bundle; RunOptions run_options; status = LoadSavedModel(sopt, run_options, export_dir, {kSavedModelTagServe}, &bundle); if (!status.ok()) { std::cerr << "tf error: " << status.ToString() << "\n"; } else { GraphDef graph = bundle.meta_graph_def.graph_def(); auto shape = graph.node().Get(0).attr().at("shape").shape(); for (int i = 0; i < shape.dim_size(); i++) { std::cout << shape.dim(i).size()<<std::endl; } int node_count = graph.node_size(); for (int i = 0; i < node_count; i++) { auto n = graph.node(i); //graph.node(i).PrintDebugString(); cout<<"Names : "<< n.name() <<endl; } } А потом я захотел модель оптимизировать и для этого её заморозил и теперь код загрузки модели уже другой, using namespace std; using namespace tensorflow; using namespace tensorflow::ops; cout << "Step1" << endl; GraphDef graph_def(true); Session* session; SessionOptions sopt; Status status = NewSession(sopt, &session); if (!status.ok()) { std::cerr << "tf error: " << status.ToString() << "\n"; } cout << "Step2" << endl; // Читаем граф //status = ReadBinaryProto(Env::Default(), "/home/user/MyBuild/build_tftest2/models/saved_model.pb", &graph_def); status = ReadBinaryProto(Env::Default(), "/home/user/MySoftware/foreign code/netology_JN/Diplom/Models/optimized/optim_model.pb", &graph_def); //status = ReadBinaryProto(Env::Default(), "/home/user/MySoftware/foreign code/netology_JN/Diplom/Models/Raw/frozen_model.pb", &graph_def); if (!status.ok()) { std::cerr << "tf error: " << status.ToString() << "\n"; } else { int node_count = graph_def.node_size(); for (int i = 0; i < node_count; i++) { auto n = graph_def.node(i); //graph.node(i).PrintDebugString(); cout<<"Names : "<< n.name() <<endl; } auto shape = graph_def.node().Get(0).attr().at("shape").shape(); for (int i = 0; i < shape.dim_size(); i++) { std::cout << shape.dim(0).size()<<std::endl; } } Список узлов я по прежнему получаю, но при попытки получить размерность имею большой облом. Подскажите пожалуйста как получить размерность хотябы входного и выходного узла. Я же должен знать тензоры каких размерностей надо создавать для интеграции модели в приложение. Документации по теме нет и я буду рад любым рассуждениям, которые могут навести на путь истинный.
  8. Спасибо, интересная утилита. Но у меня после всех оптимизаций кудато потерялись атрибуты и код: GraphDef graph_def; ... auto shape = graph_def.node().Get(0).attr().at("shape").shape(); for (int i = 0; i < shape.dim_size(); i++) { std::cout << shape.dim(0).size()<<std::endl; } приводит к исключению:
  9. Ага спасибо, только щас про него вспомнил. Он как раз с заморозкой.
  10. Добрый день, подскажите пожалуйста как правильно "заморозить" модель tensorflow, сохранённую с помощью tf.saved_model.simple_save как ./out/saved_model.pb ? #init_op = tf.initialize_all_variables() with tf.keras.backend.get_session() as sess: sess.run(init_op) tf.saved_model.simple_save( sess, export_path, inputs={'input': model.input}, outputs={'output': model.output}) saver.save(sess, 'tmp/my-weights') Пробовал приспособить freeze_graph.freeze_graph, но безуспешно. Непонятно откуда брать outoute_node когда беру имя выходного узла из модели то в ответ читаю что данные узел не в графе. Щас вообще беда, даже чекпоинт не могу сохранить, который вроде нужен для замарозки: def write_temporary(): init_op = tf.initialize_all_variables() export_path = './out' with tf.Session(graph=tf.Graph()) as sess: tf.saved_model.loader.load(sess, [tag_constants.SERVING], export_path) graph = tf.get_default_graph() tf.train.write_graph(graph, './outtmp', 'model_saved.pbtxt') #print([node.name for node in graph.as_graph_def().node]) #sess.run(init_op) with tf.Session(graph=tf.Graph()) as sess: tf.saved_model.loader.load(sess, [tag_constants.SERVING], export_path) graph = tf.get_default_graph() saver = tf.train.Saver([graph]) # #tf.train.write_graph(graph, './outtmp', 'model_saved.pbtxt') saver.save(sess, './outtmp/model.ckpt') #print([node.name for node in graph.as_graph_def().node]) sess.run(init_op) write_temporary()
  11. Я наверно упоротый параноик и из-за своей паранои проковырялся неделю. Я ж тоже когда сёрфил по инету наткнулся на эту репу https://github.com/FloopCZ/tensorflow_cc как и Вы Но тараканы в голове сказали что нельзя доверять неофициальной репе. Зато теперь я вооружён знаниями как собирать самому из первоисточника и не зависитеть от "добрых" людей.
  12. Кажеться Победа, но я ещё пока не уверен.
  13. Какие все функции ? Сообщение вываливается на этапе выполнения кода. Функции все есть конечно. Вопрос инициаллизации глобальных объектов в либе. А этот код вообще валидный сам по себе. Может он и должен такое выдавать ? Я брал пример отсюда: https://habr.com/ru/post/308002/
  14. Я не хочу себя ставить в рамки узких возможностей, которые дают сурогаты. Базель имеет значения когда я сам компилирую tensorflow. Для меня задача минимум залинковать, извлечённую из pip пакета, поэтому базель меня щас не беспокоит. Почему у меня одного не работает ?
×