Проблемы с компиляцией Tensorflow Graph с помощью компилятора Google Vision Kit
Я (безуспешно) пытаюсь скомпилировать модель с помощью компилятора Aiy Vision Kit, чтобы использовать ее в Google Vision Kit, но я всегда получаю сообщение об ошибке в отношении замороженного графика. Я использую Keras с Tensorflow 1.15.
Я заморозил и сохранил свой график в файле.pb в соответствии с запросом компилятора. Сначала я использовал Tensorflow 2 (как сообщалось в этом другом вопросе, я задал Tensorflow 2.1/Keras - ошибка "output_node is not in graph" при попытке заморозить график, где также есть код, который я использую для замораживания), но компилятор сохранил выдает мне ошибку "output_node/Softmax не на графике", поэтому я переключился на TensorFlow 1.15, и теперь ошибка следующая:
2020-01-30 07:48:20.826925: F convert_tensorflow_graph.cc:83] Check failed: graph_def.ParseFromString(frozen_graph_contents) Could not parse GraphDef in "./frozen_graph.pb"
после того, как я запустил следующие команды:
--frozen_graph_path=./frozen_graph.pb \
--output_graph_path=./frozen_graph.binaryproto \
--input_tensor_name=input_node \
--output_tensor_names=output_node/Softmax\
--input_tensor_size=256 \
--debug
Из того, что я вижу в замороженном графике в файле.pbtxt, похоже, что модель, которую я создал с помощью Keras, и имена ввода и вывода верны, поэтому я не уверен, в чем заключаю ошибку.
Я запускаю компилятор на виртуальной машине Linux в соответствии с рекомендациями. Предварительно обученные модели, загруженные с сайта Aiy Vision Kit, успешно скомпилированы, поэтому я предполагаю, что проблема связана с моим файлом.pb, а не со средой.
Это код, который я использовал для создания и обучения модели:
input_layer=layers.Input(shape = (16,16,1), name = "input_node")
conv1=layers.Conv2D(64, kernel_size=(3, 3), activation='relu')(input_layer)
pool1=layers.MaxPooling2D((2, 2))(conv1)
conv2=(layers.Conv2D(128, kernel_size=(3, 3), activation='relu'))(pool1)
pool2=(layers.MaxPooling2D((2, 2), strides=1))(conv2)
conv3=(layers.Conv2D(256, kernel_size=(3, 3), activation='relu'))(pool2)
pool3=(layers.MaxPooling2D((2, 2), strides=1))(conv3)
flat=(layers.Flatten())(pool3)
dense1=(layers.Dense(128, activation='relu'))(flat)
dense2=(layers.Dense(units=num_classes))(dense1)
output=(layers.Softmax(name="output_node"))(dense2)
model = models.Model(input_layer, output)
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
return model
model=create_model()
model.summary()
history = model.fit(X_train, Y_train, epochs=25,
validation_data=(X_test, Y_test))
Я проверил, может ли Tensorflow проанализировать graph_def с помощью этого кода, и, похоже, он работает, и я получаю узлы с правильными именами и все такое.
f = gfile.FastGFile("./frozen_graph.pb", 'rb')
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
f.close()
Я также попытался создать модель с использованием последовательного кода со следующим кодом.
model=models.Sequential()
model.add(layers.Input(shape = (16,16,1), name = "input_node"))
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2), strides=1))
model.add(layers.Conv2D(256, kernel_size=(3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2), strides=1))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(units=num_classes))
model.add(layers.Softmax(name="output_node"))
model.compile(loss=krs.losses.categorical_crossentropy,
optimizer=krs.optimizers.Adadelta(),
metrics=['accuracy'])
model.summary()
history = model.fit(X_train, Y_train, epochs=25,
validation_data=(X_test, Y_test))
И я получаю одинаковое количество параметров и одинаковую точность / потери для обоих во время тренировки, поэтому я думал, что они в значительной степени эквивалентны. Вместо этого после сохранения в виде файла.h5, если я загружаю модель и распечатываю имя входного узла, он дает мне conv2d_input, как если бы он объединил входной слой и первый сверточный слой. В этом случае я получаю другую ошибку с компилятором Vision Kit:
./bonnet_model_compiler.par \
--frozen_graph_path=./frozen_graph2.pb \
--output_graph_path=./frozen_graph2.binaryproto \
--input_tensor_name=conv2d_input \
--output_tensor_names=output_node/Softmax\
--input_tensor_size=256 \
--debug
Errorr = 2020-01-31 01:30:27.240900: I external/org_tensorflow/tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before Removing unused ops: 35 operators, 50 arrays (0 quantized)
2020-01-31 01:30:27.241337: I external/org_tensorflow/tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before general graph transformations: 35 operators, 50 arrays (0 quantized)
2020-01-31 01:30:27.241414: F external/org_tensorflow/tensorflow/contrib/lite/toco/graph_transformations/propagate_fixed_sizes.cc:347] Check failed: output_depth == input_depth * op->depth_multiplier (64 vs. 192)input/output depths and depth_multiplier don't match
Обе модели были созданы с использованием классов Keras в TF 1.15, и обе были заморожены с помощью freeze_session (как это сделано здесь https://www.dlology.com/blog/how-to-convert-trained-keras-model-to-tensorflow-and-make-prediction/). Имена узлов должны быть сразу после проверки файла pbtxt и анализа файла graph_def.
Мы будем очень благодарны за любую помощь в решении этой проблемы.