Точная настройка обнаружения объекта Tensorflow приводит к неверным значениям точности
Я работаю с Tensorflow Object-Detection API и хочу использовать предварительно обученную модель Faster R-CNN Resnet101 для данных изображений Kitti и настраивать ее для данных изображений Cityscapes. Я скачал предварительно обученную модель здесь.
Этот скрипт создает файлы tfrecord. Я использую этот скрипт для создания файлов tfrecord из изображений Cityscape (CS).
CS tf_records впоследствии используется для точной настройки предварительно обученной модели Resnet. Для этой задачи я использую это
python3.5 model_main.py --pipeline_config_path={Path to config file in ../samples/configs/} --model_dir={Output directory} --num_train_steps={Train Steps} --sample_1_of_n_eval_examples=1 --alsologtostderr
Использование только данных CS Training and Validation приводит к точности COCO -1,000
Average Precision (AP) @[ IoU=0.5:0.95 | area=all | maxDets=100 ] = -1.000
....
Я пробовал разные вещи:
Тренируйтесь на данных CS и проверяйте на данных Kitti. Это приводит к точности COCO, которая не -1000, но очень низкая. От 0,01 до 1,5% (после 10 000 шагов обучения)
Посмотрел на визуализации Tensorboard. Потери падают с 0,05 до 0,01 в течение первых 1,500 итераций и остаются на последних 8,500 итерациях в районе 2,5e-4 и практически не меняются. (Я бы загрузил изображение, если бы я знал, как..)
Точная настройка предварительно обученной модели с использованием данных Китти. Я изменил содержимое файлов tfrecord, которые создают файлы Kitti tfrecord. Под этим я подразумеваю, что я удалил все бесполезные переменные (например, 3D-аннотации и т. Д.) В данных tfrecord, чтобы иметь содержимое, аналогичное созданному CS tfrecords (код ниже). Использование этих манипулированных данных Китти также приводит к точности проверки, которая кажется нормальной (около 70-80%). Поэтому я ожидаю, что эта ошибка не вызвана отсутствующим атрибутом в tfrecords.
Вывод данных CS на предварительно обученной модели Resnet приводит к точности около 20%, и это то, что я ожидаю. Вывод Китти приводит к точности около 85%.
Использование CS tfrecords со следующим содержанием на изображение:
tf_example = tf.train.Example(features=tf.train.Features(feature={
'image/height': dataset_util.int64_feature(height),
'image/width': dataset_util.int64_feature(width),
'image/filename': dataset_util.bytes_feature(filename.encode('utf8')),
'image/source_id': dataset_util.bytes_feature(filename.encode('utf8')),
'image/encoded': dataset_util.bytes_feature(encoded_image_data),
'image/format': dataset_util.bytes_feature(image_format.encode('utf8')),
'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
'image/object/difficult': dataset_util.int64_list_feature(difficult_obj),
'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
'image/object/class/label': dataset_util.int64_list_feature(classes),
}))
return tf_example
Используя этот код для кодирования изображения
with tf.gfile.GFile(os.path.join(image_path, '{}'.format(currentImageName)), 'rb') as fid:
encoded_image_data = fid.read()
encoded_image_io = io.BytesIO(encoded_image_data)
Может ли быть причиной кодирование данных? Или что может быть другим источником ошибки? Как уже упоминалось, я пробовал несколько вещей, и ни одна из них не работала, как ожидалось. Тонкая настройка не должна быть такой сложной, или мне не хватает какой-либо точки?
Как упоминалось в пункте 4, я проверил файлы логического вывода и файлы tf_record, и, следовательно, я ожидаю, что можно уточнить модель.
В целом, я ожидаю, что точность не будет близка к 0% после 10.000 итераций.
Все выглядит немного странно, и я не знаю, в чем ошибка. Поэтому я был бы признателен за каждую подсказку / замечание / решение этой проблемы.
РЕДАКТИРОВАТЬ:
def create_tf_example(currentName, anno_path, image_path):
currentNameSplit = currentName.split('.')[0]
currentImageName = currentNameSplit + '.png'
with tf.gfile.GFile(os.path.join(image_path, '{}'.format(currentImageName)), 'rb') as fid:
encoded_image_data = fid.read()
encoded_image_io = io.BytesIO(encoded_image_data)
image = Image.open(encoded_image_io)
image = np.asarray(image)
width = int(image.shape[1])
height = int(image.shape[0])
filename = os.path.join(image_path, '{}'.format(currentImageName))
image_format = 'png' # b'jpeg' or b'png'
with open(anno_path + currentName) as file:
lines = file.readlines()
xmins = [] # List of normalized left x coordinates in bounding box (1 per box)
xmaxs = [] # List of normalized right x coordinates in bounding box
# (1 per box)
ymins = [] # List of normalized top y coordinates in bounding box (1 per box)
ymaxs = [] # List of normalized bottom y coordinates in bounding box
# (1 per box)
classes_text = [] # List of string class name of bounding box (1 per box)
classes = [] # List of integer class id of bounding box (1 per box)
for li in range(len(lines)):
print('Lines[li]: {}'.format(lines[li]))
xmins.append(float(lines[li].split()[0]) / width)
xmaxs.append(float(lines[li].split()[2]) / width)
ymins.append(float(lines[li].split()[1]) / height)
ymaxs.append(float(lines[li].split()[3]) / height)
classID = lines[li].split()[4]
if int(classID) == 0:
className = 'Car'
classes_text.append(className.encode('utf8'))
classID = 0
classes.append(classID+1) # add 1 because class 0 is always reserved for 'background'
elif int(classID) == 1:
className = 'Person'
classes_text.append(className.encode('utf8'))
classID = 1
classes.append(classID+1)
else:
print('Error with Image Annotations in {}'. format(currentName))
difficult_obj = [0] * len(xmins)
tf_example = tf.train.Example(features=tf.train.Features(feature={
'image/height': dataset_util.int64_feature(height),
'image/width': dataset_util.int64_feature(width),
'image/filename': dataset_util.bytes_feature(filename.encode('utf8')),
'image/source_id': dataset_util.bytes_feature(filename.encode('utf8')),
'image/encoded': dataset_util.bytes_feature(encoded_image_data),
'image/format': dataset_util.bytes_feature(image_format.encode('utf8')),
'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
'image/object/difficult': dataset_util.int64_list_feature(difficult_obj),
'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
'image/object/class/label': dataset_util.int64_list_feature(classes),
}))
return tf_example
def main(_):
writer_training = tf.python_io.TFRecordWriter(FLAGS.output_path_Training)
writer_valid = tf.python_io.TFRecordWriter(FLAGS.output_path_Test)
writer_test = tf.python_io.TFRecordWriter(FLAGS.output_path_Valid)
allAnnotationFiles = []
os.chdir(FLAGS.anno_path)
for file in sorted(glob.glob("*.{}".format('txt'))):
allAnnotationFiles.append(file)
counter=0
for currentName in allAnnotationFiles:
if counter < 2411:
tf_example = create_tf_example(currentName, FLAGS.anno_path, FLAGS.image_path)
writer_training.write(tf_example.SerializeToString())
counter += 1
elif counter > 2411 and counter < 2972:
tf_example = create_tf_example(currentName, FLAGS.anno_path, FLAGS.image_path)
writer_valid.write(tf_example.SerializeToString())
counter += 1
elif counter <= 3475:
tf_example = create_tf_example(currentName, FLAGS.anno_path, FLAGS.image_path)
writer_test.write(tf_example.SerializeToString())
counter += 1
writer_training.close()
writer_test.close()
writer_valid.close()
if __name__ == '__main__':
tf.app.run()