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/