Прогнозирование тензорного потока с использованием tf.estimator.Estimator слишком медленное - PullRequest
0 голосов
/ 30 мая 2018

Я установил тензор потока в Raspberry Pi 3. Он использует предварительно обученную модель и функцию модели подачи в tf.estimator.Estimator.Мой проект использует c ++ и в настоящее время встраивает код Python, используя boost :: numpy, который преобразует матрицу 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) Может быть, 20-30 изображений формы [24,16,1] все еще очень тяжелые для rpi3: нет, это не было,Даже предсказание одного изображения заняло 3 ~ 4 секунды !!.

(3) Возможно, зацикливание результата генерации tf.Estimator.predict вызывает слишком долго: нет, это не так.Я изменил на yield_single_examples=False и все равно через 3 ~ 4 секунды после 1 звонка next.

я вызываю функцию ниже для передачи изображений и прогнозирования:

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, использующий raspberry pi 3 , который обрабатывает изображения больше моего входного изображения, а больший размер сети занял менее 2 секунд !!

Даже когда я вводил 1 изображение, а не 20 ~ 30 изображений в качестве входных данных, это все равно занимало 3 ~ 4 секунды ...

Что делает tf.estimator.Estimator медленным из моегоситуация?

...