99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PyTorch教程-6.1. 層和模塊

jf_pJlTbmA9 ? 來(lái)源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

當(dāng)我們第一次引入神經(jīng)網(wǎng)絡(luò)時(shí),我們專注于具有單一輸出的線性模型。在這里,整個(gè)模型只包含一個(gè)神經(jīng)元。請(qǐng)注意,單個(gè)神經(jīng)元 (i) 接受一組輸入;(ii) 生成相應(yīng)的標(biāo)量輸出;(iii) 有一組相關(guān)參數(shù),可以更新這些參數(shù)以優(yōu)化一些感興趣的目標(biāo)函數(shù)。然后,一旦我們開(kāi)始考慮具有多個(gè)輸出的網(wǎng)絡(luò),我們就利用矢量化算法來(lái)表征整個(gè)神經(jīng)元層。就像單個(gè)神經(jīng)元一樣,層 (i) 采用一組輸入,(ii) 生成相應(yīng)的輸出,并且 (iii) 由一組可調(diào)參數(shù)描述。當(dāng)我們進(jìn)行 softmax 回歸時(shí),單層本身就是模型。然而,即使我們隨后引入了 MLP,

有趣的是,對(duì)于 MLP,整個(gè)模型及其組成層都共享這種結(jié)構(gòu)。整個(gè)模型接受原始輸入(特征),生成輸出(預(yù)測(cè)),并擁有參數(shù)(來(lái)自所有構(gòu)成層的組合參數(shù))。同樣,每個(gè)單獨(dú)的層攝取輸入(由前一層提供)生成輸出(后續(xù)層的輸入),并擁有一組可調(diào)參數(shù),這些參數(shù)根據(jù)從后續(xù)層向后流動(dòng)的信號(hào)進(jìn)行更新。

雖然您可能認(rèn)為神經(jīng)元、層和模型為我們提供了足夠的抽象來(lái)開(kāi)展我們的業(yè)務(wù),但事實(shí)證明,我們經(jīng)常發(fā)現(xiàn)談?wù)摫葐蝹€(gè)層大但比整個(gè)模型小的組件很方便。例如,在計(jì)算機(jī)視覺(jué)領(lǐng)域廣受歡迎的 ResNet-152 架構(gòu)擁有數(shù)百層。這些層由層組的重復(fù)圖案組成。一次一層地實(shí)現(xiàn)這樣的網(wǎng)絡(luò)會(huì)變得乏味。這種擔(dān)憂不僅僅是假設(shè)——這樣的設(shè)計(jì)模式在實(shí)踐中很常見(jiàn)。上面提到的 ResNet 架構(gòu)贏得了 2015 年 ImageNet 和 COCO 計(jì)算機(jī)視覺(jué)識(shí)別和檢測(cè)競(jìng)賽(He et al. , 2016)并且仍然是許多視覺(jué)任務(wù)的首選架構(gòu)。層以各種重復(fù)模式排列的類似架構(gòu)現(xiàn)在在其他領(lǐng)域無(wú)處不在,包括自然語(yǔ)言處理和語(yǔ)音。

為了實(shí)現(xiàn)這些復(fù)雜的網(wǎng)絡(luò),我們引入了神經(jīng)網(wǎng)絡(luò)模塊的概念。模塊可以描述單個(gè)層、由多個(gè)層組成的組件或整個(gè)模型本身!使用模塊抽象的一個(gè)好處是它們可以組合成更大的工件,通常是遞歸的。如圖 6.1.1所示。通過(guò)定義代碼以按需生成任意復(fù)雜度的模塊,我們可以編寫(xiě)出奇緊湊的代碼并仍然實(shí)現(xiàn)復(fù)雜的神經(jīng)網(wǎng)絡(luò)。

poYBAGR9NP2AcRNaAAJd7roQfBs959.svg

圖 6.1.1多層組合成模塊,形成更大模型的重復(fù)模式。

