From c9420cc5864119612d7b173c97b3390cf9e03c67 Mon Sep 17 00:00:00 2001 From: Adam Pocock Date: Thu, 11 Feb 2021 15:22:23 -0500 Subject: [PATCH 1/2] Added a few lines to Helpers.testModelSerialization that test ModelProvenance marshalling (and consequently all the data provenance and trainer provenances). Fixed the bugs that the test found. --- .../provenance/EnsembleModelProvenance.java | 18 ++++---------- .../tribuo/provenance/ModelProvenance.java | 24 +++++++++++++++---- .../provenance/SkeletalTrainerProvenance.java | 1 + .../test/java/org/tribuo/test/Helpers.java | 12 +++++++--- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java b/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java index 02502fcf1..4a1510d82 100644 --- a/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java +++ b/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java @@ -19,13 +19,10 @@ import com.oracle.labs.mlrg.olcut.provenance.ListProvenance; import com.oracle.labs.mlrg.olcut.provenance.ObjectProvenance; import com.oracle.labs.mlrg.olcut.provenance.Provenance; -import com.oracle.labs.mlrg.olcut.provenance.primitives.DateTimeProvenance; -import com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance; import com.oracle.labs.mlrg.olcut.util.Pair; import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; import java.util.Map; /** @@ -64,14 +61,9 @@ public String toString() { } @Override - public Iterator> iterator() { - ArrayList> iterable = new ArrayList<>(); - iterable.add(new Pair<>(CLASS_NAME,new StringProvenance(CLASS_NAME,className))); - iterable.add(new Pair<>(DATASET,datasetProvenance)); - iterable.add(new Pair<>(TRAINER,trainerProvenance)); - iterable.add(new Pair<>(TRAINING_TIME,new DateTimeProvenance(TRAINING_TIME,time))); - iterable.add(new Pair<>(INSTANCE_VALUES,instanceProvenance)); - iterable.add(new Pair<>(MEMBERS,memberProvenance)); - return iterable.iterator(); + protected List> internalProvenances() { + List> superList = super.internalProvenances(); + superList.add(new Pair<>(MEMBERS,memberProvenance)); + return superList; } } diff --git a/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java b/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java index 846a991ad..13f18fb53 100644 --- a/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java +++ b/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java @@ -27,6 +27,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -43,7 +44,7 @@ public class ModelProvenance implements ObjectProvenance { protected static final String TRAINER = "trainer"; protected static final String TRAINING_TIME = "trained-at"; protected static final String INSTANCE_VALUES = "instance-values"; - private static final String TRIBUO_VERSION_STRING = "tribuo-version"; + protected static final String TRIBUO_VERSION_STRING = "tribuo-version"; protected final String className; @@ -81,7 +82,7 @@ public ModelProvenance(Map map) { this.trainerProvenance = ObjectProvenance.checkAndExtractProvenance(map,TRAINER,TrainerProvenance.class, ModelProvenance.class.getSimpleName()); this.time = ObjectProvenance.checkAndExtractProvenance(map,TRAINING_TIME,DateTimeProvenance.class, ModelProvenance.class.getSimpleName()).getValue(); this.instanceProvenance = (MapProvenance) ObjectProvenance.checkAndExtractProvenance(map,INSTANCE_VALUES,MapProvenance.class, ModelProvenance.class.getSimpleName()); - this.versionString = ObjectProvenance.checkAndExtractProvenance(map, TRIBUO_VERSION_STRING,StringProvenance.class, DatasetProvenance.class.getSimpleName()).getValue(); + this.versionString = ObjectProvenance.checkAndExtractProvenance(map,TRIBUO_VERSION_STRING,StringProvenance.class,ModelProvenance.class.getSimpleName()).getValue(); } /** @@ -152,8 +153,12 @@ public int hashCode() { return Objects.hash(className, time, datasetProvenance, trainerProvenance, instanceProvenance, versionString); } - @Override - public Iterator> iterator() { + /** + * Returns a list of all the provenances in this model provenance so subclasses + * can append to the list. + * @return A list of all the provenances in this class. + */ + protected List> internalProvenances() { ArrayList> iterable = new ArrayList<>(); iterable.add(new Pair<>(CLASS_NAME,new StringProvenance(CLASS_NAME,className))); iterable.add(new Pair<>(DATASET,datasetProvenance)); @@ -161,6 +166,15 @@ public Iterator> iterator() { iterable.add(new Pair<>(TRAINING_TIME,new DateTimeProvenance(TRAINING_TIME,time))); iterable.add(new Pair<>(INSTANCE_VALUES,instanceProvenance)); iterable.add(new Pair<>(TRIBUO_VERSION_STRING,new StringProvenance(TRIBUO_VERSION_STRING,versionString))); - return iterable.iterator(); + return iterable; + } + + /** + * Calls {@link #internalProvenances()} and returns the iterator from that list. + * @return An iterator over all the provenances. + */ + @Override + public Iterator> iterator() { + return internalProvenances().iterator(); } } diff --git a/Core/src/main/java/org/tribuo/provenance/SkeletalTrainerProvenance.java b/Core/src/main/java/org/tribuo/provenance/SkeletalTrainerProvenance.java index b811a66d3..138df8f28 100644 --- a/Core/src/main/java/org/tribuo/provenance/SkeletalTrainerProvenance.java +++ b/Core/src/main/java/org/tribuo/provenance/SkeletalTrainerProvenance.java @@ -92,6 +92,7 @@ public Map> getInstanceValues() { map.put(TRAIN_INVOCATION_COUNT, invocationCount); map.put(IS_SEQUENCE, isSequence); + map.put(TRIBUO_VERSION_STRING, version); return map; } diff --git a/Core/src/test/java/org/tribuo/test/Helpers.java b/Core/src/test/java/org/tribuo/test/Helpers.java index 36cb08cbb..0e7744ffd 100644 --- a/Core/src/test/java/org/tribuo/test/Helpers.java +++ b/Core/src/test/java/org/tribuo/test/Helpers.java @@ -16,25 +16,26 @@ package org.tribuo.test; +import com.oracle.labs.mlrg.olcut.provenance.ProvenanceUtil; +import com.oracle.labs.mlrg.olcut.provenance.io.ObjectMarshalledProvenance; import org.junit.jupiter.api.Assertions; import org.tribuo.Example; import org.tribuo.Feature; import org.tribuo.Model; import org.tribuo.Output; import org.tribuo.impl.ListExample; +import org.tribuo.provenance.ModelProvenance; import org.tribuo.sequence.SequenceModel; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -60,6 +61,11 @@ public static Example mkExample(MockOutput label, String... features } public static > void testModelSerialization(Model model, Class outputClazz) { + // test provenance marshalling + List provenanceList = ProvenanceUtil.marshalProvenance(model.getProvenance()); + ModelProvenance provenance = (ModelProvenance) ProvenanceUtil.unmarshalProvenance(provenanceList); + Assertions.assertEquals(provenance,model.getProvenance()); + // write to byte array ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos))) { From c3c713bc01894323fb82a971a3de5b3918f9a4ae Mon Sep 17 00:00:00 2001 From: Adam Pocock Date: Thu, 11 Feb 2021 22:16:49 -0500 Subject: [PATCH 2/2] Adds tracking of Java version, os.name and os.arch to ModelProvenance. Also adds the ability to strip those provenances using StripProvenance. --- .../provenance/EnsembleModelProvenance.java | 80 +++++++++- .../tribuo/provenance/ModelProvenance.java | 150 ++++++++++++++++-- .../java/org/tribuo/json/StripProvenance.java | 14 +- 3 files changed, 231 insertions(+), 13 deletions(-) diff --git a/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java b/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java index 4a1510d82..0f7baf06b 100644 --- a/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java +++ b/Core/src/main/java/org/tribuo/provenance/EnsembleModelProvenance.java @@ -24,6 +24,7 @@ import java.time.OffsetDateTime; import java.util.List; import java.util.Map; +import java.util.Objects; /** * Model provenance for ensemble models. @@ -35,26 +36,101 @@ public class EnsembleModelProvenance extends ModelProvenance { private final ListProvenance memberProvenance; - public EnsembleModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, TrainerProvenance trainerProvenance, ListProvenance memberProvenance) { + /** + * Creates a provenance for an ensemble model tracking the class name, creation time, dataset provenance and + * trainer provenance along with the individual model provenances + * for each ensemble member. + *

+ * Also tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + * @param memberProvenance The ensemble member provenances. + */ + public EnsembleModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance, + ListProvenance memberProvenance) { super(className, time, datasetProvenance, trainerProvenance); this.memberProvenance = memberProvenance; } - public EnsembleModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, TrainerProvenance trainerProvenance, Map instanceProvenance, ListProvenance memberProvenance) { + /** + * Creates a provenance for an ensemble model tracking the class name, creation time, dataset provenance, + * trainer provenance and any instance specific provenance along with the individual model provenances + * for each ensemble member. + *

+ * Also tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + * @param instanceProvenance Provenance for this specific model training run. + * @param memberProvenance The ensemble member provenances. + */ + public EnsembleModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance, Map instanceProvenance, + ListProvenance memberProvenance) { super(className, time, datasetProvenance, trainerProvenance, instanceProvenance); this.memberProvenance = memberProvenance; } + /** + * Creates a provenance for an ensemble model tracking the class name, creation time, dataset provenance, + * trainer provenance and any instance specific provenance along with the individual model provenances + * for each ensemble member. + *

+ * Also optionally tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + * @param instanceProvenance Provenance for this specific model training run. + * @param memberProvenance The ensemble member provenances. + * @param trackSystem If true then store the java version, os name and os arch in the provenance. + */ + public EnsembleModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance, Map instanceProvenance, + boolean trackSystem, ListProvenance memberProvenance) { + super(className, time, datasetProvenance, trainerProvenance, instanceProvenance, trackSystem); + this.memberProvenance = memberProvenance; + } + + /** + * Used by the provenance unmarshalling system. + *

+ * Throws {@link com.oracle.labs.mlrg.olcut.provenance.ProvenanceException} if there are missing + * fields. + * @param map The provenance map. + */ @SuppressWarnings("unchecked") // member provenance cast. public EnsembleModelProvenance(Map map) { super(map); this.memberProvenance = (ListProvenance) ObjectProvenance.checkAndExtractProvenance(map,MEMBERS,ListProvenance.class, EnsembleModelProvenance.class.getSimpleName()); } + /** + * Get the provenances for each ensemble member. + * @return The member provenances. + */ public ListProvenance getMemberProvenance() { return memberProvenance; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + EnsembleModelProvenance pairs = (EnsembleModelProvenance) o; + return memberProvenance.equals(pairs.memberProvenance); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), memberProvenance); + } + @Override public String toString() { return generateString("EnsembleModel"); diff --git a/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java b/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java index 13f18fb53..af986af91 100644 --- a/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java +++ b/Core/src/main/java/org/tribuo/provenance/ModelProvenance.java @@ -19,6 +19,7 @@ import com.oracle.labs.mlrg.olcut.provenance.MapProvenance; import com.oracle.labs.mlrg.olcut.provenance.ObjectProvenance; import com.oracle.labs.mlrg.olcut.provenance.Provenance; +import com.oracle.labs.mlrg.olcut.provenance.ProvenanceException; import com.oracle.labs.mlrg.olcut.provenance.primitives.DateTimeProvenance; import com.oracle.labs.mlrg.olcut.provenance.primitives.StringProvenance; import com.oracle.labs.mlrg.olcut.util.Pair; @@ -26,16 +27,21 @@ import java.time.OffsetDateTime; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; /** * Contains provenance information for an instance of a {@link org.tribuo.Model}. *

