Linear層與矩陣乘法

當輸入特征被一個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í)行矩陣乘法運算。

二、使用PyTorch線性層進行變換

接下來,我們看看如何創(chuàng)建一個PyTorch的Linear層來完成相同的操作。

fc = nn.Linear(in_features=4, out_features=3, bias=False)

這里,我們定義了一個線性層,它接受4個輸入特征并把它們轉(zhuǎn)換成3個輸出特征,所以我們從4維空間轉(zhuǎn)換到3維空間。

PyTorch Linear層

Linear層的內(nèi)部實現(xiàn)

我們將權重矩陣放在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()

三、線性變換的數(shù)學符號

有時我們會看到Linear層操作被稱為 y=Ax+b。在這個方程中,我們有:

線性變換公式

可調(diào)用的層和神經(jīng)網(wǎng)絡

我們之前指出過,我們把層對象實例當作一個函數(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中的call()方法

讓我們在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

FAQ

1. 問:Linear層和Dense層有什么區(qū)別?

2. 問:如何在PyTorch中創(chuàng)建Linear層?

3. 問:Linear層的權重和偏置是如何學習的?

4. 問:為什么需要在Linear層后應用激活函數(shù)?

5. 問:Linear層在神經(jīng)網(wǎng)絡中的作用是什么?

上一篇:

QA問答如何應用大模型:深入解析與實踐指南

下一篇:

QQ查詢手機號及通訊服務的深度解析
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費