編程的角度來(lái)看,模塊由類表示。它的任何子類都必須定義一個(gè)前向傳播方法,將其輸入轉(zhuǎn)換為輸出,并且必須存儲(chǔ)任何必要的參數(shù)。請(qǐng)注意,某些模塊根本不需要任何參數(shù)。最后,為了計(jì)算梯度,模塊必須具有反向傳播方法。幸運(yùn)的是,由于自動(dòng)微分(在2.5 節(jié)中介紹)在定義我們自己的模塊時(shí)提供了一些幕后魔法,我們只需要擔(dān)心參數(shù)和前向傳播方法。

import torch
from torch import nn
from torch.nn import functional as F

from mxnet import np, npx
from mxnet.gluon import nn

npx.set_np()

from typing import List
import jax
from flax import linen as nn
from jax import numpy as jnp
from d2l import jax as d2l

No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)

import tensorflow as tf

首先,我們重新審視用于實(shí)現(xiàn) MLP 的代碼(第 5.1 節(jié))。以下代碼生成一個(gè)網(wǎng)絡(luò),該網(wǎng)絡(luò)具有一個(gè)具有 256 個(gè)單元和 ReLU 激活的全連接隱藏層,后跟一個(gè)具有 10 個(gè)單元的全連接輸出層(無(wú)激活函數(shù))。

net = nn.Sequential(nn.LazyLinear(256), nn.ReLU(), nn.LazyLinear(10))

X = torch.rand(2, 20)
net(X).shape

torch.Size([2, 10])

在這個(gè)例子中,我們通過(guò)實(shí)例化一個(gè) 來(lái)構(gòu)造我們的模型 nn.Sequential,層按照它們應(yīng)該被執(zhí)行的順序作為參數(shù)傳遞。簡(jiǎn)而言之,nn.Sequential定義了一種特殊的Module,在 PyTorch 中呈現(xiàn)模塊的類。它維護(hù)一個(gè)有序的 constituent 列表Module。請(qǐng)注意,兩個(gè)完全連接的層中的每一個(gè)都是該類的一個(gè)實(shí)例,Linear該類本身是 的子類Module。前向傳播 ( forward) 方法也非常簡(jiǎn)單:它將列表中的每個(gè)模塊鏈接在一起,將每個(gè)模塊的輸出作為輸入傳遞給下一個(gè)模塊。請(qǐng)注意,到目前為止,我們一直在通過(guò)構(gòu)造調(diào)用我們的模型 net(X)以獲得它們的輸出。這實(shí)際上只是 net.__call__(X).

net = nn.Sequential()
net.add(nn.Dense(256, activation='relu'))
net.add(nn.Dense(10))
net.initialize()

X = np.random.uniform(size=(2, 20))
net(X).shape

(2, 10)

In this example, we constructed our model by instantiating an nn.Sequential, assigning the returned object to the net variable. Next, we repeatedly call its add method, appending layers in the order that they should be executed. In short, nn.Sequential defines a special kind of Block, the class that presents a module in Gluon. It maintains an ordered list of constituent Blocks. The add method simply facilitates the addition of each successive Block to the list. Note that each layer is an instance of the Dense class which is itself a subclass of Block. The forward propagation (forward) method is also remarkably simple: it chains each Block in the list together, passing the output of each as input to the next. Note that until now, we have been invoking our models via the construction net(X) to obtain their outputs. This is actually just shorthand for net.forward(X), a slick Python trick achieved via the Block class’s __call__ method.

net = nn.Sequential([nn.Dense(256), nn.relu, nn.Dense(10)])

# get_key is a d2l saved function returning jax.random.PRNGKey(random_seed)
X = jax.random.uniform(d2l.get_key(), (2, 20))
params = net.init(d2l.get_key(), X)
net.apply(params, X).shape

(2, 10)

net = tf.keras.models.Sequential([
  tf.keras.layers.Dense(256, activation=tf.nn.relu),
  tf.keras.layers.Dense(10),
])

X = tf.random.uniform((2, 20))
net(X).shape

TensorShape([2, 10])

