源码地址:https://mxnet.incubator.apache.org/api/python/docs/_modules/mxnet/gluon/block.html#Block.name_scope
其他参考:
参数和Block命名:https://mxnet.incubator.apache.org/api/python/docs/tutorials/packages/gluon/blocks/naming.html
写在前面
name_scope函数是在Block中定义的,而又因为HybridBlock是Block的子类,所以
Block和HybridBlock都有这个函数。而gluon.nn,或者gluon.contrib下定义的高层次的组件继承了HybridBlock,一言概之,gluon中的模型,都具有name_scope功能。
调用 with xxx.name_scope时候,实际调用的是Block的name_scope函数,而name_scope返回的是self._scope,Block在构造的时候,会创建self._scope属性,而self._scope=_BlockScope(self),所以with语句最终调用的是_BlockScope。
_BlockScope类的定义
import threading
class _BlockScope(object):
"""Scope for collecting child `Block` s."""
_current = threading.local() # 确保_current中的同名变量在多线程之间互不干扰
def __init__(self, block):
self._block = block # block是gluon.Block或者gluon.HybridBlock
self._counter = {}
self._old_scope = None
self._name_scope = None
@staticmethod
def create(prefix, params, hint):
# Block调用时,hint是self._alias(),而self._alias()返回的是类名,
# self.__class__.__name__.lower()
"""Creates prefix and params for new `Block`."""
current = getattr(_BlockScope._current, "value", None)
if current is None:
if prefix is None:
if not hasattr(_name.NameManager._current, "value"):
_name.NameManager._current.value = _name.NameManager()
prefix = _name.NameManager._current.value.get(None, hint) + '_'
if params is None:
params = ParameterDict(prefix)
else:
params = ParameterDict(params.prefix, params)
return prefix, params
if prefix is None:
count = current._counter.get(hint, 0)
prefix = '%s%d_'%(hint, count)
current._counter[hint] = count + 1
if params is None:
parent = current._block.params
params = ParameterDict(parent.prefix+prefix, parent._shared)
else:
params = ParameterDict(params.prefix, params)
return current._block.prefix+prefix, params
def __enter__(self):
if self._block._empty_prefix:
return self
self._old_scope = getattr(_BlockScope._current, "value", None)
_BlockScope._current.value = self
self._name_scope = _name.Prefix(self._block.prefix)
self._name_scope.__enter__()
return self
def __exit__(self, ptype, value, trace):
if self._block._empty_prefix:
return
self._name_scope.__exit__(ptype, value, trace)
self._name_scope = None
_BlockScope._current.value = self._old_scope
Block相关函数
在这里插入代码片