源碼地址: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相關函數
在這裏插入代碼片