In this example, we constructed our model by instantiating an keras.models.Sequential, with layers in the order that they should be executed passed as arguments. In short, Sequential defines a special kind of keras.Model, the class that presents a module in Keras. It maintains an ordered list of constituent Models. Note that each of the two fully connected layers is an instance of the Dense class which is itself a subclass of Model. The forward propagation (call) method is also remarkably simple: it chains each module in the list together, passing the output of each as input to the next. Note that until now, we have been invoking our models via the construction net(X) to obtain their outputs. This is actually just shorthand for net.call(X), a slick Python trick achieved via the module class’s __call__ method.

6.1.1. 自定義模塊

也許培養(yǎng)關(guān)于模塊如何工作的直覺(jué)的最簡(jiǎn)單方法是我們自己實(shí)現(xiàn)一個(gè)。在我們實(shí)現(xiàn)自己的自定義模塊之前,我們先簡(jiǎn)單總結(jié)一下每個(gè)模塊必須提供的基本功能:

攝取輸入數(shù)據(jù)作為其前向傳播方法的參數(shù)。

通過(guò)讓前向傳播方法返回一個(gè)值來(lái)生成輸出。請(qǐng)注意,輸出可能具有與輸入不同的形狀。例如,我們上面模型中的第一個(gè)全連接層接收任意維度的輸入,但返回 256 維度的輸出。

計(jì)算其輸出相對(duì)于其輸入的梯度,可以通過(guò)其反向傳播方法訪問(wèn)。通常這會(huì)自動(dòng)發(fā)生。

存儲(chǔ)并提供對(duì)執(zhí)行前向傳播計(jì)算所需的那些參數(shù)的訪問(wèn)。

根據(jù)需要初始化模型參數(shù)。

在下面的代碼片段中,我們從頭開(kāi)始編寫(xiě)一個(gè)模塊,對(duì)應(yīng)于一個(gè)包含 256 個(gè)隱藏單元的隱藏層和一個(gè) 10 維輸出層的 MLP。請(qǐng)注意,MLP下面的類繼承了代表模塊的類。我們將嚴(yán)重依賴父類的方法,僅提供我們自己的構(gòu)造函數(shù)(__init__ Python 中的方法)和前向傳播方法。

class MLP(nn.Module):
  def __init__(self):
    # Call the constructor of the parent class nn.Module to perform
    # the necessary initialization
    super().__init__()
    self.hidden = nn.LazyLinear(256)
    self.out = nn.LazyLinear(10)

  # Define the forward propagation of the model, that is, how to return the
  # required model output based on the input X
  def forward(self, X):
    return self.out(F.relu(self.hidden(X)))

class MLP(nn.Block):
  def __init__(self):
    # Call the constructor of the MLP parent class nn.Block to perform
    # the necessary initialization
    super().__init__()
    self.hidden = nn.Dense(256, activation='relu')
    self.out = nn.Dense(10)

  # Define the forward propagation of the model, that is, how to return the
  # required model output based on the input X
  def forward(self, X):
    return self.out(self.hidden(X))

class MLP(nn.Module):
  def setup(self):
    # Define the layers
    self.hidden = nn.Dense(256)
    self.out = nn.Dense(10)

  # Define the forward propagation of the model, that is, how to return the
  # required model output based on the input X
  def __call__(self, X):
    return self.out(nn.relu(self.hidden(X)))

class MLP(tf.keras.Model):
  def __init__(self):
    # Call the constructor of the parent class tf.keras.Model to perform
    # the necessary initialization
    super().__init__()
    self.hidden = tf.keras.layers.Dense(units=256, activation=tf.nn.relu)
    self.out = tf.keras.layers.Dense(units=10)

  # Define the forward propagation of the model, that is, how to return the
  # required model output based on the input X
  def call(self, X):
    return self.out(self.hidden((X)))

