Я (безуспешно) пытаюсь скомпилировать модель с помощью компилятора Aiy Vision Kit, чтобы я мог использовать ее в Google Vision Kit, но я всегда получаю сообщение об ошибке в замороженном графике. Я использую Keras с Tensorflow 1.15.
Я заморозил и сохранил свой график в файле .pb в соответствии с запросом для компилятора. Сначала я использовал Tensorflow 2 (как сообщалось в этом другом вопросе, который я задал Tensorflow 2.1 / Keras - ошибка «output_node is in graph» при попытке заморозить граф , где также есть код, который я использую для замораживания ), но компилятор продолжал выдавать мне ошибку «output_node / Softmax is not in graph», поэтому я переключился на 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()
Я также попытался создать модель с использованием Sequential со следующим кодом:
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 (как здесь сделано * 1030) *). Имена узлов должны быть правильными после проверки файла pbtxt и синтаксического анализа graph_def.
Любая помощь в решении этой проблемы будет принята с благодарностью.