[ios][coreml] Update MarsHabitatPricePredictor to properly use .mlmodel file

This commit is contained in:
Vincent Dondain 2018-03-12 11:58:16 -04:00
Родитель 80bc5fa6f3
Коммит f2ac137ec6
8 изменённых файлов: 201 добавлений и 51 удалений

Просмотреть файл

@ -109,13 +109,13 @@
<Compile Include="DataSources\SolarPanelDataSource.cs" />
<Compile Include="DataSources\GreenhousesDataSource.cs" />
<Compile Include="DataSources\SizeDataSource.cs" />
<Compile Include="MarsHabitatPricerInput.cs" />
<Compile Include="Feature.cs" />
<Compile Include="Resources\MarsHabitatPricer.cs">
<DependentUpon>MarsHabitatPricer.mlmodel</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\MarsHabitatPricer.mlmodelc\coremldata.bin" />
<BundleResource Include="Resources\MarsHabitatPricer.mlmodelc\model0\coremldata.bin" />
<BundleResource Include="Resources\MarsHabitatPricer.mlmodelc\model1\coremldata.bin" />
<CoreMLModel Include="Resources\MarsHabitatPricer.mlmodel" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

Просмотреть файл

@ -1,41 +0,0 @@
using System;
using CoreML;
using Foundation;
namespace MarsHabitatPricePredictor
{
// test cases
// 1, 1, 750 = 1430 | 1429.74114545183
// 2.5, 4, 3000 = 16,767 | 16767.0421324377
/// <summary>
/// Xcode 9 can generate this class, but for this example it was coded from scratch
/// </summary>
/// <remarks>
/// The FeatureNames are what the model expects
/// </remarks>
public class MarsHabitatPricerInput : NSObject, IMLFeatureProvider
{
public double SolarPanels { get; set; }
public double Greenhouses { get; set; }
public double Size { get; set; }
public NSSet<NSString> FeatureNames => new NSSet<NSString>(new NSString("solarPanels"), new NSString("greenhouses"), new NSString("size"));
public MLFeatureValue GetFeatureValue(string featureName)
{
switch (featureName)
{
case "solarPanels":
return MLFeatureValue.Create(SolarPanels);
case "greenhouses":
return MLFeatureValue.Create(Greenhouses);
case "size":
return MLFeatureValue.Create(Size);
default:
return MLFeatureValue.Create(0);
}
}
}
}

Просмотреть файл

@ -0,0 +1,194 @@
// MarsHabitatPricer.cs
//
// This file was automatically generated and should not be edited.
//
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using CoreML;
using CoreVideo;
using Foundation;
namespace MarsHabitatPricePredictor {
/// <summary>
/// Model Prediction Input Type
/// </summary>
public class MarsHabitatPricerInput : NSObject, IMLFeatureProvider
{
static readonly NSSet<NSString> featureNames = new NSSet<NSString> (
new NSString ("solarPanels"), new NSString ("greenhouses"), new NSString ("size")
);
double solarPanels;
double greenhouses;
double size;
/// <summary>
/// Number of solar panels as double
/// </summary>
/// <value>Number of solar panels</value>
public double SolarPanels {
get { return solarPanels; }
set {
solarPanels = value;
}
}
/// <summary>
/// Number of greenhouses as double
/// </summary>
/// <value>Number of greenhouses</value>
public double Greenhouses {
get { return greenhouses; }
set {
greenhouses = value;
}
}
/// <summary>
/// Size in acres as double
/// </summary>
/// <value>Size in acres</value>
public double Size {
get { return size; }
set {
size = value;
}
}
public NSSet<NSString> FeatureNames {
get { return featureNames; }
}
public MLFeatureValue GetFeatureValue (string featureName)
{
switch (featureName) {
case "solarPanels":
return MLFeatureValue.Create (SolarPanels);
case "greenhouses":
return MLFeatureValue.Create (Greenhouses);
case "size":
return MLFeatureValue.Create (Size);
default:
return null;
}
}
public MarsHabitatPricerInput (double solarPanels, double greenhouses, double size)
{
SolarPanels = solarPanels;
Greenhouses = greenhouses;
Size = size;
}
}
/// <summary>
/// Model Prediction Output Type
/// </summary>
public class MarsHabitatPricerOutput : NSObject, IMLFeatureProvider
{
static readonly NSSet<NSString> featureNames = new NSSet<NSString> (
new NSString ("price")
);
double price;
/// <summary>
/// Price of the habitat (in millions) as double
/// </summary>
/// <value>Price of the habitat (in millions)</value>
public double Price {
get { return price; }
set {
price = value;
}
}
public NSSet<NSString> FeatureNames {
get { return featureNames; }
}
public MLFeatureValue GetFeatureValue (string featureName)
{
switch (featureName) {
case "price":
return MLFeatureValue.Create (Price);
default:
return null;
}
}
public MarsHabitatPricerOutput (double price)
{
Price = price;
}
}
/// <summary>
/// Class for model loading and prediction
/// </summary>
public class MarsHabitatPricer : NSObject
{
readonly MLModel model;
public MarsHabitatPricer ()
{
var url = NSBundle.MainBundle.GetUrlForResource ("MarsHabitatPricer", "mlmodelc");
NSError err;
model = MLModel.Create (url, out err);
}
MarsHabitatPricer (MLModel model)
{
this.model = model;
}
public static MarsHabitatPricer Create (NSUrl url, out NSError error)
{
if (url == null)
throw new ArgumentNullException (nameof (url));
var model = MLModel.Create (url, out error);
if (model == null)
return null;
return new MarsHabitatPricer (model);
}
/// <summary>
/// Make a prediction using the standard interface
/// </summary>
/// <param name="input">an instance of MarsHabitatPricerInput to predict from</param>
/// <param name="error">If an error occurs, upon return contains an NSError object that describes the problem.</param>
public MarsHabitatPricerOutput GetPrediction (MarsHabitatPricerInput input, out NSError error)
{
var prediction = model.GetPrediction (input, out error);
if (prediction == null)
return null;
var priceValue = prediction.GetFeatureValue ("price").DoubleValue;
return new MarsHabitatPricerOutput (priceValue);
}
/// <summary>
/// Make a prediction using the convenience interface
/// </summary>
/// <param name="solarPanels">Number of solar panels as double</param>
/// <param name="greenhouses">Number of greenhouses as double</param>
/// <param name="size">Size in acres as double</param>
/// <param name="error">If an error occurs, upon return contains an NSError object that describes the problem.</param>
public MarsHabitatPricerOutput GetPrediction (double solarPanels, double greenhouses, double size, out NSError error)
{
var input = new MarsHabitatPricerInput (solarPanels, greenhouses, size);
return GetPrediction (input, out error);
}
}
}

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -42,12 +42,9 @@ namespace MarsHabitatPricePredictor
void updatePredictedPrice()
{
var pricerInput = new MarsHabitatPricerInput()
{
SolarPanels = datasource.GetValue(pickerView.SelectedRowInComponent(0), Feature.SolarPanels),
Greenhouses = datasource.GetValue(pickerView.SelectedRowInComponent(1), Feature.Greenhouses),
Size = datasource.GetValue(pickerView.SelectedRowInComponent(2), Feature.Size)
};
var pricerInput = new MarsHabitatPricerInput (datasource.GetValue (pickerView.SelectedRowInComponent (0), Feature.SolarPanels),
datasource.GetValue (pickerView.SelectedRowInComponent (1), Feature.Greenhouses),
datasource.GetValue (pickerView.SelectedRowInComponent (2), Feature.Size));
// Use the ML model
NSError prErr;