讓我們首先關(guān)注前向傳播方法。請(qǐng)注意,它以 X輸入為輸入,應(yīng)用激活函數(shù)計(jì)算隱藏表示,并輸出其對(duì)數(shù)。在這個(gè)MLP 實(shí)現(xiàn)中,兩層都是實(shí)例變量。要了解為什么這是合理的,想象一下實(shí)例化兩個(gè) MLPnet1和net2,并在不同的數(shù)據(jù)上訓(xùn)練它們。自然地,我們希望它們代表兩種不同的學(xué)習(xí)模型。

我們?cè)跇?gòu)造函數(shù)中實(shí)例化 MLP 的層,隨后在每次調(diào)用前向傳播方法時(shí)調(diào)用這些層。注意幾個(gè)關(guān)鍵細(xì)節(jié)。首先,我們的自定義方法通過(guò)讓我們免于重述適用于大多數(shù)模塊的樣板代碼的痛苦來(lái)__init__調(diào)用父類的方法。然后我們實(shí)例化我們的兩個(gè)完全連接的層,將它們分配給 和。請(qǐng)注意,除非我們實(shí)現(xiàn)一個(gè)新層,否則我們不必?fù)?dān)心反向傳播方法或參數(shù)初始化。系統(tǒng)會(huì)自動(dòng)生成這些方法。讓我們?cè)囋囘@個(gè)。__init__super().__init__()self.hiddenself.out

net = MLP()
net(X).shape

torch.Size([2, 10])

net = MLP()
net.initialize()
net(X).shape

(2, 10)

net = MLP()
params = net.init(d2l.get_key(), X)
net.apply(params, X).shape

(2, 10)

net = MLP()
net(X).shape

TensorShape([2, 10])

模塊抽象的一個(gè)關(guān)鍵優(yōu)點(diǎn)是它的多功能性。我們可以對(duì)模塊進(jìn)行子類化以創(chuàng)建層(例如全連接層類)、整個(gè)模型(例如MLP上面的類)或中等復(fù)雜度的各種組件。我們將在接下來(lái)的章節(jié)中利用這種多功能性,例如在處理卷積神經(jīng)網(wǎng)絡(luò)時(shí)。

6.1.2. 順序模塊

我們現(xiàn)在可以仔細(xì)看看這個(gè)Sequential類是如何工作的。回想一下,它Sequential的設(shè)計(jì)目的是將其他模塊菊花鏈在一起。要構(gòu)建我們自己的簡(jiǎn)化版MySequential,我們只需要定義兩個(gè)關(guān)鍵方法:

一種將模塊逐個(gè)附加到列表的方法。

一種前向傳播方法,通過(guò)模塊鏈傳遞輸入,順序與附加順序相同。

以下MySequential類提供與默認(rèn)Sequential類相同的功能。

class MySequential(nn.Module):
  def __init__(self, *args):
    super().__init__()
    for idx, module in enumerate(args):
      self.add_module(str(idx), module)

  def forward(self, X):
    for module in self.children():
      X = module(X)
    return X

在__init__方法中,我們通過(guò)調(diào)用方法來(lái)添加每個(gè)模塊 add_modules。稍后可以通過(guò)該方法訪問(wèn)這些模塊 children。這樣系統(tǒng)就知道添加的模塊,并且會(huì)正確地初始化每個(gè)模塊的參數(shù)。

class MySequential(nn.Block):
  def add(self, block):
    # Here, block is an instance of a Block subclass, and we assume that
    # it has a unique name. We save it in the member variable _children of
    # the Block class, and its type is OrderedDict. When the MySequential
    # instance calls the initialize method, the system automatically
    # initializes all members of _children
    self._children[block.name] = block

  def forward(self, X):
    # OrderedDict guarantees that members will be traversed in the order
    # they were added
    for block in self._children.values():
      X = block(X)
    return X

The add method adds a single block to the ordered dictionary _children. You might wonder why every Gluon Block possesses a _children attribute and why we used it rather than just define a Python list ourselves. In short the chief advantage of _children is that during our block’s parameter initialization, Gluon knows to look inside the _children dictionary to find sub-blocks whose parameters also need to be initialized.

