machinelearning icon indicating copy to clipboard operation
machinelearning copied to clipboard

ImageLoadingTransformer hides exceptions in Mapper.MakeGetter

Open mareklinka opened this issue 5 years ago • 10 comments

System information

  • OS version/distro: Windows 10 1809
  • .NET Version (eg., dotnet --info): 2.2.202

Issue

I recently tried to use ML.NET in a Xamarin-based UWP app. I targeted the earliest version of UWP that support .NET Standard 2.0 and everything installed correctly. My intention was to make use a separately-trained TensorFlow model to predict some data from an image.

While my code worked without issues in a .NET Core 2.2 console app, in the UWP it was failing. I was constantly getting an exception when attempting to load the target image - Image [whatever] was not found. No additional details, no inner exception.

Only after a fair amount of headscratching and trying various things I managed to find the culprit (which was obvious in hindsight): UWP does not support bitmaps. After I tried to replicate a little bit of the ImageLoader code, I got an unsupported platform exception.

This is all fair but then looking into the code some more, I found this: https://github.com/dotnet/machinelearning/blob/b5a8d9962a10bcf6b7885ba9a4efa56e2b65f3f4/src/Microsoft.ML.ImageAnalytics/ImageLoader.cs#L215

The code is catching all exceptions and throwing a custom exception in their place, without providing the base exception. I think this could be improved as part of making the API surface friendlier to use - spending an hour on this, I started to think I was doing something insanely wrong. The inner exception would have told me the root cause in 10 seconds flat.

So there are basically two issues:

  1. Hiding the base exceptions
  2. Image analytics won't work in UWP at all because of bitmaps

I think a fix for 1. could be relatively simple. 2. will be much more difficult and might not be desirable but I wanted to throw it out there. Maybe using a platform-agnostic implementation of image handling could be useful.

Opinions? Thoughts?

mareklinka avatar Apr 01 '19 16:04 mareklinka

@eerhardt @danmosemsft Can you provide information regarding System.Drawing.Common and it's UWP support? If it doesn't support UWP what is best alternative for System.Drawing?

Ivanidzo4ka avatar Apr 02 '19 04:04 Ivanidzo4ka

@safern @JeremyKuhne @nattress - do you have any recommendations here on using System.Drawing on UWP?

eerhardt avatar Apr 02 '19 17:04 eerhardt

@safern @JeremyKuhne @nattress - do you have any recommendations here on using System.Drawing on UWP?

Not really, Drawing is just a platform not supported assembly in UWP, we basically just throw there. I don't know if there are any plans on supporting it in the near future (even if we can because of all the P/Invokes to GDI+).

safern avatar Apr 02 '19 17:04 safern

So #1, yes it's a bug, and it need to be fixed #2 We will come up with plan how to enable image support in UWP. Our whole UWP story isn't great and I guess we would tackle this issue during work on UWP support.

Ivanidzo4ka avatar Apr 02 '19 23:04 Ivanidzo4ka

I was working with the exact same setup - Xamarin-based UWP utilising a previously trained TensorFlow model - and hit the PlatformNotSupportedException for System.Drawing when calling into the PredictionEngine:

System.PlatformNotSupportedException: 'System.Drawing is not supported on this platform.'

This exception was originally thrown at this call stack:
    System.Drawing.Bitmap.Bitmap(string)
    Microsoft.ML.Data.ImageLoadingTransformer.Mapper.MakeGetterImageDataViewType.AnonymousMethod__0(ref System.Drawing.Bitmap)
    Microsoft.ML.Transforms.Image.ImageResizingTransformer.Mapper.MakeGetter.AnonymousMethod__1(ref System.Drawing.Bitmap)
    Microsoft.ML.Transforms.Image.ImagePixelExtractingTransformer.Mapper.GetGetterCore.AnonymousMethod__1(ref Microsoft.ML.Data.VBuffer<TValue>)
    Microsoft.ML.Transforms.TensorFlowTransformer.TensorValueGetterVec<T>.GetTensor()
    Microsoft.ML.Transforms.TensorFlowTransformer.Mapper.UpdateCacheIfNeeded(long, Microsoft.ML.Transforms.TensorFlowTransformer.ITensorValueGetter[], string[], Microsoft.ML.Transforms.TensorFlowTransformer.Mapper.OutputCache)
    Microsoft.ML.Transforms.TensorFlowTransformer.Mapper.MakeGetter.AnonymousMethod__4(ref Microsoft.ML.Data.VBuffer<T>)
    Microsoft.ML.Data.TypedCursorable<TRow>.TypedRowBase.CreateDirectVBufferSetter.AnonymousMethod__0(TRow)
    Microsoft.ML.Data.TypedCursorable<TRow>.TypedRowBase.FillValues(TRow)
    Microsoft.ML.PredictionEngineBase<TSrc, TDst>.Predict(TSrc)
    ...
    [Call Stack Truncated]

It's my first time doing anything with ML.NET. Has there been any plan formulated to bring this sort of image support to ML.NET on UWP?

labChariot avatar Jan 10 '20 02:01 labChariot

Hi, @labChariot . As of now, ML.NET doesn't have any plan to provide image support on UWP.

antoniovs1029 avatar Jan 10 '20 19:01 antoniovs1029

Thanks @antoniovs1029

labChariot avatar Jan 12 '20 20:01 labChariot

ImageSharp just released RC2. I would love an implementation of the ImagePixelExtractingTransformer which is based of ImageSharp instead of GDI

I started to take a look at implementing something locally, but access modifiers on the base classes make that difficult. I haven't had time to look it is beyond that.

brianfeucht avatar Jun 09 '20 15:06 brianfeucht

Is there any progress on migrating from System.Drawing to ImageSharp? I saw it was mentioned on the Roadmap but it's not really clear if it's still being worked on. It's a very desirable change since NET7 will not support System.Drawing at all (even with a configuration switch) on any platform other than Windows.

XorZy avatar Aug 22 '22 17:08 XorZy

cc @luisquintanilla

dakersnar avatar Aug 25 '22 21:08 dakersnar

Same issue here. Any update?

mapo80 avatar Oct 02 '22 17:10 mapo80

There is a PR #6363 that should address this issue.

luisquintanilla avatar Oct 11 '22 14:10 luisquintanilla