讀源碼torch.nn.Module

def init(self):

定義了很多有序字典OrderedDict()
在創(chuàng)建網(wǎng)絡時疏叨,我們要實現(xiàn)該方法,通過spuer方法將init里的表達式繼承下來。
從python類的用法上講,也可以采用baseClass.__init__()的方式妄壶,但是通常不這么用,這里每驗證這么用會不會出問題寄狼,只是溫習一下python的使用方法丁寄。

def forward(self, *input):

這個方法要被重寫,上面的init方法叫實現(xiàn)泊愧。
該方法傳入輸入伊磺。

def forward(self, *input):
    raise NotImplementedError

采用這種方式達到不重寫就會報對應的錯。方法很好删咱。

def register_buffer(self, name, tensor):

向模塊添加持久緩沖區(qū)屑埋。

def register_buffer(self, name, tensor):
    if '_buffers' not in self.__dict__:
            raise AttributeError(
                "cannot assign buffer before Module.__init__() call")
        elif not isinstance(name, torch._six.string_classes):
            raise TypeError("buffer name should be a string. "
                            "Got {}".format(torch.typename(name)))
        elif '.' in name:
            raise KeyError("buffer name can't contain \".\"")
        elif name == '':
            raise KeyError("buffer name can't be empty string \"\"")
        elif hasattr(self, name) and name not in self._buffers:
            raise KeyError("attribute '{}' already exists".format(name))
        elif tensor is not None and not isinstance(tensor, torch.Tensor):
            raise TypeError("cannot assign '{}' object to buffer '{}' "
                            "(torch Tensor or None required)"
                            .format(torch.typename(tensor), name))
        else:
            self._buffers[name] = tensor

如果參數(shù)name類型不對會報相應的錯。

def register_parameter(self, name, param):

向模塊添加參數(shù)痰滋。
同樣會做一些格式和存在與否的判斷摘能,進而報錯,這是我應該學習的方式敲街。兩個參數(shù)分了三步去判斷团搞。

def add_module(self, name, module):

給當前模塊添加一個子模塊。
同時做一些isinstance hasattr == 的判斷raise一些TypeError KeyError

def _apply(self, fn):

這是后續(xù)方法要經(jīng)常調(diào)用的方法
pytorch的更新參數(shù)最底層的方法都是這個方法和def apply(self, fn)定義的多艇。

def apply(self, fn):

def cuda(self, device=None):

將所有模型參數(shù)和緩沖區(qū)移至GPU逻恐。

def cuda(self, device=None):
    return self._apply(lambda t: t.cuda(device))

def cpu(self):

將所有模型參數(shù)和緩沖區(qū)移至CPU。

def cpu(self):
    return self._apply(lambda t: t.cpu())

def type(self, dst_type):

將所有參數(shù)和緩沖區(qū)強制轉換為dst_type峻黍。

def type(self, dst_type):
    return self._apply(lambda t: t.type(dst_type))

def float(self):

將所有浮點參數(shù)和緩沖區(qū)強制轉換為float數(shù)據(jù)類型复隆。

def float(self):
    return self._apply(lambda t: t.float() if t.is_floating_point() else t)

def double(self):

將所有浮點參數(shù)和緩沖區(qū)強制轉換為“ double”數(shù)據(jù)類型。

def half(self):

將所有浮點參數(shù)和緩沖區(qū)強制轉換為“ half”數(shù)據(jù)類型姆涩。
Half是用16位表示浮點數(shù)的一種數(shù)據(jù)類型挽拂,在IEEE 754中也有規(guī)定,這種數(shù)據(jù)類型在深度學習系統(tǒng)中的應用比較廣泛骨饿。但是在當前主流cpu上轻局,不支持half類型數(shù)據(jù)的計算和輸出,所以需要half和float兩個數(shù)據(jù)類型之間的轉換样刷。
IEEE754-2008包含一種“半精度”格式,只有16位寬览爵。故它又被稱之為binary16置鼻,這種類型的浮點數(shù)只適合用于存儲那些對精度要求不高的數(shù)字,不適合用于進行計算蜓竹。與單精度浮點數(shù)相比箕母,它的優(yōu)點是只需要一半的存儲空間和帶寬储藐,但是缺點是精度較低。