class MySequential(nn.Module):
  modules: List

  def __call__(self, X):
    for module in self.modules:
      X = module(X)
    return X

class MySequential(tf.keras.Model):
  def __init__(self, *args):
    super().__init__()
    self.modules = args

  def call(self, X):
    for module in self.modules:
      X = module(X)
    return X

當(dāng)MySequential調(diào)用我們的前向傳播方法時(shí),每個(gè)添加的模塊都按照添加的順序執(zhí)行。我們現(xiàn)在可以使用我們的類重新實(shí)現(xiàn) MLP MySequential。

net = MySequential(nn.LazyLinear(256), nn.ReLU(), nn.LazyLinear(10))
net(X).shape

torch.Size([2, 10])

net = MySequential()
net.add(nn.Dense(256, activation='relu'))
net.add(nn.Dense(10))
net.initialize()
net(X).shape

(2, 10)

net = MySequential([nn.Dense(256), nn.relu, nn.Dense(10)])
params = net.init(d2l.get_key(), X)
net.apply(params, X).shape

(2, 10)

net = MySequential(
  tf.keras.layers.Dense(units=256, activation=tf.nn.relu),
  tf.keras.layers.Dense(10))
net(X).shape

TensorShape([2, 10])

請(qǐng)注意,此用法MySequential與我們之前為該類編寫(xiě)的代碼相同(如第 5.1 節(jié)Sequential所述 )。

6.1.3. 在前向傳播方法中執(zhí)行代碼

該類Sequential使模型構(gòu)建變得容易,使我們無(wú)需定義自己的類就可以組裝新的體系結(jié)構(gòu)。然而,并非所有架構(gòu)都是簡(jiǎn)單的菊花鏈。當(dāng)需要更大的靈活性時(shí),我們會(huì)想要定義我們自己的塊。例如,我們可能希望在前向傳播方法中執(zhí)行 Python 的控制流。此外,我們可能想要執(zhí)行任意數(shù)學(xué)運(yùn)算,而不是簡(jiǎn)單地依賴于預(yù)定義的神經(jīng)網(wǎng)絡(luò)層。

您可能已經(jīng)注意到,直到現(xiàn)在,我們網(wǎng)絡(luò)中的所有操作都對(duì)我們網(wǎng)絡(luò)的激活及其參數(shù)起作用。然而,有時(shí)我們可能想要合并既不是前幾層結(jié)果也不是可更新參數(shù)的術(shù)語(yǔ)。我們稱這些 為常量參數(shù)。比如說(shuō)我們想要一個(gè)計(jì)算函數(shù)的層 f(x,w)=c?w?x, 在哪里x是輸入,w是我們的參數(shù),并且c是一些指定的常量,在優(yōu)化期間不會(huì)更新。所以我們實(shí)現(xiàn)一個(gè)FixedHiddenMLP類如下。

class FixedHiddenMLP(nn.Module):
  def __init__(self):
    super().__init__()
    # Random weight parameters that will not compute gradients and
    # therefore keep constant during training
    self.rand_weight = torch.rand((20, 20))
    self.linear = nn.LazyLinear(20)

  def forward(self, X):
    X = self.linear(X)
    X = F.relu(X @ self.rand_weight + 1)
    # Reuse the fully connected layer. This is equivalent to sharing
    # parameters with two fully connected layers
    X = self.linear(X)
    # Control flow
    while X.abs().sum() > 1:
      X /= 2
    return X.sum()

class FixedHiddenMLP(nn.Block):
  def __init__(self):
    super().__init__()
    # Random weight parameters created with the get_constant method
    # are not updated during training (i.e., constant parameters)
    self.rand_weight = self.params.get_constant(
      'rand_weight', np.random.uniform(size=(20, 20)))
    self.dense = nn.Dense(20, activation='relu')

  def forward(self, X):
    X = self.dense(X)
    # Use the created constant parameters, as well as the relu and dot
    # functions
    X = npx.relu(np.dot(X, self.rand_weight.data()) + 1)
    # Reuse the fully connected layer. This is equivalent to sharing
    # parameters with two fully connected layers
    X = self.dense(X)
    # Control flow
    while np.abs(X).sum() > 1:
      X /= 2
    return X.sum()

