mxnet-gluon學習筆記之 - name_scope

源碼地址: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相關函數

在這裏插入代碼片
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章