【发布时间】:2019-12-10 18:13:50
【问题描述】:
我正在尝试从 C# (.NET Framework) 中的 HDF5 文件加载数据集,以便将内容保存在数组中,例如float[,]。我找到了HDF.PInvoke 库,但我发现很难弄清楚如何使用它。
更新
来自Soonts answer,我设法让它工作。这是我的工作 sn-p:
using System;
using System.Runtime.InteropServices;
using HDF.PInvoke;
namespace MyNamespace
{
class Program
{
static void Main()
{
string datasetPath = "/dense1/dense1/kernel:0";
long fileId = H5F.open(@"\path\to\weights.h5", H5F.ACC_RDONLY);
long dataSetId = H5D.open(fileId, datasetPath);
long typeId = H5D.get_type(dataSetId);
// read array (shape may be inferred w/ H5S.get_simple_extent_ndims)
float[,] arr = new float[162, 128];
GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned);
try
{
H5D.read(dataSetId, typeId, H5S.ALL, H5S.ALL, H5P.DEFAULT,
gch.AddrOfPinnedObject());
}
finally
{
gch.Free();
}
// show one entry
Console.WriteLine(arr[13, 87].ToString());
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
原来的第一次尝试:
到目前为止我所管理的:
using System;
using System.IO;
using System.Runtime.InteropServices;
using HDF.PInvoke;
namespace MyNamespace
{
class Program
{
static void Main()
{
string datasetPath = "/dense1/dense1/bias:0";
long fileId = H5F.open(@"\path\to\weights.h5", H5F.ACC_RDONLY);
long dataSetId = H5D.open(fileId, datasetPath);
long typeId = H5D.get_type(dataSetId);
long spaceId = H5D.get_space(dataSetId);
// not sure about this
TextWriter tw = Console.Out;
GCHandle gch = GCHandle.Alloc(tw);
// I was hoping that this would write to the Console, but the
// program crashes outside the scope of the c# debugger.
H5D.read(
dataSetId,
typeId,
H5S.ALL,
H5S.ALL,
H5P.DEFAULT,
GCHandle.ToIntPtr(gch)
);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
H5F.read() 的签名是:
Type Name Description
--------------------------------------------------------------
long dset_id Identifier of the dataset read from.
long mem_type_id Identifier of the memory datatype.
long mem_space_id Identifier of the memory dataspace.
long file_space_id Identifier of the dataset's dataspace in the file.
long plist_id Identifier of a transfer property list for this I/O operation.
IntPtr buf Buffer to receive data read from file.
问题
谁能帮我填这里的空白?
【问题讨论】:
-
顺便说一句,HDF5 是垃圾。 API 设计和文档不是很好。它很慢。它是单线程的,当尝试从多个线程使用时崩溃,即使是不同的文件。这是不可靠的,如果出现任何问题,通常会破坏包含所有数据集的完整文件。如果你打算用它来写东西而不仅仅是阅读,我建议你找一个替代品。
-
相信我,我也对整件事感到非常沮丧。只是我需要它来反序列化keras创建的一些模型权重,它使用h5py。
-
你可以用一行代码替换你的重塑代码
Buffer.BlockCopy( arrFlat, 0, arr, 0, w * h * 4 );会快得多。对这么小的数组并不重要,但仍然如此。 -
另外,由于您不需要转置或填充数据,您可以尝试固定二维数组,并将其传递给原生库。也可能会起作用,这样您根本不需要复制/重塑。
-
@AdamB
kernel:0只是 Keras 在调用keras_model.save_weights('weights.h5')(在 python 中)时赋予数据集的名称。
标签: c# hdf5 hdf5dotnet