Я установил тензор потока в 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 медленным из моегоситуация?