public void RegisterTypeWithAttribute() { // Build in-memory data. var tribe = new List <AlienHero>() { new AlienHero("ML.NET", 2, 1000, 2000, 3000, 4000, 5000, 6000, 7000) }; // Build a ML.NET pipeline and make prediction. var tribeDataView = ML.Data.LoadFromEnumerable(tribe); var heroEstimator = new CustomMappingEstimator <AlienHero, SuperAlienHero>(ML, AlienFusionProcess.MergeBody, "LambdaAlienHero"); var model = heroEstimator.Fit(tribeDataView); var tribeTransformed = model.Transform(tribeDataView); var tribeEnumerable = ML.Data.CreateEnumerable <SuperAlienHero>(tribeTransformed, false).ToList(); // Make sure the pipeline output is correct. Assert.Equal(tribeEnumerable[0].Name, "Super " + tribe[0].Name); Assert.Equal(tribeEnumerable[0].Merged.Age, tribe[0].One.Age + tribe[0].Two.Age); Assert.Equal(tribeEnumerable[0].Merged.Height, tribe[0].One.Height + tribe[0].Two.Height); Assert.Equal(tribeEnumerable[0].Merged.Weight, tribe[0].One.Weight + tribe[0].Two.Weight); Assert.Equal(tribeEnumerable[0].Merged.HandCount, tribe[0].One.HandCount + tribe[0].Two.HandCount); // Build prediction engine from the trained pipeline. var engine = ML.Model.CreatePredictionEngine <AlienHero, SuperAlienHero>(model); var alien = new AlienHero("TEN.LM", 1, 2, 3, 4, 5, 6, 7, 8); var superAlien = engine.Predict(alien); // Make sure the prediction engine produces expected result. Assert.Equal(superAlien.Name, "Super " + alien.Name); Assert.Equal(superAlien.Merged.Age, alien.One.Age + alien.Two.Age); Assert.Equal(superAlien.Merged.Height, alien.One.Height + alien.Two.Height); Assert.Equal(superAlien.Merged.Weight, alien.One.Weight + alien.Two.Weight); Assert.Equal(superAlien.Merged.HandCount, alien.One.HandCount + alien.Two.HandCount); }
public void TestCustomTransformer() { string dataPath = GetDataPath("adult.tiny.with-schema.txt"); var source = new MultiFileSource(dataPath); var loader = ML.Data.CreateTextLoader(new[] { new TextLoader.Column("Float1", DataKind.Single, 9), new TextLoader.Column("Float4", DataKind.Single, new[] { new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }) }, hasHeader: true); var data = loader.Load(source); IDataView transformedData; // We create a temporary environment to instantiate the custom transformer. This is to ensure that we don't need the same // environment for saving and loading. var tempoEnv = new MLContext(); var customEst = new CustomMappingEstimator <MyInput, MyOutput>(tempoEnv, MyLambda.MyAction, "MyLambda"); try { TestEstimatorCore(customEst, data); Assert.True(false, "Cannot work without RegisterAssembly"); } catch (InvalidOperationException ex) { if (!ex.IsMarked()) { throw; } } ML.ComponentCatalog.RegisterAssembly(typeof(MyLambda).Assembly); TestEstimatorCore(customEst, data); transformedData = customEst.Fit(data).Transform(data); var inputs = ML.Data.CreateEnumerable <MyInput>(transformedData, true); var outputs = ML.Data.CreateEnumerable <MyOutput>(transformedData, true); Assert.True(inputs.Zip(outputs, (x, y) => y.Together == $"{x.Float1} + {string.Join(", ", x.Float4)}").All(x => x)); Done(); }
public void TestCustomTransformer() { string dataPath = GetDataPath("adult.test"); var source = new MultiFileSource(dataPath); var loader = ML.Data.TextReader(new[] { new TextLoader.Column("Float1", DataKind.R4, 0), new TextLoader.Column("Float4", DataKind.R4, new[] { new TextLoader.Range(0), new TextLoader.Range(2), new TextLoader.Range(4), new TextLoader.Range(10) }) }, s => { s.Separator = ","; s.HasHeader = true; }); var data = loader.Read(source); IDataView transformedData; // We create a temporary environment to instantiate the custom transformer. This is to ensure that we don't need the same // environment for saving and loading. using (var tempoEnv = new ConsoleEnvironment()) { var customEst = new CustomMappingEstimator <MyInput, MyOutput>(tempoEnv, MyLambda.MyAction, "MyLambda"); try { TestEstimatorCore(customEst, data); Assert.True(false, "Cannot work without MEF injection"); } catch (Exception) { // REVIEW: we should have a common mechanism that will make sure this is 'our' exception thrown. } ML.CompositionContainer = new CompositionContainer(new TypeCatalog(typeof(MyLambda))); TestEstimatorCore(customEst, data); transformedData = customEst.Fit(data).Transform(data); } var inputs = transformedData.AsEnumerable <MyInput>(ML, true); var outputs = transformedData.AsEnumerable <MyOutput>(ML, true); Assert.True(inputs.Zip(outputs, (x, y) => y.Together == $"{x.Float1} + {string.Join(", ", x.Float4)}").All(x => x)); Done(); }
public void TestCustomTransformer(bool registerAssembly) { string dataPath = GetDataPath("adult.tiny.with-schema.txt"); var source = new MultiFileSource(dataPath); var loader = ML.Data.CreateTextLoader(new[] { new TextLoader.Column("Float1", DataKind.Single, 9), new TextLoader.Column("Float4", DataKind.Single, new[] { new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }) }, hasHeader: true); var data = loader.Load(source); IDataView transformedData; // We create a temporary environment to instantiate the custom transformer. This is to ensure that we don't need the same // environment for saving and loading. var tempoEnv = new MLContext(1); var customEst = new CustomMappingEstimator <MyInput, MyOutput>(tempoEnv, MyLambda.MyAction, "MyLambda"); // Before 1.5-preview3 it was required to register the assembly. // Now, the assembly information is automatically saved in the model and the assembly is registered // when loading. // This tests the case that the CustomTransformer still works even if you explicitly register the assembly if (registerAssembly) { ML.ComponentCatalog.RegisterAssembly(typeof(MyLambda).Assembly); } TestEstimatorCore(customEst, data); transformedData = customEst.Fit(data).Transform(data); var inputs = ML.Data.CreateEnumerable <MyInput>(transformedData, true); var outputs = ML.Data.CreateEnumerable <MyOutput>(transformedData, true); Assert.True(inputs.Zip(outputs, (x, y) => y.Together == $"{x.Float1} + {string.Join(", ", x.Float4)}").All(x => x)); Done(); }