class FixedHiddenMLP(nn.Module):
  # Random weight parameters that will not compute gradients and
  # therefore keep constant during training
  rand_weight: jnp.array = jax.random.uniform(d2l.get_key(), (20, 20))

  def setup(self):
    self.dense = nn.Dense(20)

  def __call__(self, X):
    X = self.dense(X)
    X = nn.relu(X @ self.rand_weight + 1)
    # Reuse the fully connected layer. This is equivalent to sharing
    # parameters with two fully connected layers
    X = self.dense(X)
    # Control flow
    while jnp.abs(X).sum() > 1:
      X /= 2
    return X.sum()

class FixedHiddenMLP(tf.keras.Model):
  def __init__(self):
    super().__init__()
    self.flatten = tf.keras.layers.Flatten()
    # Random weight parameters created with tf.constant are not updated
    # during training (i.e., constant parameters)
    self.rand_weight = tf.constant(tf.random.uniform((20, 20)))
    self.dense = tf.keras.layers.Dense(20, activation=tf.nn.relu)

  def call(self, inputs):
    X = self.flatten(inputs)
    # Use the created constant parameters, as well as the relu and
    # matmul functions
    X = tf.nn.relu(tf.matmul(X, self.rand_weight) + 1)
    # Reuse the fully connected layer. This is equivalent to sharing
    # parameters with two fully connected layers
    X = self.dense(X)
    # Control flow
    while tf.reduce_sum(tf.math.abs(X)) > 1:
      X /= 2
    return tf.reduce_sum(X)

在這個(gè)FixedHiddenMLP模型中,我們實(shí)現(xiàn)了一個(gè)隱藏層,其權(quán)重 ( self.rand_weight) 在實(shí)例化時(shí)隨機(jī)初始化,此后保持不變。該權(quán)重不是模型參數(shù),因此永遠(yuǎn)不會(huì)通過(guò)反向傳播更新。然后網(wǎng)絡(luò)將這個(gè)“固定”層的輸出傳遞給一個(gè)全連接層。

請(qǐng)注意,在返回輸出之前,我們的模型做了一些不尋常的事情。我們運(yùn)行了一個(gè) while 循環(huán),測(cè)試它的條件?1范數(shù)大于1,并將我們的輸出向量除以2直到滿足條件。最后,我們返回了 中條目的總和X。據(jù)我們所知,沒(méi)有標(biāo)準(zhǔn)的神經(jīng)網(wǎng)絡(luò)執(zhí)行此操作。請(qǐng)注意,此特定操作可能對(duì)任何實(shí)際任務(wù)都沒(méi)有用。我們的目的只是向您展示如何將任意代碼集成到您的神經(jīng)網(wǎng)絡(luò)計(jì)算流程中。

net = FixedHiddenMLP()
net(X)

tensor(-0.1058, grad_fn=)

net = FixedHiddenMLP()
net.initialize()
net(X)

array(0.52637565)

net = FixedHiddenMLP()
params = net.init(d2l.get_key(), X)
net.apply(params, X)

Array(-0.00932113, dtype=float32)

net = FixedHiddenMLP()
net(X)


我們可以混合搭配各種方式將模塊組裝在一起。在下面的示例中,我們以一些創(chuàng)造性的方式嵌套模塊。

class NestMLP(nn.Module):
  def __init__(self):
    super().__init__()
    self.net = nn.Sequential(nn.LazyLinear(64), nn.ReLU(),
                 nn.LazyLinear(32), nn.ReLU())
    self.linear = nn.LazyLinear(16)

  def forward(self, X):
    return self.linear(self.net(X))

chimera = nn.Sequential(NestMLP(), nn.LazyLinear(20), FixedHiddenMLP())
chimera(X)

tensor(0.0964, grad_fn=)

