Jump to content
Compvision.ru

All Activity

This stream auto-updates     

  1. Yesterday
  2. А вот так почти сработало, только понять бы в чём разница с предыдущем вариантом. 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");
  3. Пока забил вручную: Но я не врублюсь какой размерности тензор создавать. В питоне было [-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 равное единице.
  4. Не уверен что хуже, задавать размер тензора вручную, или мешать C и C++, но так-то теоретически возможно: https://www.oracle.com/technetwork/articles/servers-storage-dev/mixingcandcpluspluscode-305840.html Может оптимально будет просто записывать при заморозке еще один файл, с дополнительной инфой ?
  5. Last week
  6. А C API можно миксить с С++ API ? Вот тут интересные рассуждения.
  7. Фильтрация облака точек

    попробую на днях
  8. Размер тензора вроде можно узнать, но мне надо конвертировать Node графа в тензор прежде и я без понятия как это сделать. Да я конечно могу сам забить размер, но както дико ненадёжное реение получается от таких кастылей. Второй вариант это всёже както сохранять аттрибуты в модели. Функция simple_save это както же делает. В любом случае спасибо. Мне важно знать как делают другие.
  9. Так там вроде как размеры тензоров при заморозке фиксируются, и надо самому их знать по модели. Вроде как получение размеров тензоров и не поддерживалось. Но тут у меня опыта немного, могу ошибаться.
  10. Замарозку делал вот так: 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)
  11. Более подробно расписал в новой теме.
  12. Когда у меня была незамароженная модель я без труда определял размерность входного и выходного узла графа загруженной модели вот таким образом: 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; } } Список узлов я по прежнему получаю, но при попытки получить размерность имею большой облом. Подскажите пожалуйста как получить размерность хотябы входного и выходного узла. Я же должен знать тензоры каких размерностей надо создавать для интеграции модели в приложение. Документации по теме нет и я буду рад любым рассуждениям, которые могут навести на путь истинный.
  13. Фильтрация облака точек

    Я бы вот эти методы попробовал бы. http://ceur-ws.org/Vol-2391/paper23.pdf Медианы она когда у вас много кадров. А тут явно по 1 снимку восстанавливают. Нужно отсеявать по аналогии с мат.морфологий,- если точка имеет более 2-х соседний на расстоянии L то оставляем. Если соседний менее или вовсе, нет то удаляем. Можно ещё как тут. При еденичных и малом числе фото. https://vision.in.tum.de/data/datasets/intrinsic3d Нейронные сети https://vision.in.tum.de/research/image-based_3d_reconstruction/singleviewreconstruction
  14. Спасибо, интересная утилита. Но у меня после всех оптимизаций кудато потерялись атрибуты и код: 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; } приводит к исключению:
  15. Фильтрация облака точек

    Не пробовал, но кажется, что как и для 2D: медианная фильтрация, например.
  16. Кто-нибудь занимался фильтрацией точек в 3d облаке. Как такие (см. рис) выбросы можно отфильтровать?
  17. Кстати, еще подумалось, ведь уровень абстракции сети растет от входа к выходу, то есть чтобы получить признаки для описания конкретного экземпляра объекта, нужно просто отрезать побольше выходных слоев.
  18. Earlier
  19. Подкину еще один скрипт, выдранный из работающего проекта. FreezeMe.py тут некоторых вещей нехватает, но может чем и пригодится. И еще, чтобы смотреть что записалось попробуйте Netron, я его как то уже упоминал.
  20. железо для openCV

    Такое делаете ? (интересно) А если по вопросу, то я например сейчас все решения свои адаптирую под ARM (Расберри, нанопи). Если захотеть, то решения можно запустить на чем угодно...
  21. использую такой скрипт для иvпорта в opencv, сверточные слои работают #region Imports from tensorflow.python.tools import freeze_graph import tensorflow as tf import numpy as np from keras.models import Model # basic class for specifying and training a neural network from keras.layers import Input, Dense # the two types of neural network layer we will be using from keras.utils import np_utils # utilities for one-hot encoding of ground truth values from keras.models import Sequential from keras.layers import Input, Convolution2D, MaxPooling2D, Dense, Dropout, Flatten, Reshape, Activation from keras.engine.topology import InputLayer from keras.layers.core import Dense as DenseLayer from keras import backend as K import os from tensorflow.core import framework #endregion def find_all_nodes(graph_def, **kwargs): for node in graph_def.node: for key, value in kwargs.items(): if getattr(node, key) != value: break else: yield node raise StopIteration def find_node(graph_def, **kwargs): try: return next(find_all_nodes(graph_def, **kwargs)) except StopIteration: raise ValueError( 'no node with attributes: {}'.format( ', '.join("'{}': {}".format(k, v) for k, v in kwargs.items()))) def walk_node_ancestors(graph_def, node_def, exclude=set()): openlist = list(node_def.input) closelist = set() while openlist: name = openlist.pop() if name not in exclude: node = find_node(graph_def, name=name) openlist += list(node.input) closelist.add(name) return closelist def remove_nodes_by_name(graph_def, node_names): for i in reversed(range(len(graph_def.node))): if graph_def.node[i].name in node_names: del graph_def.node[i] def make_shape_node_const(node_def, tensor_values): node_def.op = 'Const' node_def.ClearField('input') node_def.attr.clear() node_def.attr['dtype'].type = framework.types_pb2.DT_INT32 tensor = node_def.attr['value'].tensor tensor.dtype = framework.types_pb2.DT_INT32 tensor.tensor_shape.dim.add() tensor.tensor_shape.dim[0].size = len(tensor_values) for value in tensor_values: tensor.tensor_content += value.to_bytes(4, 'little') output_shape = node_def.attr['_output_shapes'] output_shape.list.shape.add() output_shape.list.shape[0].dim.add() output_shape.list.shape[0].dim[0].size = len(tensor_values) def make_cv2_compatible(graph_def): # A reshape node needs a shape node as its second input to know how it # should reshape its input tensor. # When exporting a model using Keras, this shape node is computed # dynamically using `Shape`, `StridedSlice` and `Pack` operators. # Unfortunately those operators are not supported yet by the OpenCV API. # The goal here is to remove all those unsupported nodes and hard-code the # shape layer as a const tensor instead. for reshape_node in find_all_nodes(graph_def, op='Reshape'): # Get a reference to the shape node shape_node = find_node(graph_def, name=reshape_node.input[1]) # Find and remove all unsupported nodes garbage_nodes = walk_node_ancestors(graph_def, shape_node, exclude=[reshape_node.input[0]]) remove_nodes_by_name(graph_def, garbage_nodes) # Infer the shape tensor from the reshape output tensor shape if not '_output_shapes' in reshape_node.attr: raise AttributeError( 'cannot infer the shape node value from the reshape node. ' 'Please set the `add_shapes` argument to `True` when calling ' 'the `Session.graph.as_graph_def` method.') output_shape = reshape_node.attr['_output_shapes'].list.shape[0] output_shape = [dim.size for dim in output_shape.dim] # Hard-code the inferred shape in the shape node make_shape_node_const(shape_node, output_shape[1:]) def Save2(model_name,model): sess = K.get_session() graph_def = sess.graph.as_graph_def(add_shapes=True) graph_def = tf.graph_util.convert_variables_to_constants(sess, graph_def, [model.output.name.split(':')[0]]) make_cv2_compatible(graph_def) # Print the graph nodes print('\n'.join(node.name for node in graph_def.node)) # Save the graph as a binary protobuf2 file tf.train.write_graph(graph_def, '', model_name+'.pb', as_text=False) само сохранение такое (model это keras, backend tf): import TFfreez TFfreez.Save2("d://number.pb",model )
  22. железо для openCV

    Коллеги, как подобрать железо для opencv, в интернете сотни статей для железа для machinelearning, а вот как собрать комп для машинного зрения. Вкратце, моя история, я отслеживаю перемещению муравей в аквариуме- научный интерес, но постоянно имею проблемы, потеря объекта, они сволочи дергаются порой, так же, я могу следить в один момент только за 4 - иначе комп виснет, но тут понятно, наверное, комп мощнее, ну а в плане отслеживания, можно ли как то сделать чтобы повысить возможности openCV, я как вижу, купить самую навороченную камеру и под нее подобрать видеокарту и проц мощнее, это верно? что можно сделать я использовал следующие функции 1.tracking - cv2.TrackerCSRT_create () и др, 2.hara cascade, 3.color tracking, 4.optical flow, 5. frame difference, может что забыл?
  23. Ага спасибо, только щас про него вспомнил. Он как раз с заморозкой.
  24. Добрый день, подскажите пожалуйста как правильно "заморозить" модель 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()
  25. Ну тут от сети зависит, есть ведь сети для распознавания лиц, например. Что мешает обучить сеть на пешеходах под разными углами зрения, и научить извлекать признаки для различения их между собой. И соорудить каскад, тип объекта + дескриптор.
  26. Smorodov, это то, что называется re-id. Кажется, что оно может плохо работать, ведь сеть обучается не различать отдельные объекты между собой, а отличать типы объектов. Кажется, что все люди будут близки друг с другом, машины друг с другом, а надо ещё и их различать между собой. Впрочем, я тут ещё не экспериментировал, надо попробовать, раз уж YOLO в проект проинтегрировано, благо и образец имеется. Надо ещё из OpenVINO потестить, у них есть обученная модель на "Identify Someone in Different Videos". Но это опять таки же сеть специально обученная различать пешеходов между собой. Также там есть "face reidentification" - различать лица между собой.
  27. По поводу нейронок, согласен, с мелкими объектами их применять проблематично. Но можно попробовать применить метод, похожий на распознавание лиц, когда вычисляют расстояние или угол между векторами, выдаваемыми сетью. Где то видел трекер, в котором используется подобная технология. Там берется что то вроде AlexNet и обрубается последний слой, и выходы предпоследнего слоя, используются как признаки для трекинга. Вот их и используют как часть метрики схожести, наряду с расстоянием и скоростью.
  28. У меня в этом вопросе есть нерешённая проблема с расстояниями, а именно с тем, как нормировать расстояние между центрами объектов или как для него выбирать правильный порог, не зная физической модели объектов. Если мы наблюдаем за людьми со стационарной камеры, висящей на потолке помещения, то отличной метрикой будет служить IoU (Жаккара), которое есть отношение площади пересечения прямоугольников к площади объединения и расстояние это будет лежать в интервале [0, 1]. Всё круто: объекты крупные, двигаются медленно, метрика адекватная. Но тут мы вешаем камеру повыше на улицу, объекты становятся меньше, где-то проносятся машины на большой скорости. Пролетела птица возле камеры и каждый её прямоугольник не пересекается с предыдущим. Или птица летит вдалеке и её прямоугольник настолько мал, что пересечения минимальны или также равны нулю. Поэтому мы начинаем измерять не IoU, а расстояние между центрами прямоугольников на текущем и предыдущем кадрах. Расстояние в пикселях и мы берём порог, равный десятой части кадра, например. Типа объект не может двигаться так быстро, чтобы пролететь/проехать слишком далеко. Но тут появляются сразу две проблемы: 1. Почему мы взяли 10-ю часть кадра? Очевидно, что для далёких объектов это слишком много, а для близких может быть и мало. Такое ощущение, что порог должен быть свой для каждого детектируемого объекта в зависимости от его размеров и расстояния до камеры. А если мы распознаём тип объекта, то и для типа: автомобиль может проехать с одной максимальной скоростью, а человек нет. 2. Если мы хотим использовать в качестве расстояния не только расстояние между центрами на текущем и предыдущем кадрах, а ещё и расстояние между, скажем, гистограммами, то получится, что они имеют совершенно разные размерности. Одно в пикселях, а другое относительно. Хочется первое тоже как-то нормировать от [0, 1], но непонятно как. Разделить на диагональ кадра будет слишком круто, значения окажутся черезчур маленькими. Как нормировать расстояние в пикселях? Кажется, что проблему так сходу не решить или решить только костылями. Делать калибровку камеры и считать расстояния не в пикселях, а в метрах. Это может помочь, если бы мы знали тип объекта и его размер, так как посчитать расстояние до него по одной камере не всегда возможно. То есть для людей и машин на одной плоскости это может быть хорошо, а с птицами на расстоянии 10 и 100 метров от камеры будет всё плохо. Да и откалибровать камеру редко когда можно. Хорошее распознавание может помочь: для людей, легковушек, велосипедов и т.п. можно задать средние размеры и средние скорости, строить модели движения и пороги индивидуально. Но это тоже не всегда выход, если нам надо детектировать всё движение и/или маленькие объекты. Нейросети плохо себя чувствуют, когда есть объект в 4-8 пикселей размером, их либо не задетектит, либо будет ооочень медленно. Да и не во всех задачах нейросети применимы. Напрашивается ещё решение: применять сначала какой-то средний порог в зависимости от размера объекта. Типа объект не может сдвинуться дальше, чем, скажем, три его диагонали. А далее брать из фильтра Кальмана его скорость и корректировать этот порог исходя ещё из скорости. соответственно и нормировать можно на него. Вооот. получился не столько вопрос, сколько рассуждения. Если у кого-то есть какие-нибудь мысли или успешный опыт решения проблемы - welcome.
  1. Load more activity
×