在 ML.NET 中延迟加载位图

Lazy Loading Bitmaps in ML.NET

我在 ML.NET 图像分类中找到的所有示例在训练管道时都使用图像路径,但是在生产中。我想直接从位图进行预测,所以我将学习管道转换为使用位图而不是路径。这会导致其他问题,例如当我们有一个 IEnumerable 数据集列表,其中 615.000 个位图加载到内存中时,好吧,这台 PC 没有足够的 RAM。

有没有办法在管道 Fit/Trained 时创建包含位图模型的延迟加载 IEnumerable 数据集?

编辑:

根据 JonasH 的建议,我只是实现了自己的 Enumerator 来处理运行时加载图像。这是实现:

public class ImageDataCollection : IEnumerable<ImageClassificationData>
{
    private IEnumerable<string> files { get; set; }
    public Func<Bitmap, Bitmap> Handler { get; set; }

    public ImageDataCollection(IEnumerable<string> files)
    {
        this.files = files;
    }

    public IEnumerator<ImageClassificationData> GetEnumerator()
    {
        IEnumerator<string> iterator = files.GetEnumerator();
        while (iterator.MoveNext())
        {
            string data = iterator.Current;
            Bitmap image = new Bitmap(data);
            if (Handler != null)
            {
                image = Handler(image);
            }
            string[] c = data.Split(new char[] { '\' });
            yield return new ImageClassificationData { Label = c[c.Length - 1], Image = image };
            image.Dispose();
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

This WORKS 但是我希望将其视为 ML.NET 中的某种扩展方法,如果可能的话,或者至少记录在案,因为这是没有说清楚,毕竟 DEEP Learning 使用了很多 RAM :P ..

Linq 语句是惰性求值的。因此,如果您有一个路径列表并使用 select 语句加载位图,则应该延迟加载它们,除非管道使用 .ToList() 或类似方法将 IEnumerable 实体化。

但是,位图使用非托管内存进行存储,除非您想依赖终结器来释放内存,否则应将其丢弃。您也许可以使用 iterator block 来生成位图然后处理它,但是如果框架在迭代之间保留引用,这可能会失败,例如在并行循环中。