{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 网络内构造常量\n", "\n", "`Ascend` `GPU` `CPU` `模型开发`\n", "\n", "[![在线运行](https://gitee.com/mindspore/docs/raw/r1.6/resource/_static/logo_modelarts.png)](https://authoring-modelarts-cnnorth4.huaweicloud.com/console/lab?share-url-b64=aHR0cHM6Ly9taW5kc3BvcmUtd2Vic2l0ZS5vYnMuY24tbm9ydGgtNC5teWh1YXdlaWNsb3VkLmNvbS9ub3RlYm9vay9tYXN0ZXIvcHJvZ3JhbW1pbmdfZ3VpZGUvemhfY24vbWluZHNwb3JlX2NvbnN0ZXhwci5pcHluYg==&imageid=65f636a0-56cf-49df-b941-7d2a07ba8c8c) [![下载Notebook](https://gitee.com/mindspore/docs/raw/r1.6/resource/_static/logo_notebook.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r1.6/programming_guide/zh_cn/mindspore_constexpr.ipynb) [![下载样例代码](https://gitee.com/mindspore/docs/raw/r1.6/resource/_static/logo_download_code.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r1.6/programming_guide/zh_cn/mindspore_constexpr.py) [![查看源文件](https://gitee.com/mindspore/docs/raw/r1.6/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/r1.6/docs/mindspore/programming_guide/source_zh_cn/constexpr.ipynb)\n", "\n", "`mindspore.ops.constexpr`中提供了一个@constexpr的Python\n", "装饰器,该装饰器可以用于修饰一个函数,该函数在编译阶段将会通过Python解释器执行,最终在MindSpore的类型推导阶段被常量折叠成为ANF图的一个常量节点(ValueNode)。\n", "\n", "由于该函数在MindSpore编译时期进行,所以使用@constexpr函数时,要求输入函数的入参必须为一个编译时刻就能够确定的常量值,否则如果该函数入参为一个编译时刻无法确定的值,那么入参将会为None,从而可能导致函数输出与预期不符。\n", "\n", "当@constexpr的入参为提前明确的参数时可以实现一些在construct函数中不支持的操作。比如根据shape创建Tensor等。\n", "\n", "为了避免出现@constexpr输入为编译时无法确定的值,可以在内部进行对None的判断处理,避免一些未知错误。\n", "\n", "代码样例如下:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2022-01-04T02:52:51.150509Z", "start_time": "2022-01-04T02:52:48.980586Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[7. 6. 3.]\n" ] } ], "source": [ "import numpy as np\n", "from mindspore.ops import constexpr\n", "import mindspore.ops as ops\n", "import mindspore.nn as nn\n", "from mindspore import Tensor\n", "import mindspore\n", "\n", "\n", "@constexpr\n", "def construct_tensor(x):\n", " if x is None:\n", " raise ValueError(\"input is an unknown value\")\n", " return Tensor(np.array(x), dtype=mindspore.float32)\n", "\n", "\n", "class Net(nn.Cell):\n", " def __init__(self):\n", " super(Net, self).__init__()\n", " self.relu = ops.ReLU()\n", "\n", " def construct(self, x):\n", " return self.relu(construct_tensor(ops.shape(x)))\n", "\n", "\n", "net = Net()\n", "x = Tensor(np.random.random([7, 6, 3]))\n", "out = net(x)\n", "print(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如下所示,如果我们将Net改成输入为编译时无法确定的值时,则会抛出异常。 由于construct_tensor输入为运行ReLU时才能确定的值。在constexpr中会抛出ValueError。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "@constexpr\n", "def construct_tensor(x):\n", " if x is None:\n", " raise ValueError(\"input is an unknown value\")\n", " return Tensor(np.array(x), dtype=mindspore.float32)\n", "\n", "\n", "class Net(nn.Cell):\n", " def __init__(self):\n", " super(Net, self).__init__()\n", " self.relu = ops.ReLU()\n", "\n", " def construct(self, x):\n", " return self.relu(construct_tensor(self.relu(x)))\n", "\n", "\n", "net = Net()\n", "x = Tensor(np.random.random([7, 6, 3]))\n", "out = net(x)\n", "print(out)\n", "```\n", "\n", "运行结果如下:\n", "\n", "```text\n", "ValueError: input is an unknown value\n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "mindspore" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.5" } }, "nbformat": 4, "nbformat_minor": 4 }