Cannot load model using WinML - c#

As WinML is still fairly new and ever changing, I was hoping to know if anyone else has come across this error when trying to load a ONNX file made via the Custom Vision Service Export.
Type Error: Type (map(string,tensor(float))) of output arg (loss) of node (ZipMap) does not match expected type (seq(map(string,tensor(float))))
using Windows.AI.MachineLearning;
Windows RS5 1809 (build 17763.1)
UWP SDK 17763
Testing code from this link:
https://learn.microsoft.com/en-us/uwp/api/windows.ai.machinelearning
// Load and create the model
var modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///{_modelFileName}"));
_model = await LearningModel.LoadFromStorageFileAsync(modelFile);
Any help would be greatly appreciated.

Windows build 17763 (RS5) requires ONNX version 1.2 when Windows.AI.MachineLearning.
The Azure Custom Vision service supports this today .
Here is a post around a sample app that does this.
As a note, you need to make sure your output data type matches when you bind. In c# this looks something like this:
public sealed class ModelOutput
{
public TensorString ClassLabel = TensorString.Create(new long[] { 1, 1 });
public IList<IDictionary<string, float>> Loss = new List<IDictionary<string, float>>();
}

I received info from a Microsoft associate that stated that the windows.ai.machinelearning api only supports ONNX 2. He didn't supply a date to which we can expect the custom vision service to export version 2 files.

Related

Loading Tensorflow model in c#

I am really struggling with the fact that i don't know how can I load and use a TensorFlow image classifier model in c#.
To be more precise I want to use a model trained in Teachable Machine that can be exported in multiple TensorFlow formats.
And if possible an example code will be really helpful.
I have tried to ask the same question but it got closed, I really need to find out how can I load and use the model so please let the question open. Thanks a lot for the support.
If you need only to evaluate model in C# code, then you need some lightweight library that can be used as loader and evaluator for your network.
There are many good libraries to work with tensorflow models in C#, like:
TensorFlowSharp
TensorFlow.NET
Unfortunately, all existing libraries has pre-defined logic for training model too, so that is a little ballast for your task.
To accomplish your purposes, please see this detailed article about how to load TF model into your C# application using TensorFlowSharp.
I used TensorFlowSharpin the past, but that library is still stuck with TensorFlow 1.x, and development seems quite dead. Because of that, I moved on to ML.NET.
Please see this article about how to use ML.NET with C# (disclaimer: I was the author of that article). Below is the gist of it.
Convert saved_model to onnx
Install tf2onnx.
pip install tf2onnx
Use it to convert saved_model to onnx.
python -m tf2onnx.convert --saved-model <path to saved_model folder> --output "model.onnx"
Use ML.NET to make prediction
Install the necessary packages.
dotnet add package Microsoft.ML
dotnet add package Microsoft.ML.OnnxRuntime
dotnet add package Microsoft.ML.OnnxTransformer
Define the input and output model classes.
public class Input
{
[VectorType(<input size>)]
[ColumnName("<input node name>")]
public float[] Data { get; set; } // Remember to change the type if your model does not use float
}
public class Output
{
[VectorType(<output size>)]
[ColumnName("<output node name>")]
public float[] Data { get; set; } // Remember to change the type if your model does not use float
}
Load the model in onnx format.
using Microsoft.ML;
var modelPath = "<path to onnx model>";
var outputColumnNames = new[] { "<output name>" };
var inputColumnNames = new[] { "<input name>" };
var mlContext = new MLContext();
var pipeline = _mlContext.Transforms.ApplyOnnxModel(outputColumnNames, inputColumnNames, modelPath);
Make prediction
var input_data= ... // code to load input into an array
var input = new Input { Data = data };
var dataView = mlContext.Data.LoadFromEnumerable(new[] { input });
var transformedValues = pipeline.Fit(dataView).Transform(dataView);
var output = mlContext.Data.CreateEnumerable<Output>(transformedValues, reuseRowObject: false);
// code to use the result in output

How to store iOS startup custom scheme data in NSUserDefaults to read from Unity

