<jupyter_start><jupyter_text>序列化 --- 读写模型我们现在已经讲了很多，包括- 如何处理数据- 如何构建模型- 如何在数据上训练模型- 如何使用不同的损失函数来做分类和回归但即使知道了所有这些，我们还没有完全准备好来构建一个真正的机器学习系统。这是因为我们还没有讲如何读和写模型。因为现实中，我们通常在一个地方训练好模型，然后部署到很多不同的地方。我们需要把内存中的训练好的模型存在硬盘上好下次使用。 读写NDArrays作为开始，我们先看看如何读写NDArray。虽然我们可以使用Python的序列化包例如`Pickle`，不过我们更倾向直接`save`和`load`，通常这样更快，而且别的语言，例如R和Scala也能用到。<jupyter_code>from mxnet import nd

x = nd.ones(3)
y = nd.zeros(4)
filename = "../data/test1.params"
nd.save(filename, [x, y])<jupyter_output><empty_output><jupyter_text>读回来<jupyter_code>a, b = nd.load(filename)
print(a, b)<jupyter_output>[ 1.  1.  1.]
<NDArray 3 @cpu(0)> 
[ 0.  0.  0.  0.]
<NDArray 4 @cpu(0)><jupyter_text>不仅可以读写单个NDArray，NDArray list，dict也是可以的：<jupyter_code>mydict = {"x": x, "y": y}
filename = "../data/test2.params"
nd.save(filename, mydict)
c = nd.load(filename)
print(c)<jupyter_output>{'x': 
[ 1.  1.  1.]
<NDArray 3 @cpu(0)>, 'y': 
[ 0.  0.  0.  0.]
<NDArray 4 @cpu(0)>}<jupyter_text>读写Gluon模型的参数跟NDArray类似，Gluon的模型（就是`nn.Block`）提供便利的`save_params`和`load_params`函数来读写数据。我们同前一样创建一个简单的多层感知机<jupyter_code>from mxnet.gluon import nn

def get_net():
    net = nn.Sequential()
    with net.name_scope():
        net.add(nn.Dense(10, activation="relu"))
        net.add(nn.Dense(2))
    return net

net = get_net()
net.initialize()
x = nd.random.uniform(shape=(2,10))
print(net(x))<jupyter_output>[[ 0.00205935 -0.00979935]
 [ 0.00107034 -0.00423382]]
<NDArray 2x2 @cpu(0)><jupyter_text>下面我们把模型参数存起来<jupyter_code>filename = "../data/mlp.params"
net.save_params(filename)<jupyter_output><empty_output><jupyter_text>之后我们构建一个一样的多层感知机，但不像前面那样随机初始化，我们直接读取前面的模型参数。这样给定同样的输入，新的模型应该会输出同样的结果。<jupyter_code>import mxnet as mx
net2 = get_net()
net2.load_params(filename, mx.cpu())  # FIXME, gluon will support default ctx later 
print(net2(x))<jupyter_output>[[ 0.00205935 -0.00979935]
 [ 0.00107034 -0.00423382]]
<NDArray 2x2 @cpu(0)>
{'fraction_non_alphanumeric': 0.1639957264957265, 'fraction_numerical': 0.060363247863247864, 'mean_word_length': 6.55241935483871, 'pattern_counts': {'":': 2, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '532221', 'license': 'Apache-2.0', 'n_tokens_mistral': 1121, 'n_tokens_neox': 1110, 'n_words': 113, 'path': 'chapter_gluon-basics/serialization.ipynb', 'repo_name': 'kyoyo/gluon_tutorials_zh_git', 'size': '1872'}