class NestMLP(nn.Block):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.net = nn.Sequential()
    self.net.add(nn.Dense(64, activation='relu'),
           nn.Dense(32, activation='relu'))
    self.dense = nn.Dense(16, activation='relu')

  def forward(self, X):
    return self.dense(self.net(X))

chimera = nn.Sequential()
chimera.add(NestMLP(), nn.Dense(20), FixedHiddenMLP())
chimera.initialize()
chimera(X)

array(0.9772054)

class NestMLP(nn.Module):
  def setup(self):
    self.net = nn.Sequential([nn.Dense(64), nn.relu,
                 nn.Dense(32), nn.relu])
    self.dense = nn.Dense(16)

  def __call__(self, X):
    return self.dense(self.net(X))


chimera = nn.Sequential([NestMLP(), nn.Dense(20), FixedHiddenMLP()])
params = chimera.init(d2l.get_key(), X)
chimera.apply(params, X)

Array(0.20007098, dtype=float32)

class NestMLP(tf.keras.Model):
  def __init__(self):
    super().__init__()
    self.net = tf.keras.Sequential()
    self.net.add(tf.keras.layers.Dense(64, activation=tf.nn.relu))
    self.net.add(tf.keras.layers.Dense(32, activation=tf.nn.relu))
    self.dense = tf.keras.layers.Dense(16, activation=tf.nn.relu)

  def call(self, inputs):
    return self.dense(self.net(inputs))

chimera = tf.keras.Sequential()
chimera.add(NestMLP())
chimera.add(tf.keras.layers.Dense(20))
chimera.add(FixedHiddenMLP())
chimera(X)


6.1.4. 概括

層是模塊。許多層可以組成一個(gè)模塊。許多模塊可以組成一個(gè)模塊。

模塊可以包含代碼。模塊負(fù)責(zé)很多內(nèi)部事務(wù),包括參數(shù)初始化和反向傳播。層和模塊的順序連接由模塊處理Sequential 。

6.1.5. 練習(xí)

如果改用MySequentialPython列表存儲(chǔ)模塊會(huì)出現(xiàn)什么樣的問(wèn)題?

實(shí)現(xiàn)一個(gè)將兩個(gè)模塊作為參數(shù)的模塊,比如 net1和net2并在前向傳播中返回兩個(gè)網(wǎng)絡(luò)的串聯(lián)輸出。這也稱為并行模塊。

