Несовместимая средняя точность с сверточной сетью, используемой в выходных данных локализации объекта
Я тренирую свою собственную систему локализации объектов с использованием тензорного потока, входные данные - изображения с формой (1170,765, 1)
и система просто имеет один целевой класс, мой выходной вектор y_hat
как следует: [P, x, y, w, h]
где P представляет вероятность присутствия объекта на изображении и x,y,w,h
являются координатами и размерами ограничительной рамки.
Принимая это во внимание, моя функция стоимости: (y_1)(MSE(y,y_hat)) + (1-y_1)(MSE(y_1,y_hat_1))
(Это было взято из глубокого обучения специализации Эндрю Нг).
Я вычисляю оценку AP с помощью следующей процедуры:
def AP(y,y_hat):
y_scores = y_hat[:,0]
y_hat_bbox = y_hat[:,1:]
y_bbox = y[:,1:]
y_true = np.zeros(y_scores.shape[0])
for i in range(y_true.shape[0]):
y_true[i] = iou(get_corners(y_hat_bbox[i]), get_corners(y_bbox[i]), True)
AP = average_precision_score(y_true = y_true, y_score = y_scores)
return AP
average_precision_score
это тот, который предоставлен scikit-Learn, и iou в основном возвращает 1.0, если значение iou превышает заданный порог, и 0.0 в противном случае
Я использую 3 сверточных слоя, два из которых с шагом 2, а затем три слоя максимального пула с шагом 4 (это имеет целью быстрое уменьшение размерности входных данных), наконец, 35 полностью связанных нейронов и последний выходной слой из 5 нейронов.,
Это тренировочная функция:
def conv_train(costW,LRates,RegParam):
costs = []
n_samples = X_train.shape[0]
varsnames = tf.trainable_variables()
lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in varsnames if 'bias' not in v.name]) * RegParam
cost_pos = costW*tf.multiply( y[:,0],tf.reduce_mean(tf.squared_difference(predictions,y),1))
cost_neg = tf.multiply(tf.subtract(1.0,y[:,0]),tf.squared_difference(predictions[:,0],y[:,0]))
cost = tf.reduce_mean(tf.add(cost_pos,cost_neg)) + lossL2
optimizer = tf.train.AdamOptimizer(learning_rate = LRates).minimize(cost)
tf.set_random_seed(1)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
seed = 0
for epoch in range(training_epochs):
epoch_cost = 0.
num_minibatches = int(n_samples / minibatch_size)
print("Epoca " + str(seed+1))
print(datetime.datetime.time(datetime.datetime.now()))
seed = seed + 1
minibatches = random_mini_batches(X_train, y_train,mini_batch_size=minibatch_size, seed=seed)
for minibatch in minibatches:
(minibatch_X, minibatch_y) = minibatch
_ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, y: minibatch_y})
epoch_cost += minibatch_cost / num_minibatches
print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
sys.stdout.flush()
costs.append(epoch_cost)
saver.save(sess, logPath + "/Model/model.ckpt")
plot_cost(costs)
test_results = predictions.eval({X: X_test})
train_result = predictions.eval({X: X_train})
AP_test = write_log(y = y_train, y_hat = train_result, flag = "Train")
AP = write_log(y = y_test, y_hat = test_results, flag = "Test")
sess.close()
return AP
Я планировал выполнить поиск по сетке, чтобы получить лучшую скорость обучения, параметр регуляризации и дополнительный вес, который влияет на часть функции стоимости, которая штрафует ограничивающие рамки.
APs = []
reg_params = np.power(2,np.linspace(-14,-6, num = 7))
LearningRates = np.power(2,np.linspace(-12,-7, num = 5))
cost_weights = np.power(2,np.linspace(2,5, num = 12))
for LR in LearningRates:
for reg_param in reg_params:
for cost_w in cost_weights:
tf.reset_default_graph()
imgRows, imgCols, n_channels = targetShape
X = tf.placeholder("float", [None, imgRows, imgCols, n_channels])
y = tf.placeholder("float", [None, 5])
predictions = conv_network_model(X,35)
AP = conv_train(cost_w,LR,reg_param)
APs.append(AP)
но потом я понял, что выполнение процедуры обучения с одинаковыми параметрами для одних и тех же данных (процедура мини-партии гарантирует, что для каждой тренировки мини-партии все эпохи будут одинаковыми, т.е. партия 1 эпохи 1 одинакова для первой и вторая тренировка) дает очень разные результаты для значения AP. Мне известно, что использование свертки с графическим процессором создает некоторую случайность, а также то, что начальные веса могут начинаться с очень разных позиций. Но различия между значениями AP огромны, например, после запуска ячейки 3 раза я получаю следующие результаты:
AP тренировка: 0,1846 - 0,3488 - 0,42
AP тест: 0,1203 - 0,4326 - 0,2254
У меня даже были случаи, когда AP на тестовом наборе была близка к 0,6, а после повторного запуска тренировочного процесса она снижалась до 0,3, что вдвое меньше!
Я не уверен, что моя реализация AP не правильна, это нормально, чтобы иметь такие разные результаты.