#python #tensorflow #keras
#python #тензорный поток #keras
Вопрос:
У меня есть код, как показано ниже:
def yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = .6):
"""Filters YOLO boxes by thresholding on object and class confidence.
Arguments:
box_confidence -- tensor of shape (3, 3, 5, 1)
boxes -- tensor of shape (3, 3, 5, 4)
box_class_probs -- tensor of shape (3, 3, 5, 80)
threshold -- real value, if [ highest class probability score < threshold], then get rid of the corresponding box
Returns:
scores -- tensor of shape (None,), containing the class probability score for selected boxes
boxes -- tensor of shape (None, 4), containing (b_x, b_y, b_h, b_w) coordinates of selected boxes
classes -- tensor of shape (None,), containing the index of the class detected by the selected boxes
Note: "None" is here because you don't know the exact number of selected boxes, as it depends on the threshold.
For example, the actual output size of scores would be (10,) if there are 10 boxes.
"""
# Step 1: Compute box scores
box_scores = np.multiply(box_confidence, box_class_probs)
# Step 2: Find the box_classes thanks to the max box_scores, keep track of the corresponding score
box_classes = K.argmax(box_scores, -1)
box_class_scores = K.max(box_scores, -1)
# Step 3: Create a filtering mask based on "box_class_scores" by using "threshold". The mask should have the
# same dimension as box_class_scores, and be True for the boxes you want to keep (with probability >= threshold)
filtering_mask = K.greater_equal(box_class_scores,threshold)
# Step 4: Apply the mask to scores, boxes and classes
print(filtering_mask.shape)
print(filtering_mask.eval())
print(box_class_scores.shape)
print(box_class_scores.eval())
scores = tf.boolean_mask(box_class_scores, filtering_mask)
print(scores.eval())
boxes = tf.boolean_mask(boxes, filtering_mask)
classes = tf.boolean_mask(box_classes, filtering_mask)
return scores, boxes, classes
with tf.Session() as test_a:
box_confidence = tf.random_normal([3, 3, 5, 1], mean=1, stddev=4, seed = 1)
boxes = tf.random_normal([3, 3, 5, 4], mean=1, stddev=4, seed = 1)
box_class_probs = tf.random_normal([3, 3, 5, 80], mean=1, stddev=4, seed = 1)
scores, boxes, classes = yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = 0.5)
print("scores[2] = " str(scores[2].eval()))
print("boxes[2] = " str(boxes[2].eval()))
print("classes[2] = " str(classes[2].eval()))
print("scores.shape = " str(scores.shape))
print("boxes.shape = " str(boxes.shape))
print("classes.shape = " str(classes.shape))
и это результат:
(3, 3, 5)
[[[ True True True True True]
[ True True True True True]
[ True False True True True]]
[[ True True True True True]
[ True True True True True]
[ True True True True True]]
[[ True True True True False]
[ True True True True True]
[ True True True True True]]]
(3, 3, 5)
[[[ 45.00004959 21.20238304 17.39275742 26.73288918 49.47431946]
[ 22.16205978 27.96604347 12.38916492 33.66600418 62.04590225]
[ 113.03194427 2.68868852 6.33391762 45.17211914 10.5103178 ]]
[[ 8.22186852 35.88579941 48.54780579 12.48789883 32.40937042]
[ 75.73269653 17.52830696 62.99983597 29.0468502 42.82471848]
[ 72.42234039 108.19727325 36.93912888 40.9789238 36.91137314]]
[[ 1.57321405 3.35663748 16.33576775 5.16499805 19.43038177]
[ 48.13769913 68.20082092 47.06818008 1.82166731 67.30760956]
[ 33.01203537 63.93298721 9.71860027 49.06838989 60.74739456]]]
[ 22.63684464 10.29589462 58.76845551 74.67560577 20.25722504
47.24279022 6.96320772 22.59087944 86.61974335 1.05248117
57.47060394 92.50878143 16.8335762 23.29385757 78.58971405
6.95861435 65.61254883 45.47106171 43.53435135 10.0660677
60.34520721 28.5535984 15.9668026 45.14865494 5.49425364
2.35473752 29.40540886 2.5579865 46.96302032 9.39739799
45.78501892 49.42660904 34.68322754 40.72031784 58.91592407
35.39850616 56.24537277 6.80519342 9.52552414 138.54457092
14.07888412 56.37608719 69.59171295 25.83714676]
scores[2] = 62.0051
boxes[2] = [-1.89158893 0.7749185 3.57417917 -0.05729628]
classes[2] = 36
scores.shape = (?,)
boxes.shape = (?, 4)
classes.shape = (?,)
у меня простой вопрос. как появился scores
результат? он содержит 44 элемента, в то время как filtering_mask
и box_class_scores
имеют 45 элементов(3 * 3 * 5 ) и filtering_mask имеет 2 ложных значения, которые должны составлять 43 элемента. даже если filtering_mask имеет значение 1 false, ни одно из чисел в оценках не совпадает box_class_scores
.
кто-нибудь может объяснить мне, как scores
вычисляется
Ответ №1:
Проблема не в маскировке, которая работает так, как вы ожидаете. Проблема в том, что вы используете случайные значения в своем графике, поведение которых может быть немного неожиданным. Каждый раз, когда вы вызываете, eval()
это действительно вызов run
в сеансе по умолчанию. Проблема в том, как случайные значения работают в TensorFlow. Каждый раз, когда run
вызывается сеанс, генерируется новое случайное значение. Это означает, что каждый eval
вызов выдает результаты, основанные на разных значениях box_confidence
, boxes
и box_class_probs
. Есть возможные способы исправить это, либо просто не использовать генераторы случайных значений в качестве входных данных, либо оценивать все выходные данные в одном вызове run
(а не с eval
). Поскольку вы, похоже, пишете тестовый код, один простой способ решить эту проблему — заменить входные данные константами, созданными из случайных значений NumPy.
import tensorflow as tf
import numpy as np
def yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = .6):
# ...
with tf.Session() as test_a:
np.random.seed(1)
box_confidence = tf.constant(np.random.normal(loc=1, scale=4, size=[3, 3, 5, 1]), dtype=tf.float32)
boxes = tf.constant(np.random.normal(loc=1, scale=4, size=[3, 3, 5, 4]), dtype=tf.float32)
box_class_probs = tf.constant(np.random.normal(loc=1, scale=4, size=[3, 3, 5, 80]), dtype=tf.float32
scores, boxes, classes = yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = 0.5)
print("scores[2] = " str(scores[2].eval()))
print("boxes[2] = " str(boxes[2].eval()))
print("classes[2] = " str(classes[2].eval()))
print("scores.shape = " str(scores.shape))
print("boxes.shape = " str(boxes.shape))
print("classes.shape = " str(classes.shape))
Или вы все еще можете использовать случайные числа TensorFlow, но использовать переменные для своих входных данных. Разница с переменными заключается в том, что они оценивают свое начальное значение только при инициализации, а затем сохраняют свое значение среди сеансов (до тех пор, пока оно не будет изменено снова), поэтому вы не будете генерировать новые случайные значения каждый раз.
import tensorflow as tf
def yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = .6):
# ...
with tf.Session() as test_a:
box_confidence = tf.Variable(tf.random_normal([3, 3, 5, 1], mean=1, stddev=4, seed = 1)))
boxes = tf.Variable(tf.random_normal([3, 3, 5, 4], mean=1, stddev=4, seed = 1))
box_class_probs = tf.Variable(tf.random_normal([3, 3, 5, 80], mean=1, stddev=4, seed = 1))
# You must initialize the variables
test_a.run(tf.global_variables_initializer())
scores, boxes, classes = yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = 0.5)
print("scores[2] = " str(scores[2].eval()))
print("boxes[2] = " str(boxes[2].eval()))
print("classes[2] = " str(classes[2].eval()))
print("scores.shape = " str(scores.shape))
print("boxes.shape = " str(boxes.shape))
print("classes.shape = " str(classes.shape))