Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用numpy实现MXNet参数序列化_Python_Numpy_Mxnet_S390x - Fatal编程技术网

Python 使用numpy实现MXNet参数序列化

Python 使用numpy实现MXNet参数序列化,python,numpy,mxnet,s390x,Python,Numpy,Mxnet,S390x,我想在s390x架构上使用预先训练过的MXNet模型,但它似乎不起作用。这是因为预先训练的模型是小端的,而s390x是大端的。所以,我试着使用对小端和大端都有效的方法 解决这个问题的一种方法是在x86机器上加载模型参数,调用asnumpy,通过numpy保存,然后使用numpy在s390x机器上加载参数,并将其转换为MXNet。但我真的不知道如何编码。谁能帮我一下吗 更新 这个问题似乎还不清楚。所以,我添加了一个例子,更好地解释了我想在3个步骤中做什么- 从MXNet加载一个预先存在的模型,类似

我想在s390x架构上使用预先训练过的MXNet模型,但它似乎不起作用。这是因为预先训练的模型是小端的,而s390x是大端的。所以,我试着使用对小端和大端都有效的方法

解决这个问题的一种方法是在x86机器上加载模型参数,调用asnumpy,通过numpy保存,然后使用numpy在s390x机器上加载参数,并将其转换为MXNet。但我真的不知道如何编码。谁能帮我一下吗

更新

这个问题似乎还不清楚。所以,我添加了一个例子,更好地解释了我想在3个步骤中做什么-

  • 从MXNet加载一个预先存在的模型,类似这样-
  • 导出模型。以下代码将模型参数保存在.param文件中。但是这个.param二进制文件有endian问题。因此,我希望使用numpy-保存参数文件,而不是使用mxnetapi直接保存模型。因为使用numpy,将使二进制文件(.npy)endian独立。我不知道如何将MXNet模型的参数转换为numpy格式并保存它们
  • 加载模型。下面的代码从.param文件加载模型

  • 我希望使用numpy来加载我们在步骤2中创建的.npy文件,而不是使用MXNETAPI进行加载。加载.npy文件后,需要将其转换为MXNet。因此,我最终可以在MXNet中使用该模型。

    从另一个问题中发布的代码片段开始:

    mxnet似乎有一个选项,可以在内部将数据存储为numpy阵列:

    mx.npx.set_np(True, True)
    
    不幸的是,这个选项没有达到我希望的效果(我的IPython会话崩溃)

    参数是
    mxnet.glion.parameter.parameter
    实例的
    dict
    ,每个实例都包含其他特殊数据类型的属性。将其分离,以便将其存储为大量纯numpy数组(或将它们的集合存储在
    .npz
    文件中),这是一项毫无希望的任务

    幸运的是,python有
    pickle
    将复杂的数据结构转换成或多或少可移植的东西:

    # (mxnet/resnet setup skipped)
    parameters = resnet.collect_params()
    
    import pickle
    with open('foo.pkl', 'wb') as f:
        pickle.dump(parameters, f)
    
    要恢复参数,请执行以下操作:

    with open('foo.pkl', 'rb') as f:
        parameters_loaded = pickle.load(f)
    
    本质上,它看起来像
    mxnet/glion/block.py
    中定义的
    resnet.save_parameters()
    获取参数(使用
    \u collect_parameters\u和前缀()
    )并使用自定义写入函数将其写入文件,该函数似乎是从C编译的(我没有检查详细信息)

    您可以改为使用
    pickle
    保存参数

    对于加载,
    load\u参数(也在
    util.py
    中)包含以下代码(删除了健全性检查):

    这里,
    load
    是从文件加载的dict。通过检查代码,我没有完全掌握加载的内容-
    params
    似乎是函数中不再使用的局部变量。但从这里开始值得一试,为
    load\u parameters
    函数编写一个替换函数。通过在类外定义函数,可以将函数“猴子补丁”到现有类中,如下所示:

    def my_load_parameters(self, ...):
       ... (put your modified implementation here)
    
    mx.gluon.Block.load_parameters = my_load_parameters
    
    免责声明/警告:

    • 即使通过
      pickle
      获得save/load以在单个big-endian系统上工作,也不能保证在不同的endian系统之间工作。pickle协议本身是endian中立的,但是如果是浮点值(在
      mxnet.glion.parameter.parameter的深处,parameter
      被存储为机器endian约定的原始数据缓冲区,那么pickle不会神奇地猜测缓冲区中的8字节组需要反转。我认为当pickle时,numpy数组是endian安全的
    • 如果基础类定义在Pickle和unpickle之间发生变化,Pickle就不是很健壮
    • 永远不要取消勾选不受信任的数据

    您能提供一个生成/保存/加载模型(不处理endian ness)的最小示例吗?@Han KwangNienhuys我想在mxnet中加载一个先前存在的胶子模型。假设我们将该模型设为resnet-50。因此,我想编写将resnet-50参数保存为numpy文件(.npy)的代码。然后我想导入这个.npy文件以在另一台计算机上使用resnet-50模型。我不确定该如何用Python编写此文件。您能提供帮助吗?使用.npy扩展名将自动解决任何endian问题。因此,只生成/保存/加载模型的代码将在不考虑endianness的情况下工作。我无法编码这个approach@Han-KwangNienhuys我添加了一个示例。如果您需要更多信息,请让我知道。可复制的示例可以复制粘贴用于实验,并且可以工作或演示问题,而无需依赖您的私人文件。仍然不工作,得到以下-
    回溯:loaded_dict=pickle.load(f)File“/root/mxnet-1.5.0/mxnet/python/mxnet/ndarray/ndarray.py”,第386行,在设置状态检查调用中(_LIB.mxndarrayoladfromrawbytes(ptr,length,ctypes.byref(handle))/root/mxnet-1.5.0/mxnet/python/mxnet/base.py),第253行,在检查调用中引发MXNetError(py_str(_-str.mxnet.getlasterror())错误:[15:34:40]include/mxnet//tuple.h:354:检查失败:ndim>=-1(-906324999 vs-1):ndim不能小于-1,收到-906324999
    ,感谢您的努力。我看到您正在使用mxnet 1.5.0。我安装了mxnet 1.6(通过pip,在Anaconda 64位Linux中使用Python 3.7.6/numpy 1.18.1)还有我发布的pickle转储/加载循环。您是否将参数pickle文件保存在一个小的endian机器上,然后加载到big endian机器上?对不起,没有,我在同一台机器上进行了转储/加载往返。恐怕您必须修补C代码。
    # (mxnet/resnet setup skipped)
    parameters = resnet.collect_params()
    
    import pickle
    with open('foo.pkl', 'wb') as f:
        pickle.dump(parameters, f)
    
    with open('foo.pkl', 'rb') as f:
        parameters_loaded = pickle.load(f)
    
    for name in loaded:
        params[name]._load_init(loaded[name], ctx, cast_dtype=cast_dtype, dtype_source=dtype_source)
    
    def my_load_parameters(self, ...):
       ... (put your modified implementation here)
    
    mx.gluon.Block.load_parameters = my_load_parameters