在 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 来生成位图然后处理它,但是如果框架在迭代之间保留引用,这可能会失败,例如在并行循环中。
我在 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 来生成位图然后处理它,但是如果框架在迭代之间保留引用,这可能会失败,例如在并行循环中。