代码之家  ›  专栏  ›  技术社区  ›  TripleS

如何在OpenCV中加载带有tensorflow后端的Keras模型构建

  •  1
  • TripleS  · 技术社区  · 6 年前

    tensorFlowSession = K.get_session()
    tf.saved_model.simple_save(tensorFlowSession, newpath + "/TensorFlow", inputs={"x": x}, outputs={"y": y})
    tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow",  "trainGraph_def.pbtxt")
    

    然后我尝试在python中使用opencv加载保存的模型,我从python中的opencv开始,但是在c++中使用opencv时遇到了类似的错误。

    net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
    

    问题是opencv无法加载tensorflow图,我得到一个错误-

    Saving and loading a tensorflow graph using opencv 应该很直截了当,我在这里遗漏了什么?见附件我的代码。

    '''Trains a simple convnet on the MNIST dataset.
    Gets to 99.25% test accuracy after 12 epochs
    (there is still a lot of margin for parameter tuning).
    16 seconds per epoch on a GRID K520 GPU.
    '''
    
    from __future__ import print_function
    import keras
    from keras.datasets import mnist
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Flatten
    from keras.layers import Conv2D, MaxPooling2D
    from keras import backend as K
    import tensorflow as tf
    import datetime
    import cv2 as cv
    from pathlib import Path
    import numpy as np
    from os import listdir
    from os.path import isfile, join
    import os
    os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
    
    batch_size = 128
    num_classes = 10
    epochs = 1
    
    # input image dimensions
    img_rows, img_cols = 28, 28
    
    # the data, split between train and test sets
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    
    if K.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)
    
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train /= 255
    x_test /= 255
    print('x_train shape:', x_train.shape)
    print(x_train.shape[0], 'train samples')
    print(x_test.shape[0], 'test samples')
    
    # convert class vectors to binary class matrices
    y_train = keras.utils.to_categorical(y_train, num_classes)
    y_test = keras.utils.to_categorical(y_test, num_classes)
    
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3),
                     activation='relu',
                     input_shape=input_shape))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))
    
    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])
    
    model.fit(x_train, y_train,
              batch_size=batch_size,
              epochs=epochs,
              verbose=1,
              validation_data=(x_test, y_test))
    score = model.evaluate(x_test, y_test, verbose=0)
    print('Test loss:', score[0])
    print('Test accuracy:', score[1])
    
    # Save as tensor flow graph
    # Save the model to pd file
    exportModelDir = '/home/iaiai/Documents/Shahar/DataSets/TrainedNetworks/MnistKeras/'
    newpath = exportModelDir + str(datetime.datetime.now())
    print ("output dir", newpath)
    if not os.path.exists(newpath):
        os.makedirs(newpath)
    
    x = tf.placeholder(dtype=tf.float32, shape=input_shape)
    y = tf.placeholder(dtype=tf.float32, shape=num_classes)
    tensorFlowSession = K.get_session()
    tf.saved_model.simple_save(tensorFlowSession, newpath + "/TensorFlow", inputs={"x": x}, outputs={"y": y})
    
    # with tf.Session() as sess:
    #     tf.train.Saver(tf.trainable_variables()).save(sess, newpath + "/TensorFlow/" + 'saveTrainableVariables')
    if not os.path.exists(newpath + "/TensorFlow/" + 'saveTrainableVariables/'):
        os.makedirs(newpath + "/TensorFlow/" + 'saveTrainableVariables/')
    tf.train.Saver(tf.trainable_variables()).save(tensorFlowSession, newpath + "/TensorFlow/saveTrainableVariables/" + 'saveTrainableVariables')
    
    # Write graph in tensorflow format
    tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow", "trainGraph_def.pbtxt")
    tf.train.write_graph(tensorFlowSession.graph,newpath + "/TensorFlow", "trainGraph.pbtxt")
    tf.train.write_graph(tensorFlowSession.graph_def,newpath + "/TensorFlow", "trainGraph_def_notAsText.pbtxt", False)
    
    # now try to load the tensorflow graph from opencv python module
    net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
    

        [libprotobuf ERROR /io/opencv/3rdparty/protobuf/src/google/protobuf/wire_format_lite.cc:629] String field 'tensorflow.FunctionDef.Node.ret' contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes. 
    Traceback (most recent call last):
      File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1664, in <module>
        main()
      File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1658, in main
        globals = debugger.run(setup['file'], None, None, is_module)
      File "/snap/pycharm-community/79/helpers/pydev/pydevd.py", line 1068, in run
        pydev_imports.execfile(file, globals, locals)  # execute the script
      File "/snap/pycharm-community/79/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
        exec(compile(contents+"\n", file, 'exec'), glob, loc)
      File "/home/iaiai/Documents/Shahar/Project2/MnistKerasExport/mnist_cnn.py", line 106, in <module>
        net = cv.dnn.readNet(newpath + '/TensorFlow/' + 'saved_model.pb', newpath + '/TensorFlow/' + 'trainGraph.pbtxt')
    cv2.error: OpenCV(3.4.2) /io/opencv/modules/dnn/src/tensorflow/tf_io.cpp:44: error: (-2:Unspecified error) FAILED: ReadProtoFromBinaryFile(param_file, param). Failed to parse GraphDef file: /home/iaiai/Documents/Shahar/DataSets/TrainedNetworks/MnistKeras/2018-09-06 08:35:34.025216/TensorFlow/saved_model.pb in function 'ReadTFNetParamsFromBinaryFileOrDie'
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   paul    6 年前

    与my net相同,但使用*.pbtxt文件。

      FAILED: ReadProtoFromTextFile(param_file, param). Failed to parse GraphDef file: ./output_graph.pbtxt"    char *
    

    使用*.pb似乎没问题,下面是生成它的代码:

           output_nodes = [n.name for n in tf.get_default_graph().as_graph_def().node]
           # Freeze the graph
            frozen_gdef = tf.graph_util.convert_variables_to_constants(
                sess,
                sess.graph_def,
                output_nodes)
    
            # Save the frozen graph
            with open('./model/output_graph.pb', 'wb') as f:
                f.write(frozen_gdef.SerializeToString())
    

    希望对你有帮助!

    如果你的*.pbtxt可以,请告诉我