CharlesCNorton
Image-level person classification on EUPE-ViT-B features with no free parameters
e8b8483 | """The rules are well formed and say the same thing everywhere they appear.""" | |
| import pytest | |
| from conftest import load | |
| RULE_NAMES = sorted(load('rules.json')['rules']) | |
| def test_sets_are_disjoint_and_balanced(name, rules): | |
| r = rules['rules'][name] | |
| pos, neg = r['pos_dims'], r['neg_dims'] | |
| assert len(pos) == len(neg), f'{name}: the two sums must have equal term counts' | |
| assert not set(pos) & set(neg), f'{name}: a dim appears on both sides' | |
| assert len(set(pos)) == len(pos) and len(set(neg)) == len(neg) | |
| assert r['n_dims'] == len(pos) + len(neg) | |
| def test_dims_are_in_range(name, rules): | |
| for d in rules['rules'][name]['pos_dims'] + rules['rules'][name]['neg_dims']: | |
| assert 0 <= d < 768 | |
| def test_no_free_parameters(name, rules): | |
| assert rules['rules'][name]['free_parameters'] == 0 | |
| def test_name_matches_size(name, rules): | |
| assert name == f'd{rules["rules"][name]["n_dims"]}' | |
| def test_rules_nest(rules): | |
| """Greedy selection grows the sets, so each rule extends the one below it.""" | |
| by_size = sorted(rules['rules'].values(), key=lambda r: r['n_dims']) | |
| for small, large in zip(by_size, by_size[1:]): | |
| assert small['pos_dims'] == large['pos_dims'][:len(small['pos_dims'])] | |
| assert small['neg_dims'] == large['neg_dims'][:len(small['neg_dims'])] | |
| def test_eval_carries_the_same_dims(name, rules, evaluation): | |
| r, e = rules['rules'][name], evaluation['rules'][name] | |
| assert e['pos_dims'] == r['pos_dims'] | |
| assert e['neg_dims'] == r['neg_dims'] | |
| assert e['F1_train'] == r['F1_train'] | |
| def test_more_dims_do_not_score_worse(evaluation): | |
| by_size = sorted(evaluation['rules'].values(), key=lambda r: r['n_dims']) | |
| f1 = [r['F1'] for r in by_size] | |
| assert f1 == sorted(f1), f'F1 is not monotone in dim count: {f1}' | |
| def test_val_tracks_train(evaluation): | |
| """Selection on 118k images should not overfit; val must stay close to train.""" | |
| for name, r in evaluation['rules'].items(): | |
| assert abs(r['F1'] - r['F1_train']) < 0.02, \ | |
| f'{name}: train {r["F1_train"]} against val {r["F1"]}' | |