File size: 2,727 Bytes
8e5456b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #!/usr/bin/env python3
"""Fan the existing BARTpho gloss predictions out to all three views.
`output_vsl/text2gloss/pred_full_trivis.json` is keyed by front-view clip name. The
left/right clips of the same recording carry the SAME sentence and the SAME reference
gloss, only a different camera, so no model run is needed -- the prediction is a function
of the sentence alone. Rebuilding the map sentence -> prediction and re-emitting it per
clip of the 3-view CSV keeps the predictions bit-identical to the front-only evaluation,
which is what makes the two comparable.
"""
import argparse
import collections
import csv
import json
import os
REPO = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
def signs(s):
parts = [t.strip() for t in str(s).split('|')] if '|' in str(s) else str(s).split()
return [p for p in parts if p]
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--pred', default='output_vsl/text2gloss/pred_full_trivis.json')
ap.add_argument('--csv', default=os.path.join(REPO, 'Full_TriVis',
'split_lab_3view.csv'))
ap.add_argument('--out', default='output_vsl/text2gloss/pred_3view.json')
args = ap.parse_args()
with open(args.pred, encoding='utf-8') as f:
pred = json.load(f)
by_sent = {}
for v in pred.values():
by_sent.setdefault(v['sentence'], (v['pred_gloss'], v['pred_signs']))
print(f'{len(pred)} front clips -> {len(by_sent)} distinct sentences with a prediction')
out, miss = {}, 0
with open(args.csv, newline='', encoding='utf-8') as f:
rows = list(csv.DictReader(f))
for r in rows:
name = os.path.splitext(os.path.basename(r['npz_path']))[0]
hit = by_sent.get(r['Sentence'].strip())
if hit is None:
miss += 1
continue
pg, ps = hit
out[name] = {'split': r['split'], 'view': r['view'],
'sentence': r['Sentence'].strip(),
'pred_gloss': pg, 'pred_signs': ps,
'ref_gloss': ' '.join(signs(r['Sign_sentence'])),
'ref_signs': signs(r['Sign_sentence'])}
os.makedirs(os.path.dirname(args.out) or '.', exist_ok=True)
with open(args.out, 'w', encoding='utf-8') as f:
json.dump(out, f, ensure_ascii=False)
print(f'wrote {args.out}: {len(out)} clips ({miss} sentences had no prediction)')
c = collections.Counter((v['split'], v['view']) for v in out.values())
for sp in ('train', 'val', 'test'):
print(f" {sp:<6} " + ' '.join(f'{v} {c[(sp, v)]}'
for v in ('front', 'left', 'right')))
if __name__ == '__main__':
main()
|