from django.conf import settings as s from django.core.management.base import BaseCommand from django.db import transaction from epdb.models import MLRelativeReasoning, EnviFormer, Package class Command(BaseCommand): """This command can be run with `python manage.py create_ml_models [model_names] -d [data_packages] OPTIONAL: -e [eval_packages]` For example, to train both EnviFormer and MLRelativeReasoning on BBD and SOIL and evaluate them on SLUDGE the below command would be used: `python manage.py create_ml_models enviformer mlrr -d bbd soil -e sludge """ def add_arguments(self, parser): parser.add_argument("model_names", nargs="+", type=str, help="The names of models to train. Options are: enviformer, mlrr") parser.add_argument("-d", "--data-packages", nargs="+", type=str, help="Packages for training") parser.add_argument("-e", "--eval-packages", nargs="*", type=str, help="Packages for evaluation", default=[]) parser.add_argument("-r", "--rule-packages", nargs="*", type=str, help="Rule Packages mandatory for MLRR", default=[]) @transaction.atomic def handle(self, *args, **options): # Find Public Prediction Models package to add new models to try: pack = Package.objects.filter(name="Public Prediction Models")[0] bbd = Package.objects.filter(name="EAWAG-BBD")[0] soil = Package.objects.filter(name="EAWAG-SOIL")[0] sludge = Package.objects.filter(name="EAWAG-SLUDGE")[0] sediment = Package.objects.filter(name="EAWAG-SEDIMENT")[0] except IndexError: raise IndexError("Can't find correct packages. They should be created with the bootstrap command") def decode_packages(package_list): """Decode package strings into their respective packages""" packages = [] for p in package_list: p = p.lower() if p == "bbd": packages.append(bbd) elif p == "soil": packages.append(soil) elif p == "sludge": packages.append(sludge) elif p == "sediment": packages.append(sediment) else: raise ValueError(f"Unknown package {p}") return packages # Iteratively create models in options["model_names"] print(f"Creating models: {options['model_names']}") data_packages = decode_packages(options["data_packages"]) eval_packages = decode_packages(options["eval_packages"]) rule_packages = decode_packages(options["rule_packages"]) for model_name in options['model_names']: model_name = model_name.lower() if model_name == "enviformer" and s.ENVIFORMER_PRESENT: model = EnviFormer.create(pack, data_packages=data_packages, eval_packages=eval_packages, threshold=0.5, name="EnviFormer - T0.5", description="EnviFormer transformer") elif model_name == "mlrr": model = MLRelativeReasoning.create(package=pack, rule_packages=rule_packages, data_packages=data_packages, eval_packages=eval_packages, threshold=0.5, name='ECC - BBD - T0.5', description='ML Relative Reasoning') else: raise ValueError(f"Cannot create model of type {model_name}, unknown model type") # Build the dataset for the model, train it, evaluate it and save it print(f"Building dataset for {model_name}") model.build_dataset() print(f"Training {model_name}") model.build_model() print(f"Evaluating {model_name}") model.evaluate_model() print(f"Saving {model_name}") model.save()