+ label = None
+ filtered_lines = []
+ with open(features, 'r') as rf:
+ lines = rf.readlines()
+ for line in lines:
+ line = line[:-1]
+ if line.startswith(label_label):
+ label = ''.join(line.split(':')[1:])
+ label = label.strip()
+ else:
+ filtered_lines.append(line)
+
+ if not helper.is_valid_example(image, features, filtered_lines):
+ logger.warning('%s/%s: Invalid example.', image, features)
+ if config.config['ml_quick_label_delete_invalid_examples']:
+ os.remove(image)
+ os.remove(features)
+ continue
+
+ if label and not config.config['ml_quick_label_overwrite_labels']:
+ logger.warning('%s/%s: already has label, SKIPPING.', image, features)
+ continue
+
+ if config.config['ml_quick_label_skip_where_model_agrees']:
+ model_says = helper.ask_current_model_about_example(image, features, filtered_lines)
+ if model_says and label:
+ if model_says[0] == int(label):
+ continue
+ print(f'{image}/{features}: The model disagrees with the current label.')
+ print(f' ...model says {model_says[0]} with probability {model_says[1]}.')
+ print(f' ...the example is currently labeled {label}')
+ filtered_images.append((image, features))
+ return filtered_images
+
+
+def quick_label(helper: QuickLabelHelper) -> None:
+ skip_list = _maybe_read_skip_list()
+
+ # Ask helper for an initial set of files.
+ images = helper.get_candidate_files()
+ if len(images) == 0:
+ logger.warning('No images files to operate on.')
+ return
+
+ # Filter out any that can't be converted to features or already have a
+ # label (unless they used --ml_qukck_label_overwrite_labels).
+ filtered_images = _filter_images(images, skip_list, helper)
+ if len(filtered_images) == 0:
+ logger.warning('No image files to operate on (post filter).')
+ return
+
+ # Allow the user to label the non-filtered images one by one.
+ import input_utils
+
+ cursor = 0
+ label_label = helper.get_label_feature()
+ while True:
+ assert 0 <= cursor < len(filtered_images)
+
+ image = filtered_images[cursor][0]
+ assert os.path.exists(image)
+ features = filtered_images[cursor][1]
+ assert features and os.path.exists(features)
+