def to(self, *args, **kwargs):

移動或強制轉換參數(shù)和緩沖區(qū)嘶是。

Example::
            >>> linear = nn.Linear(2, 2)
            >>> linear.weight
            Parameter containing:
            tensor([[ 0.1913, -0.3420],
                    [-0.5113, -0.2325]])
            >>> linear.to(torch.double)
            Linear(in_features=2, out_features=2, bias=True)
            >>> linear.weight
            Parameter containing:
            tensor([[ 0.1913, -0.3420],
                    [-0.5113, -0.2325]], dtype=torch.float64)
            >>> gpu1 = torch.device("cuda:1")
            >>> linear.to(gpu1, dtype=torch.half, non_blocking=True)
            Linear(in_features=2, out_features=2, bias=True)
            >>> linear.weight
            Parameter containing:
            tensor([[ 0.1914, -0.3420],
                    [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1')
            >>> cpu = torch.device("cpu")
            >>> linear.to(cpu)
            Linear(in_features=2, out_features=2, bias=True)
            >>> linear.weight
            Parameter containing:
            tensor([[ 0.1914, -0.3420],
                    [-0.5112, -0.2324]], dtype=torch.float16)

def register_backward_hook(self, hook):

在模塊上注冊反向掛鉤钙勃。
每當計算相對于模塊輸入的梯度時,都會調(diào)用該掛鉤聂喇。

def register_forward_pre_hook(self, hook):

在模塊上注冊前向預鉤辖源。
每次調(diào)用:func:forward之前,都會調(diào)用該鉤子希太。

def register_forward_hook(self, hook):

在模塊上注冊一個前向掛鉤克饶。
每當:func:forward計算出輸出后,該鉤子就會被調(diào)用誊辉。

def _slow_forward(self, *input, **kwargs):

沒有加速的前向函數(shù).

def _call_(self, *input, **kwargs):

給個參數(shù)就執(zhí)行的前向調(diào)用?

def _setstate_(self, state):

快速設置所有字典狀態(tài)

def _getattr_(self, name):

獲取屬性

def _setattr_(self, name, value):

設置屬性

def _delattr_(self, name):

刪除屬性

def _register_state_dict_hook(self, hook):

這個鉤子可以就地修改“ state_dict”或返回一個新的矾湃。

def_save_to_state_dict(self, destination, prefix, keep_vars):

將模塊狀態(tài)保存到“destination”字典中,其中包含模塊的狀態(tài)堕澄,但不包含其后代邀跃。

def state_dict(self, destination=None, prefix='', keep_vars=False):

返回包含模塊整個狀態(tài)的字典。

def _register_load_state_dict_pre_hook(self, hook):

這些鉤子將被以下參數(shù)進行調(diào)用:state_dict蛙紫,prefix拍屑,local_metadata,strict惊来,strict丽涩,missing_keys,unexpected_keys裁蚁,
error_msgs矢渊,在將state_dict加載到self之前。 這些參數(shù)與_load_from_state_dict的參數(shù)完全相同枉证。

def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs):

從:attr:'state_dict'復制參數(shù)和緩沖區(qū)矮男。

def load_state_dict(self, state_dict, strict=True):

將參數(shù)和緩沖區(qū)從state_dict復制到此模塊及其后代中。

def _named_members(self, get_members_fn, prefix='', recurse=True):

產(chǎn)生各種名稱+模塊成員的輔助方法室谚。

def parameters(self, recurse=True):

返回模塊參數(shù)上的迭代器毡鉴。

def named_parameters(self, prefix='', recurse=True):

返回包含模塊參數(shù)的迭代器,yield返回參數(shù)名稱和參數(shù)本身秒赤。

def buffers(self, recurse=True):

返回模塊緩沖的迭代器猪瞬。

def named_buffers(self, prefix='', recurse=True):

返回模塊緩沖的迭代器,包括緩沖的名字和緩沖本身入篮。

def children(self):

返回直接子模塊構成的迭代器陈瘦。

def children(self):
    for name, module in self.named_children():
        yield module

def named_children(self):

返回直接子模塊的迭代器,同時yield返回模塊的名稱和模塊本身潮售。

def modules(self):

返回網(wǎng)絡中所有模塊的迭代器痊项。

def named_modules(self, memo=None, prefix=''):

同時返回名字

def train(self, mode=True):

常用的锅风,如model.train()
作用是使模塊處于訓練狀態(tài)。
mode=True training mode
mode=True evaluation mode
代碼很簡單

def train(self, mode=True):
    self.training = mode #使self.training=True
    for module in self.children(): 把children以及children的children也設置為True鞍泉,所以這里使用的是調(diào)用自己皱埠,進而構成循環(huán)
        module.train(mode)
    return self

return self是一種鏈式調(diào)用。

class Foo(object):

  def __init__(self):
    self.myattr = 0

  def bar(self):
    self.myattr += 1
    return self

f = Foo()
f.bar().bar().bar()
print(f.myattr)
輸出結果為3.
把bar()方法改為返回return None咖驮, 則上述代碼會出錯边器。

def eval(self):

def eval(self):
    return self.train(False)

def requires_grad_(self, requires_grad=True):

這個也是很重要很常用的函數(shù)
Change if autograd should record operations
on parameters in this module.
控制自動求導是否記錄求導結果,它是單個模塊控制的游沿。

def requires_grad_(self, requires_grad=True):

    for p in self.parameters():
        p.requires_grad_(requires_grad) #也是遞歸的調(diào)用饰抒,也是return self
    return self

def zero_grad(self):

將所有模型參數(shù)的梯度設置為零。

def zero_grad(self):
    r"""Sets gradients of all model parameters to zero."""
    for p in self.parameters():#遍歷所以參數(shù)
        if p.grad is not None:#如果存在
            p.grad.detach_()
            p.grad.zero_()#使用其他函數(shù)設置為0

此外诀黍,

def parameters(self, recurse=True):
    for name, param in self.named_parameters(recurse=recurse):
        yield param

所以self.parameters()是parameters方法產(chǎn)生的一個遞歸袋坑。
最終用到的數(shù)據(jù)來自module._parameters.items()

def share_memory(self):

好像是共享內(nèi)存

def _get_name(self):

def _get_name(self):
    return self.__class__.__name__

返回本類的名字

def extra_repr(self):

設置模塊的額外表示形式

def extra_repr(self):
    return ''

默認為空字符串,需要重寫該方法以達到額外命名

def repr(self):

一個表示形式眯勾,用到上面的額外命名枣宫,分有沒有額外名情況去組織結果。

def dir(self):

老博客地址:http://www.reibang.com/u/1c73a3a8ae2d
新博客地址:https://inspiring26.github.io/

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吃环,一起剝皮案震驚了整個濱河市也颤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郁轻,老刑警劉巖翅娶,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異好唯,居然都是意外死亡竭沫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門骑篙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜕提,“玉大人,你說我怎么就攤上這事靶端』咽疲” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵杨名,是天一觀的道長脏榆。 經(jīng)常有香客問我,道長台谍,這世上最難降的妖魔是什么姐霍? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上镊折,老公的妹妹穿的比我還像新娘。我一直安慰自己介衔,他們只是感情好恨胚,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炎咖,像睡著了一般赃泡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乘盼,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天升熊,我揣著相機與錄音,去河邊找鬼绸栅。 笑死级野,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的粹胯。 我是一名探鬼主播蓖柔,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼风纠!你這毒婦竟也來了况鸣?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤竹观,失蹤者是張志新(化名)和其女友劉穎镐捧,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臭增,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡懂酱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了速址。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玩焰。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡卸奉,死狀恐怖祈餐,靈堂內(nèi)的尸體忽然破棺而出希柿,到底是詐尸還是另有隱情蜓堕,我是刑警寧澤阵漏,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布鞠值,位于F島的核電站引几,受9級特大地震影響芭毙,放射性物質發(fā)生泄漏逃魄。R本人自食惡果不足惜荤西,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邪锌,春花似錦勉躺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至妇萄,卻和暖如春蜕企,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冠句。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工轻掩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人懦底。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓唇牧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親基茵。 傳聞我的和親對象是個殘疾皇子奋构,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348