假設(shè)您想要連接同一網(wǎng)絡(luò)的多個(gè)實(shí)例。實(shí)現(xiàn)一個(gè)工廠函數(shù),生成同一模塊的多個(gè)實(shí)例,并從中構(gòu)建一個(gè)更大的網(wǎng)絡(luò)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    809

    瀏覽量

    13962
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    PyTorch如何入門

    PyTorch 入門實(shí)戰(zhàn)(一)——Tensor
    發(fā)表于 06-01 09:58

    Pytorch AI語(yǔ)音助手

    想做一個(gè)Pytorch AI語(yǔ)音助手,有沒(méi)有好的思路呀?
    發(fā)表于 03-06 13:00

    如何安裝TensorFlow2 Pytorch

    如何安裝TensorFlow2 Pytorch?
    發(fā)表于 03-07 07:32

    怎樣使用PyTorch Hub去加載YOLOv5模型

    在Python>=3.7.0環(huán)境中安裝requirements.txt,包括PyTorch>=1.7。模型和數(shù)據(jù)集從最新的 YOLOv5版本自動(dòng)下載。簡(jiǎn)單示例此示例從
    發(fā)表于 07-22 16:02

    SRWF-1(V6.1)無(wú)線模塊使用說(shuō)明書(shū)

    SRWF-1(V6.1)無(wú)線模塊,很好的無(wú)線模塊資料,快來(lái)下載學(xué)習(xí)吧
    發(fā)表于 03-29 10:58 ?0次下載

    Caffe2 和 PyTorch 代碼合并旨為提高開(kāi)發(fā)效率

    按照賈揚(yáng)清的說(shuō)法,F(xiàn)acebook 去年啟動(dòng) ONNX 項(xiàng)目并組建團(tuán)隊(duì)時(shí),就已經(jīng)開(kāi)始推動(dòng) Caffe2 和 PyTorch 在代碼的合并。
    的頭像 發(fā)表于 04-30 09:16 ?3665次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之PyTorch簡(jiǎn)單知識(shí)

    本文參考PyTorch官網(wǎng)的教程,分為五個(gè)基本模塊來(lái)介紹PyTorch。為了避免文章過(guò)長(zhǎng),這五個(gè)模塊分別在五篇博文中介紹。 Part1:PyTorc
    的頭像 發(fā)表于 02-16 15:20 ?2507次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之PyTorch的自動(dòng)梯度計(jì)算

    本文參考PyTorch官網(wǎng)的教程,分為五個(gè)基本模塊來(lái)介紹PyTorch。為了避免文章過(guò)長(zhǎng),這五個(gè)模塊分別在五篇博文中介紹。 Part1:PyTorc
    的頭像 發(fā)表于 02-16 15:26 ?2281次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之使用PyTorch構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò)

    ? ? ? ? 前言 本文參考PyTorch官網(wǎng)的教程,分為五個(gè)基本模塊來(lái)介紹PyTorch。為了避免文章過(guò)長(zhǎng),這五個(gè)模塊分別在五篇博文中介紹。 Part1:
    的頭像 發(fā)表于 02-15 09:40 ?2330次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之PyTorch重點(diǎn)綜合實(shí)踐

    實(shí)例。該網(wǎng)絡(luò)有一個(gè)隱含,使用梯度下降來(lái)訓(xùn)練,目標(biāo)是最小化網(wǎng)絡(luò)輸出和真實(shí)輸出之間的歐氏距離。 目錄 Tensors(張量) Warm-up:numpy PyTorch:Tensors Autograd
    的頭像 發(fā)表于 02-15 10:01 ?2124次閱讀

    PyTorch中使用ReLU激活函數(shù)的例子

    PyTorch已為我們實(shí)現(xiàn)了大多數(shù)常用的非線性激活函數(shù),我們可以像使用任何其他的那樣使用它們。讓我們快速看一個(gè)在PyTorch中使用ReLU激活函數(shù)的例子:
    的頭像 發(fā)表于 07-06 15:27 ?2797次閱讀

    PyTorch教程6.1模塊

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程6.1模塊.pdf》資料免費(fèi)下載
    發(fā)表于 06-05 15:23 ?0次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>6.1</b>之<b class='flag-5'>層</b>和<b class='flag-5'>模塊</b>

    PyTorch教程7.1之從全連接到卷積

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程7.1之從全連接到卷積.pdf》資料免費(fèi)下載
    發(fā)表于 06-05 11:50 ?0次下載
    <b class='flag-5'>PyTorch</b>教程7.1之從全連接<b class='flag-5'>層</b>到卷積

    PyTorch神經(jīng)網(wǎng)絡(luò)模型構(gòu)建過(guò)程

    PyTorch,作為一個(gè)廣泛使用的開(kāi)源深度學(xué)習(xí)庫(kù),提供了豐富的工具和模塊,幫助開(kāi)發(fā)者構(gòu)建、訓(xùn)練和部署神經(jīng)網(wǎng)絡(luò)模型。在神經(jīng)網(wǎng)絡(luò)模型中,輸出是尤為關(guān)鍵的部分,它負(fù)責(zé)將模型的預(yù)測(cè)結(jié)果以合適的形式輸出。以下將詳細(xì)解析
    的頭像 發(fā)表于 07-10 14:57 ?923次閱讀

    PyTorch 數(shù)據(jù)加載與處理方法

    ,數(shù)據(jù)加載主要依賴于 torch.utils.data 模塊,該模塊提供了 Dataset 和 DataLoader 兩個(gè)核心類。 1.1 Dataset 類 Dataset 類是 PyTorch 中所
    的頭像 發(fā)表于 11-05 17:37 ?933次閱讀