Lecture 03参数更新和三个单条件比较 · 实现代码
参数更新和三个单条件比较 · 实现代码
按问题继续
前景/背景/mIoU口径、RGB到mask训练、FCN与1×1读出及边界
展开完整实现代码
%%writefile -a lab11_segmentation.py
def run(out='lab11-results',epochs=20):
started=datetime.now(timezone.utc).isoformat();start=time.time();out=Path(out);out.mkdir(exist_ok=True,parents=True);seed_all(19)
warmup=sampling_warmup(out)
train,_,raw_train=make_scenes(384,7101);test,_,raw_test=make_scenes(128,7901)
small,_,raw_small=make_scenes(128,7901,scale=.45)
target=with_ignore(raw_train);test_target=with_ignore(raw_test);small_target=with_ignore(raw_small)
readout=PixelReadout();pixel_history=train_model(readout,train,target,epochs=25,lr=.03)
fcn=SmallFCN();random_pred=predict(fcn,test);history=train_model(fcn,train,target,epochs=epochs,lr=.003)
pred=predict(fcn,test);nearest_pred=predict(fcn,test,mode='nearest');small_pred=predict(fcn,small)
# Same image/target, blur changes RGB only, preserving geometry and label.
blurred=F.avg_pool2d(F.pad(test,(2,2,2,2),mode='reflect'),5,stride=1);blur_pred=predict(fcn,blurred)
# ignore_index check: arbitrarily changing predictions only at ignored pixels leaves metrics identical.
altered=pred.clone();altered[test_target==255]=(altered[test_target==255]+1)%3
assert segmentation_metrics(pred,test_target)==segmentation_metrics(altered,test_target)
# Synchronized flip can be undone on both image and categorical target.
assert torch.equal(train.flip(-1).flip(-1),train) and torch.equal(target.flip(-1).flip(-1),target)
results={'provenance':provenance(__file__,started),'config':{'image_shape':[3,48,48],'logits_shape':['B',3,48,48],'target_shape':['B',48,48],
'target_dtype':'int64','classes':{'0':'background','1':'red rectangle','2':'blue ellipse'},'ignore_label':255,
'train_count':384,'heldout_count':128,'split_seeds':[7101,7901],'seed':19,'FCN_epochs':epochs,'readout_epochs':25,
'loss':'cross_entropy on valid pixels, ignore_index=255','optimizer':'Adam FCN lr=.003; pixel readout lr=.03',
'FCN_parameters':sum(p.numel() for p in fcn.parameters()),'readout_parameters':sum(p.numel() for p in readout.parameters()),
'upsampling':'12x12 coarse logits ->48x48 bilinear align_corners=False + fine skip logits','augmentation':'paired horizontal flip',
'data_identity':'generated scenes with color/shape correlated; heldout original scene seeds; no pretrained weights'},
'sampling_warmup':warmup,'random_FCN':segmentation_metrics(random_pred,test_target),
'learned_pixel_readout':segmentation_metrics(predict(readout,test),test_target),'trained_FCN':segmentation_metrics(pred,test_target),
'condition_nearest_logits':segmentation_metrics(nearest_pred,test_target),'condition_scale_045':segmentation_metrics(small_pred,small_target),
'condition_RGB_blur5':segmentation_metrics(blur_pred,test_target),'readout_RGB_blur5':segmentation_metrics(predict(readout,blurred),test_target),'readout_scale_045':segmentation_metrics(predict(readout,small),small_target),'history_FCN':history,'history_pixel_readout':pixel_history,
'ignore_metric_invariance_test':'passed','paired_flip_involution_test':'passed','sampling_known_values_tests':'passed','seconds':time.time()-start}
counts=((pred!=test_target)&(test_target!=255)).flatten(1).sum(1);worst=counts.argsort(descending=True)[:4].tolist()
results['failure_examples']=[{'sample_index':i,'wrong_valid_pixels':int(counts[i])} for i in worst]
torch.save({'state_dict':fcn.state_dict(),'config':results['config']},out/'fcn.pt');torch.save(readout.state_dict(),out/'pixel-readout.pt')
np.savez_compressed(out/'heldout-input-target-predictions.npz',images=test.numpy(),target=test_target.numpy(),prediction=pred.numpy(),
half_scale_images=small.numpy(),half_scale_target=small_target.numpy(),half_scale_prediction=small_pred.numpy(),blur_images=blurred.numpy(),blur_prediction=blur_pred.numpy())
plot_predictions(test,test_target,pred,out/'heldout-segmentation.png','FCN heldout image-to-mask predictions')
plot_predictions(test,test_target,pred,out/'failure-segmentation.png','Four largest valid-pixel error counts',worst)
plot_predictions(small,small_target,small_pred,out/'small-object-segmentation.png','Same latent scenes: object dimensions x0.45')
plot_predictions(blurred,test_target,blur_pred,out/'blur-segmentation.png','Same geometry, RGB blurred with 5x5 average')
fig,ax=plt.subplots(figsize=(7,4));ax.plot(history,label='FCN');ax.plot(pixel_history,label='pixel softmax readout');ax.set(xlabel='epoch (zero based)',ylabel='valid-pixel CE');ax.legend();fig.tight_layout();fig.savefig(out/'training-curve.png',dpi=150);plt.close(fig)
save_json(out/'run.json',results);print(json.dumps({k:results[k]['mIoU_3_classes'] for k in ['random_FCN','learned_pixel_readout','trained_FCN','condition_scale_045','condition_RGB_blur5']},indent=2),flush=True)
return results
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('--out',default='lab11-results');p.add_argument('--epochs',type=int,default=20);a=p.parse_args();run(a.out,a.epochs)