使用tf.estimator.Estimator的Tensorflow预测太慢

时间:2018-05-30 13:14:51

标签: python tensorflow machine-learning raspberry-pi3 boost-python

我在树莓派3中安装了张量流。它将预训练模型和饲料模型功能用于tf.estimator.Estimator。我的项目是使用c ++,目前使用boost :: numpy嵌入python代码,将opencv矩阵转换为numpy类型,并将其传递给python函数进行预测并获得结果。我的模型函数定义如下。只有传播部分:

def cnn_estimator_fn(features, labels, mode):

inputs=tf.reshape(features[FEATURE_LABEL],[-1,24,16,1],name="input_node") #24 x 16 x 1, which is gray or binary image and same number of samples

conv1=tf.layers.conv2d(inputs=inputs,
                       filters=6,
                       kernel_size=[5,5],
                       padding='same',
                       activation=tf.nn.leaky_relu
                       )
#conv1 output shape: (batch_size,24,16,6)

pool1=tf.layers.max_pooling2d(inputs=conv1,pool_size=[2,2],strides=2,padding='valid')

#pool1 output shape: (batch_size,12,8,6)

conv2=tf.layers.conv2d(inputs=pool1,filters=12,kernel_size=[5,5],padding='same',activation=tf.nn.leaky_relu)

#conv2 output shape: (batch_size, 12,8,12)

pool2=tf.layers.max_pooling2d(inputs=conv2,pool_size=[2,2],strides=2,padding='valid')

#pool2 output shape: (batch_size, 6,4,12)


#dense fully connected layer
pool2_flat=tf.reshape(pool2,[-1,6*4*12]) #flatten pool2 output to feed in dense layer
dense1=tf.layers.dense(inputs=pool2_flat,units=144,activation=tf.nn.leaky_relu)
#apply dropout to avoid overfitting
dropout=tf.layers.dropout(inputs=dense1,rate=0.3,training=mode==tf.estimator.ModeKeys.TRAIN)

logits=tf.layers.dense(dropout,11) #input for softmax layer

嗯,它的制作很差但是我的网络规模足以满足rpi3规范。但是当我通过将这个函数输入到tf.estimator.Estimator并调用tf.estimator.predict进行预测时,预测20个图像需要3~5秒,每个形状都是[24,16,1]。这太慢了!!

我尝试了以下假设成为问题,没有一个是正确的:

(1)将vector<cv::Mat>>转换为boost :: numpy需要太长时间:不,它不是因为花了0.00023秒。

(2)对于rpi3,可能20~30张形状[24,16,1]的图像仍然非常重:不,它不是。即使预测1张图像也需要3~4秒!!

(3)可能循环tf.Estimator.predict调用的生成器结果花费的时间太长了:不,它不是。我改为yield_single_examples=False,在拨打next后仍然需要3到4秒。

我调用下面的函数来传递图像并预测:

def predict_model(img_list: list):

    predict_input = np.asarray(img_list,dtype=np.float32)

    predict_input/=255

    lpr_letter_classifier = tf.estimator.Estimator(cnn_estimator_fn,
    model_dir=model_dir)

    predict_input_fn = tf.estimator.inputs.numpy_input_fn({FEATURE_LABEL: predict_input},
                                                  y=None,
                                                  batch_size=len(img_list),
                                                  num_epochs=1,
                                                  shuffle=False)    

    pred_dict_gen = lpr_letter_classifier.predict(predict_input_fn, yield_single_examples=False)    

    t0=time.time()

    pred_dict_list=next(pred_dict_gen)

    print("pred time: "+str(time.time()-t0))

    class_id = pred_dict_list["classes"]
    probability = pred_dict_list["probabilities"]

所以我现在的猜测是,也许有一个代码,每当我调用predict_model(img_list: list)时它会初始化图形,因此预测时间太长。在那里,在代码中,

t0=time.time()

pred_dict_list=next(pred_dict_gen)

print("pred time: "+str(time.time()-t0))

我在调用next(pred_dict_gen)之后测量了时间,在yield_single_examples=False模式下,花了3~4秒。当我将预测模式更改为yield_single_examples=True时,第一次拨打next(pred_dict_gen)仍需要3~4秒和第二次next(pred_dict_gen)来电,需要0.000034秒或更短时间。所以我想首先调用next对整个输入图像执行预测,然后调用是每个图像预测的结果。哇...我强烈认为这不是rpi3性能问题,因为我看到squeezenet using raspberry pi 3执行的图像比我的输入图像更大,更大的网络大小花了不到2秒!!

即使我输入1张图像,而不是20~30张图像作为输入,仍然需要3~4秒...

是什么让tf.estimator.Estimator从我的情况变慢?

0 个答案:

没有答案