My app is developed using Unity3d (2018) and c#. The app is then build for iOS. Now, I want to use a custom scheme to launch my iOS app and provide some extra information:
some-custom-scheme://some-parameter=some-value
I've read in the Unity forum that the best way to do this is to create a plugin in Unity and hook into the iOS startup pipeline as described in the forum post like this:
-(BOOL)application:(UIApplication*) application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions
{
NSArray *keyArray = [launchOptions allKeys];
if ([launchOptions objectForKey:[keyArray objectAtIndex:0]]!=nil) {
NSURL *url = [launchOptions objectForKey:[keyArray objectAtIndex:0]];
NSString *urlString = [url absoluteString];
[[NSUserDefaults standardUserDefaults] setObject:urlString forKey:#"url"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
Within the app, I simply check the PlayerPrefs like this:
var url = PlayerPrefs.GetString("url");
The url value however is empty. Iterating through the keys and alerting them in the app give two results: UIApplicationLaunchOptionsKey and UIApplicationLaunchOptionsSourceApplicationKey. Both irrelevant according the Apple documentation which state that the data should be in the UIApplicationLaunchOptionsAnnotationKey key.
I've also read this SO question telling the poster to use the openURL method.
I feel that I'm close but not there yet. What am I doing wrong and how can it be fixed? Which method is better? My approach using didFinishLaunchingWithOptions or the openURL method?
Any help is greatly appreciated!
Method openURL need for opening link. NSUserDefaults - local storage for app.
if need save you color scheme need use NSUserDefaults, if need opening link for use new color scheme need use openURL.
Save to NSUserDefaults
NSString *urlScheme = #"some-custom-scheme://some-parameter=some-value";
[[NSUserDefaults standardUserDefaults] setValue:urlScheme forKey:#"url"];
[[NSUserDefaults standardUserDefaults] synchronize];
Read NSUserDefaults
NSString *loadUrlScheme = [[NSUserDefaults standardUserDefaults] valueForKey:#"url"];
//loadUrlScheme = some-custom-scheme://some-parameter=some-value

Couldn't get Apple Photos details - C# macOS Sierra 10.12 Xamarin Application

I'm developing an iMac desktop application which is able to upload normal photos as well as Photos library (Previously iPhotos library) to online services like Flickr,SmugMug. Before upgrading to Sierra i was able to get details of iPhotos and could upload too but after upgradation those files/directories doesn't exist.
Below is the block by which i was getting files:
string PhotosLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Photos Library.photoslibrary/Database/apdb/Library.apdb");
But above is not working anymore in Sierra 10.12, if i go to finder itself to locate above mentioned path then i find 'Database' directory but no 'apdb' is there by which i can get Library.apdb
I have googled but no luck, can anybody please show me some pointers on how to get Photos Library files using C#.
Please tell me if i missed any information to share.
Thanks.
The Media Library Framework is the place to go if your situation permit.
NSDictionary<NSString, NSObject> options = new NSDictionary<NSString, NSObject>(
new[] { MLMediaLibrary.MediaLoadSourceTypesKey, MLMediaLibrary.MediaLoadIncludeSourcesKey },
new[] { new NSString(MLMediaSourceType.Image.ToString()), MLMediaSource.MediaSourcePhotosIdentifier }
);
var ml = new MLMediaLibrary(options);
ml.AddObserver("mediaSources", 0, (obj) => Console.WriteLine("Loaded"));
var src = ml.MediaSources; // returns null first time
In order to access MLMediaLibrary, your application has to be sandboxed and codesigned.
See also https://stackoverflow.com/a/29626032 to learn how to deal with entitlements.plist.

TFS can't find BuildDefinition

I am working on a solution where I want to get parameters from a Builddefinition per Code. When I hit it, I get an error message "No build definition was found for
team project ToyStory with name Spass-mit-Flaggen."
The used code is written below:
var tfsCreds = new TfsClientCredentials(new WindowsCredential(), false);
var tpc = new TfsTeamProjectCollection(new Uri(options.CollectionUri), tfsCreds);
var buildServer = (IBuildServer)tpc.GetService(typeof(IBuildServer));
var buildDetail = buildServer.GetBuild(new Uri(options.BuildUri));
var buildDefinition = buildServer.GetBuildDefinition(
buildDetail.TeamProject,
options.BuildDefinition);
The options object contains all program parameters. In this case they are the following strings:
options.CollectionUri == "http://tfs-test:8080/tfs/Test/"
options.BuildUri == "vstfs:///Build/Build/85"
options.BuildDefiniton == "Spass-mit-Flaggen"
Has someone an idea what's going wrong here?
Thanks in advance
You're using the old SOAP API for accessing builds. The new build system introduced in TFS 2015 doesn't use SOAP messaging, it has a totally separate REST API. You'll need to use the REST API, available in easily-consumable object model form on NuGet.

C# code completion with NRefactory 5

I just found out about NRefactory 5 and I would guess, that it is the most suitable solution for my current problem. At the moment I'm developing a little C# scripting application for which I would like to provide code completion. Until recently I've done this using the "Roslyn" project from Microsoft. But as the latest update of this project requires .Net Framework 4.5 I can't use this any more as I would like the app to run under Win XP as well. So I have to switch to another technology here.
My problem is not the compilation stuff. This can be done, with some more effort, by .Net CodeDomProvider as well. The problem ist the code completion stuff. As far as I know, NRefactory 5 provides everything that is required to provide code completion (parser, type system etc.) but I just can't figure out how to use it. I took a look at SharpDevelop source code but they don't use NRefactory 5 for code completion there, they only use it as decompiler. As I couldn't find an example on how to use it for code completion in the net as well I thought that I might find some help here.
The situation is as follows. I have one single file containing the script code. Actually it is not even a file but a string which I get from the editor control (by the way: I'm using AvalonEdit for this. Great editor!) and some assemblies that needs to get referenced. So, no solution files, no project files etc. just one string of source code and the assemblies.
I've taken a look at the Demo that comes with NRefactory 5 and the article on code project and got up with something like this:
var unresolvedTypeSystem = syntaxTree.ToTypeSystem();
IProjectContent pc = new CSharpProjectContent();
// Add parsed files to the type system
pc = pc.AddOrUpdateFiles(unresolvedTypeSystem);
// Add referenced assemblies:
pc = pc.AddAssemblyReferences(new CecilLoader().LoadAssemblyFile(
System.Reflection.Assembly.GetAssembly(typeof(Object)).Location));
My problem is that I have no clue on how to go on. I'm not even sure if it is the right approach to accomplish my goal. How to use the CSharpCompletionEngine? What else is required? etc. You see there are many things that are very unclear at the moment and I hope you can bring some light into this.
Thank you all very much in advance!
I've just compiled and example project that does C# code completion with AvalonEdit and NRefactory.
It can be found on Github here.
Take a look at method ICSharpCode.NRefactory.CSharp.CodeCompletion.CreateEngine. You need to create an instance of CSharpCompletionEngine and pass in the correct document and the resolvers. I managed to get it working for CTRL+Space compltition scenario. However I am having troubles with references to types that are in other namespaces. It looks like CSharpTypeResolveContext does not take into account the using namespace statements - If I resolve the references with CSharpAstResolver, they are resolved OK, but I am unable to correctly use this resolver in code completition scenario...
UPDATE #1:
I've just managed to get the working by obtaining resolver from unresolved fail.
Here is the snippet:
var mb = new DefaultCompletionContextProvider(doc, unresolvedFile);
var resolver3 = unresolvedFile.GetResolver(cmp, loc); // get the resolver from unresolvedFile
var engine = new CSharpCompletionEngine(doc, mb, new CodeCompletionBugTests.TestFactory(resolver3), pctx, resolver3.CurrentTypeResolveContext );
Update #2:
Here is the complete method. It references classes from unit test projects, sou you would need to reference/copy them into your project:
public static IEnumerable<ICompletionData> DoCodeComplete(string editorText, int offset) // not the best way to put in the whole string every time
{
var doc = new ReadOnlyDocument(editorText);
var location = doc.GetLocation(offset);
string parsedText = editorText; // TODO: Why there are different values in test cases?
var syntaxTree = new CSharpParser().Parse(parsedText, "program.cs");
syntaxTree.Freeze();
var unresolvedFile = syntaxTree.ToTypeSystem();
var mb = new DefaultCompletionContextProvider(doc, unresolvedFile);
IProjectContent pctx = new CSharpProjectContent();
var refs = new List<IUnresolvedAssembly> { mscorlib.Value, systemCore.Value, systemAssembly.Value};
pctx = pctx.AddAssemblyReferences(refs);
pctx = pctx.AddOrUpdateFiles(unresolvedFile);
var cmp = pctx.CreateCompilation();
var resolver3 = unresolvedFile.GetResolver(cmp, location);
var engine = new CSharpCompletionEngine(doc, mb, new CodeCompletionBugTests.TestFactory(resolver3), pctx, resolver3.CurrentTypeResolveContext );
engine.EolMarker = Environment.NewLine;
engine.FormattingPolicy = FormattingOptionsFactory.CreateMono();
var data = engine.GetCompletionData(offset, controlSpace: false);
return data;
}
}
Hope it helps,
Matra
NRefactory 5 is being used in SharpDevelop 5. The source code for SharpDevelop 5 is currently available in the newNR branch on github. I would take a look at the CSharpCompletionBinding class which has code to display a completion list window using information from NRefactory's CSharpCompletionEngine.

Categories

Resources