
Google語音識別技術詳解與實踐應用
當輸入特征被一個Linear層接收時,它們以一個展平成一維張量的形式接收,然后乘以權重矩陣。這個矩陣乘法產(chǎn)生輸出特征。
讓我們通過一個簡單的代碼示例來理解這一過程。
in_features = torch.tensor([1,2,3,4], dtype=torch.float32)
weight_matrix = torch.tensor([
[1,2,3,4],
[2,3,4,5],
[3,4,5,6]
], dtype=torch.float32)
> weight_matrix.matmul(in_features)
tensor([30., 40., 50.])
在這里,我們創(chuàng)建了一個一維張量in_features
和一個權重矩陣weight_matrix
。使用matmul()
函數(shù)來執(zhí)行矩陣乘法運算。
接下來,我們看看如何創(chuàng)建一個PyTorch的Linear層來完成相同的操作。
fc = nn.Linear(in_features=4, out_features=3, bias=False)
這里,我們定義了一個線性層,它接受4個輸入特征并把它們轉(zhuǎn)換成3個輸出特征,所以我們從4維空間轉(zhuǎn)換到3維空間。
我們將權重矩陣放在PyTorch LinearLayer類中,是由PyTorch創(chuàng)建。PyTorch LinearLayer類使用傳遞給構造函數(shù)的數(shù)字4和3來創(chuàng)建一個3 x 4的權重矩陣。讓我們通過查看PyTorch源代碼來驗證這一點。
def __init__(self, in_features, out_features, bias=True):
super(Linear, self).__init__()
self.in_features = in_features
self.out_features = out_features
self.weight = Parameter(torch.Tensor(out_features, in_features))
if bias:
self.bias = Parameter(torch.Tensor(out_features))
else:
self.register_parameter('bias', None)
self.reset_parameters()
有時我們會看到Linear層操作被稱為 y=Ax+b
。在這個方程中,我們有:
我們之前指出過,我們把層對象實例當作一個函數(shù)來調(diào)用是多么奇怪。
> fc(in_features)
tensor([-0.8877, 1.4250, 0.8370], grad_fn=)
使這成為可能的是PyTorch模塊類實現(xiàn)了另一個特殊的Python函數(shù),稱為__call__()
。如果一個類實現(xiàn)了__call__()
方法,那么只要對象實例被調(diào)用,這個特殊的調(diào)用方法就會被調(diào)用。
讓我們在PyTorch源代碼中看看這一點。
def __call__(self, *input, **kwargs):
for hook in self._forward_pre_hooks.values():
hook(self, input)
if torch._C._get_tracing_state():
result = self._slow_forward(*input, **kwargs)
else:
result = self.forward(*input, **kwargs)
for hook in self._forward_hooks.values():
hook_result = hook(self, input, result)
if hook_result is not None:
raise RuntimeError(
"forward hooks should never return any values, but '{}'"
"didn't return None".format(hook))
if len(self._backward_hooks) > 0:
var = result
while not isinstance(var, torch.Tensor):
if isinstance(var, dict):
var = next((v for v in var.values() if isinstance(v, torch.Tensor)))
else:
var = var[0]
grad_fn = var.grad_fn
if grad_fn is not None:
for hook in self._backward_hooks.values():
wrapper = functools.partial(hook, self)
functools.update_wrapper(wrapper, hook)
grad_fn.register_hook(wrapper)
return result
nn.Linear(in_features, out_features, bias=True)
來創(chuàng)建Linear層,其中in_features
是輸入特征的數(shù)量,out_features
是輸出特征的數(shù)量,bias
表示是否包含偏置項。