* Made up of the class name of the model object, the date and time it was trained, the provenance of * the training data, and the provenance of the trainer. + *

+ * In addition by default it collects the Java version, OS name and system architecture, along + * with the running Tribuo version. */ public class ModelProvenance implements ObjectProvenance { private static final long serialVersionUID = 1L; @@ -46,6 +52,16 @@ public class ModelProvenance implements ObjectProvenance { protected static final String INSTANCE_VALUES = "instance-values"; protected static final String TRIBUO_VERSION_STRING = "tribuo-version"; + // Note these have been added due to a discrepancy between java.lang.Math + // and java.lang.StrictMath on x64 and aarch64 platforms (and between Java 8 and 9+). + // Training a linear SGD predictor can create different models on different platforms + // due to this discrepancy. + protected static final String JAVA_VERSION_STRING = "java-version"; + protected static final String OS_STRING = "os-name"; + protected static final String ARCH_STRING = "os-arch"; + + protected static final String UNKNOWN_VERSION = "unknown-version"; + protected final String className; protected final OffsetDateTime time; @@ -58,24 +74,81 @@ public class ModelProvenance implements ObjectProvenance { protected final String versionString; - public ModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, TrainerProvenance trainerProvenance) { - this.className = className; - this.time = time; - this.datasetProvenance = datasetProvenance; - this.trainerProvenance = trainerProvenance; - this.instanceProvenance = new MapProvenance<>(); - this.versionString = Tribuo.VERSION; + protected final String javaVersionString; + + protected final String osString; + + protected final String archString; + + /** + * Creates a model provenance tracking the class name, creation time, dataset provenance and trainer provenance. + *

+ * Also tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + */ + public ModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance) { + this(className,time,datasetProvenance,trainerProvenance,Collections.emptyMap()); } - public ModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, TrainerProvenance trainerProvenance, Map instanceProvenance) { + /** + * Creates a model provenance tracking the class name, creation time, dataset provenance, + * trainer provenance and any instance specific provenance. + *

+ * Also tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + * @param instanceProvenance Provenance for this specific model training run. + */ + public ModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance, Map instanceProvenance) { + this(className,time,datasetProvenance,trainerProvenance,instanceProvenance,true); + } + + /** + * Creates a model provenance tracking the class name, creation time, dataset provenance, + * trainer provenance and any instance specific provenance. + *

+ * Also optionally tracks system details like the os name, os architecture, java version, and Tribuo version. + * @param className The model class name. + * @param time The model creation time. + * @param datasetProvenance The dataset provenance. + * @param trainerProvenance The trainer provenance. + * @param instanceProvenance Provenance for this specific model training run. + * @param trackSystem If true then store the java version, os name and os arch in the provenance. + */ + public ModelProvenance(String className, OffsetDateTime time, DatasetProvenance datasetProvenance, + TrainerProvenance trainerProvenance, Map instanceProvenance, + boolean trackSystem) { this.className = className; this.time = time; this.datasetProvenance = datasetProvenance; this.trainerProvenance = trainerProvenance; - this.instanceProvenance = new MapProvenance<>(instanceProvenance); + this.instanceProvenance = instanceProvenance.isEmpty() ? new MapProvenance<>() : new MapProvenance<>(instanceProvenance); this.versionString = Tribuo.VERSION; + if (trackSystem) { + this.javaVersionString = System.getProperty("java.version"); + this.osString = System.getProperty("os.name"); + this.archString = System.getProperty("os.arch"); + } else { + this.javaVersionString = UNKNOWN_VERSION; + this.osString = UNKNOWN_VERSION; + this.archString = UNKNOWN_VERSION; + } } + /** + * Used by the provenance unmarshalling system. + *

+ * Throws {@link com.oracle.labs.mlrg.olcut.provenance.ProvenanceException} if there are missing + * fields. + * @param map The provenance map. + */ public ModelProvenance(Map map) { this.className = ObjectProvenance.checkAndExtractProvenance(map,CLASS_NAME,StringProvenance.class, ModelProvenance.class.getSimpleName()).getValue(); this.datasetProvenance = ObjectProvenance.checkAndExtractProvenance(map,DATASET,DatasetProvenance.class, ModelProvenance.class.getSimpleName()); @@ -83,6 +156,33 @@ public ModelProvenance(Map map) { this.time = ObjectProvenance.checkAndExtractProvenance(map,TRAINING_TIME,DateTimeProvenance.class, ModelProvenance.class.getSimpleName()).getValue(); this.instanceProvenance = (MapProvenance) ObjectProvenance.checkAndExtractProvenance(map,INSTANCE_VALUES,MapProvenance.class, ModelProvenance.class.getSimpleName()); this.versionString = ObjectProvenance.checkAndExtractProvenance(map,TRIBUO_VERSION_STRING,StringProvenance.class,ModelProvenance.class.getSimpleName()).getValue(); + this.javaVersionString = maybeExtractProvenance(map,JAVA_VERSION_STRING,StringProvenance.class).map(StringProvenance::getValue).orElse(UNKNOWN_VERSION); + this.osString = maybeExtractProvenance(map,OS_STRING,StringProvenance.class).map(StringProvenance::getValue).orElse(UNKNOWN_VERSION); + this.archString = maybeExtractProvenance(map,ARCH_STRING,StringProvenance.class).map(StringProvenance::getValue).orElse(UNKNOWN_VERSION); + } + + /** + * Like {@link ObjectProvenance#checkAndExtractProvenance(Map, String, Class, String)} but doesn't + * throw if it fails to find the key, only if the value is of the wrong type. + * @param map The map to inspect. + * @param key The key to find. + * @param type The class of the value. + * @param The type of the value. + * @return An optional containing the value if present. + * @throws ProvenanceException If the value is the wrong type. + */ + @SuppressWarnings("unchecked") // Guarded by isInstance check + private static Optional maybeExtractProvenance(Map map, String key, Class type) throws ProvenanceException { + Provenance tmp = map.remove(key); + if (tmp != null) { + if (type.isInstance(tmp)) { + return Optional.of((T) tmp); + } else { + throw new ProvenanceException("Failed to cast " + key + " when constructing ModelProvenance, found " + tmp); + } + } else { + return Optional.empty(); + } } /** @@ -125,6 +225,30 @@ public String getTribuoVersion() { return versionString; } + /** + * The Java version used to create this model. + * @return The Java version. + */ + public String getJavaVersion() { + return javaVersionString; + } + + /** + * The name of the OS used to create this model. + * @return The OS name. + */ + public String getOS() { + return osString; + } + + /** + * The CPU architecture used to create this model. + * @return The CPU architecture. + */ + public String getArch() { + return archString; + } + @Override public String toString() { return generateString("Model"); @@ -145,7 +269,10 @@ public boolean equals(Object o) { datasetProvenance.equals(pairs.datasetProvenance) && trainerProvenance.equals(pairs.trainerProvenance) && instanceProvenance.equals(pairs.instanceProvenance) && - versionString.equals(pairs.versionString); + versionString.equals(pairs.versionString) && + javaVersionString.equals(pairs.javaVersionString) && + osString.equals(pairs.osString) && + archString.equals(pairs.archString); } @Override @@ -166,6 +293,9 @@ protected List> internalProvenances() { iterable.add(new Pair<>(TRAINING_TIME,new DateTimeProvenance(TRAINING_TIME,time))); iterable.add(new Pair<>(INSTANCE_VALUES,instanceProvenance)); iterable.add(new Pair<>(TRIBUO_VERSION_STRING,new StringProvenance(TRIBUO_VERSION_STRING,versionString))); + iterable.add(new Pair<>(JAVA_VERSION_STRING,new StringProvenance(JAVA_VERSION_STRING,javaVersionString))); + iterable.add(new Pair<>(OS_STRING,new StringProvenance(OS_STRING,osString))); + iterable.add(new Pair<>(ARCH_STRING,new StringProvenance(ARCH_STRING,archString))); return iterable; } diff --git a/Json/src/main/java/org/tribuo/json/StripProvenance.java b/Json/src/main/java/org/tribuo/json/StripProvenance.java index 4e93bafa8..96f9a179f 100644 --- a/Json/src/main/java/org/tribuo/json/StripProvenance.java +++ b/Json/src/main/java/org/tribuo/json/StripProvenance.java @@ -66,6 +66,7 @@ import static org.tribuo.json.StripProvenance.ProvenanceTypes.ALL; import static org.tribuo.json.StripProvenance.ProvenanceTypes.DATASET; import static org.tribuo.json.StripProvenance.ProvenanceTypes.INSTANCE; +import static org.tribuo.json.StripProvenance.ProvenanceTypes.SYSTEM; import static org.tribuo.json.StripProvenance.ProvenanceTypes.TRAINER; /** @@ -96,6 +97,10 @@ public enum ProvenanceTypes { * Select any instance provenance from the specific training run that created this model. */ INSTANCE, + /** + * Selects any system information provenance. + */ + SYSTEM, /** * Selects all provenance stored in the model. */ @@ -139,7 +144,14 @@ private static ModelProvenance cleanProvenance(ModelProvenance old, String prove instanceProvenance.put("original-provenance-hash",new HashProvenance(opt.hashType,"original-provenance-hash",provenanceHash)); } - return new ModelProvenance(old.getClassName(),time,datasetProvenance,trainerProvenance,instanceProvenance); + boolean stripSystem; + if (opt.removeProvenances.contains(ALL) || opt.removeProvenances.contains(SYSTEM)) { + stripSystem = true; + } else { + stripSystem = false; + } + + return new ModelProvenance(old.getClassName(),time,datasetProvenance,trainerProvenance,instanceProvenance,!stripSystem); } /**