RM新时代网站-首页

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

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

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

PyTorch教程-5.2. 多層感知器的實(shí)現(xiàn)

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:43 ? 次閱讀

多層感知器 (MLP) 的實(shí)現(xiàn)并不比簡單的線性模型復(fù)雜多少。關(guān)鍵的概念差異是我們現(xiàn)在連接多個(gè)層。

import torch
from torch import nn
from d2l import torch as d2l

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

npx.set_np()

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
from d2l import tensorflow as d2l

5.2.1. 從零開始實(shí)施

讓我們從頭開始實(shí)現(xiàn)這樣一個(gè)網(wǎng)絡(luò)

5.2.1.1. 初始化模型參數(shù)

回想一下,F(xiàn)ashion-MNIST 包含 10 個(gè)類,并且每個(gè)圖像由一個(gè)28×28=784灰度像素值網(wǎng)格。和以前一樣,我們暫時(shí)忽略像素之間的空間結(jié)構(gòu),因此我們可以將其視為具有 784 個(gè)輸入特征和 10 個(gè)類別的分類數(shù)據(jù)集。首先,我們將實(shí)現(xiàn)一個(gè)具有一個(gè)隱藏層和 256 個(gè)隱藏單元的 MLP。層數(shù)和寬度都是可調(diào)的(它們被認(rèn)為是超參數(shù))。通常,我們選擇層寬度可以被 2 的較大次冪整除。由于內(nèi)存在硬件中分配和尋址的方式,這在計(jì)算上是高效的。

同樣,我們將用幾個(gè)張量表示我們的參數(shù)。請(qǐng)注意, 對(duì)于每一層,我們必須跟蹤一個(gè)權(quán)重矩陣和一個(gè)偏置向量。與往常一樣,我們?yōu)檫@些參數(shù)的損失梯度分配內(nèi)存。

在下面的代碼中,我們使用 `nn.Parameter< https://pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html >`__ 自動(dòng)將類屬性注冊(cè)為要跟蹤的參數(shù)autograd(第 2.5 節(jié)) .

class MLPScratch(d2l.Classifier):
  def __init__(self, num_inputs, num_outputs, num_hiddens, lr, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens) * sigma)
    self.b1 = nn.Parameter(torch.zeros(num_hiddens))
    self.W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs) * sigma)
    self.b2 = nn.Parameter(torch.zeros(num_outputs))

In the code below, we first define and initialize the parameters and then enable gradient tracking.

class MLPScratch(d2l.Classifier):
  def __init__(self, num_inputs, num_outputs, num_hiddens, lr, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.W1 = np.random.randn(num_inputs, num_hiddens) * sigma
    self.b1 = np.zeros(num_hiddens)
    self.W2 = np.random.randn(num_hiddens, num_outputs) * sigma
    self.b2 = np.zeros(num_outputs)
    for param in self.get_scratch_params():
      param.attach_grad()

In the code below we use `flax.linen.Module.param `__ to define the model parameter.

class MLPScratch(d2l.Classifier):
  num_inputs: int
  num_outputs: int
  num_hiddens: int
  lr: float
  sigma: float = 0.01

  def setup(self):
    self.W1 = self.param('W1', nn.initializers.normal(self.sigma),
               (self.num_inputs, self.num_hiddens))
    self.b1 = self.param('b1', nn.initializers.zeros, self.num_hiddens)
    self.W2 = self.param('W2', nn.initializers.normal(self.sigma),
               (self.num_hiddens, self.num_outputs))
    self.b2 = self.param('b2', nn.initializers.zeros, self.num_outputs)

In the code below we use `tf.Variable `__ to define the model parameter.

class MLPScratch(d2l.Classifier):
  def __init__(self, num_inputs, num_outputs, num_hiddens, lr, sigma=0.01):
    super().__init__()
    self.save_hyperparameters()
    self.W1 = tf.Variable(
      tf.random.normal((num_inputs, num_hiddens)) * sigma)
    self.b1 = tf.Variable(tf.zeros(num_hiddens))
    self.W2 = tf.Variable(
      tf.random.normal((num_hiddens, num_outputs)) * sigma)
    self.b2 = tf.Variable(tf.zeros(num_outputs))

5.2.1.2. 模型

為了確保我們知道一切是如何工作的,我們將自己實(shí)現(xiàn) ReLU 激活,而不是直接調(diào)用內(nèi)置relu函數(shù)。

def relu(X):
  a = torch.zeros_like(X)
  return torch.max(X, a)

def relu(X):
  return np.maximum(X, 0)

def relu(X):
  return jnp.maximum(X, 0)

def relu(X):
  return tf.math.maximum(X, 0)

由于我們忽略了空間結(jié)構(gòu),我們將reshape每個(gè)二維圖像轉(zhuǎn)換為長度為 的平面向量num_inputs。最后,我們只用幾行代碼就實(shí)現(xiàn)了我們的模型。由于我們使用框架內(nèi)置的 autograd,這就是它所需要的全部。

@d2l.add_to_class(MLPScratch)
def forward(self, X):
  X = X.reshape((-1, self.num_inputs))
  H = relu(torch.matmul(X, self.W1) + self.b1)
  return torch.matmul(H, self.W2) + self.b2

@d2l.add_to_class(MLPScratch)
def forward(self, X):
  X = X.reshape((-1, self.num_inputs))
  H = relu(np.dot(X, self.W1) + self.b1)
  return np.dot(H, self.W2) + self.b2

@d2l.add_to_class(MLPScratch)
def forward(self, X):
  X = X.reshape((-1, self.num_inputs))
  H = relu(jnp.matmul(X, self.W1) + self.b1)
  return jnp.matmul(H, self.W2) + self.b2

@d2l.add_to_class(MLPScratch)
def forward(self, X):
  X = tf.reshape(X, (-1, self.num_inputs))
  H = relu(tf.matmul(X, self.W1) + self.b1)
  return tf.matmul(H, self.W2) + self.b2

5.2.1.3. 訓(xùn)練

幸運(yùn)的是,MLP 的訓(xùn)練循環(huán)與 softmax 回歸完全相同。我們定義模型、數(shù)據(jù)、訓(xùn)練器,最后fit在模型和數(shù)據(jù)上調(diào)用方法。

model = MLPScratch(num_inputs=784, num_outputs=10, num_hiddens=256, lr=0.1)
data = d2l.FashionMNIST(batch_size=256)
trainer = d2l.Trainer(max_epochs=10)
trainer.fit(model, data)

poYBAGR9NJeAcxmqAAGBExPEUqc353.svg

model = MLPScratch(num_inputs=784, num_outputs=10, num_hiddens=256, lr=0.1)
data = d2l.FashionMNIST(batch_size=256)
trainer = d2l.Trainer(max_epochs=10)
trainer.fit(model, data)

poYBAGR9NJmAGTC8AAGCCLiJXcw943.svg

model = MLPScratch(num_inputs=784, num_outputs=10, num_hiddens=256, lr=0.1)
data = d2l.FashionMNIST(batch_size=256)
trainer = d2l.Trainer(max_epochs=10)
trainer.fit(model, data)

pYYBAGR9NJyAM_ysAAGCybKjia0271.svg

model = MLPScratch(num_inputs=784, num_outputs=10, num_hiddens=256, lr=0.1)
data = d2l.FashionMNIST(batch_size=256)
trainer = d2l.Trainer(max_epochs=10)
trainer.fit(model, data)

pYYBAGR9NJ6AeFYhAAGBuQZFjtY204.svg

5.2.2. 簡潔的實(shí)現(xiàn)

正如您所料,通過依賴高級(jí) API,我們可以更簡潔地實(shí)現(xiàn) MLP。

5.2.2.1. 模型

與我們對(duì) softmax 回歸實(shí)現(xiàn)的簡潔實(shí)現(xiàn)(第 4.5 節(jié))相比,唯一的區(qū)別是我們添加了兩個(gè)完全連接的層,而我們之前只添加了 一個(gè)。第一個(gè)是隱藏層,第二個(gè)是輸出層。

class MLP(d2l.Classifier):
  def __init__(self, num_outputs, num_hiddens, lr):
    super().__init__()
    self.save_hyperparameters()
    self.net = nn.Sequential(nn.Flatten(), nn.LazyLinear(num_hiddens),
                 nn.ReLU(), nn.LazyLinear(num_outputs))

class MLP(d2l.Classifier):
  def __init__(self, num_outputs, num_hiddens, lr):
    super().__init__()
    self.save_hyperparameters()
    self.net = nn.Sequential()
    self.net.add(nn.Dense(num_hiddens, activation='relu'),
           nn.Dense(num_outputs))
    self.net.initialize()

class MLP(d2l.Classifier):
  num_outputs: int
  num_hiddens: int
  lr: float

  @nn.compact
  def __call__(self, X):
    X = X.reshape((X.shape[0], -1)) # Flatten
    X = nn.Dense(self.num_hiddens)(X)
    X = nn.relu(X)
    X = nn.Dense(self.num_outputs)(X)
    return X

class MLP(d2l.Classifier):
  def __init__(self, num_outputs, num_hiddens, lr):
    super().__init__()
    self.save_hyperparameters()
    self.net = tf.keras.models.Sequential([
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(num_hiddens, activation='relu'),
      tf.keras.layers.Dense(num_outputs)])

以前,我們forward為模型定義了使用模型參數(shù)轉(zhuǎn)換輸入的方法。這些操作本質(zhì)上是一個(gè)管道:您獲取一個(gè)輸入并應(yīng)用一個(gè)轉(zhuǎn)換(例如,矩陣與權(quán)重相乘,然后是偏差加法),然后重復(fù)使用當(dāng)前轉(zhuǎn)換的輸出作為下一個(gè)轉(zhuǎn)換的輸入。但是,您可能已經(jīng)注意到 forward這里沒有定義任何方法。實(shí)際上,從類(第 3.2.2 節(jié)MLP)繼承 方法以簡單地調(diào)用 (是輸入),現(xiàn)在定義為通過類進(jìn)行的一系列轉(zhuǎn)換。該類抽象了前向過程,使我們能夠?qū)W⒂谵D(zhuǎn)換。我們將進(jìn)一步討論如何forwardModuleself.net(X)XSequentialSequentialSequential類在第 6.1.2 節(jié)中起作用 。

5.2.2.2. 訓(xùn)練

訓(xùn)練循環(huán)與我們實(shí)現(xiàn) softmax 回歸時(shí)完全相同。這種模塊化使我們能夠?qū)⒂嘘P(guān)模型架構(gòu)的問題與正交考慮分開。

model = MLP(num_outputs=10, num_hiddens=256, lr=0.1)
trainer.fit(model, data)

poYBAGR9NKGAMJGUAAF5pOY74F4213.svg

model = MLP(num_outputs=10, num_hiddens=256, lr=0.1)
trainer.fit(model, data)

pYYBAGR9NKSANquDAAF72nzDx0M343.svg

model = MLP(num_outputs=10, num_hiddens=256, lr=0.1)
trainer.fit(model, data)

pYYBAGR9NKeAEH6HAAF08_rOZ80451.svg

model = MLP(num_outputs=10, num_hiddens=256, lr=0.1)
trainer.fit(model, data)

poYBAGR9NKmAX8IxAAGKzgziMks047.svg

5.2.3. 概括

現(xiàn)在我們?cè)谠O(shè)計(jì)深度網(wǎng)絡(luò)方面有了更多的實(shí)踐,從單層到多層深度網(wǎng)絡(luò)的步驟不再構(gòu)成如此重大的挑戰(zhàn)。特別是,我們可以重用訓(xùn)練算法和數(shù)據(jù)加載器。但請(qǐng)注意,從頭開始實(shí)施 MLP 仍然很麻煩:命名和跟蹤模型參數(shù)使得擴(kuò)展模型變得困難。例如,假設(shè)想要在第 42 層和第 43 層之間插入另一層。這可能是第 42b 層,除非我們?cè)敢鈭?zhí)行順序重命名。此外,如果我們從頭開始實(shí)施網(wǎng)絡(luò),框架就很難執(zhí)行有意義的性能優(yōu)化。

盡管如此,您現(xiàn)在已經(jīng)達(dá)到了 1980 年代后期的最先進(jìn)水平,當(dāng)時(shí)完全連接的深度網(wǎng)絡(luò)是神經(jīng)網(wǎng)絡(luò)建模的首選方法。我們的下一個(gè)概念性步驟將是考慮圖像。在我們這樣做之前,我們需要回顧一些關(guān)于如何有效計(jì)算模型的統(tǒng)計(jì)基礎(chǔ)知識(shí)和細(xì)節(jié)。

5.2.4. 練習(xí)

更改隱藏單元的數(shù)量num_hiddens并繪制其數(shù)量如何影響模型的準(zhǔn)確性。這個(gè)超參數(shù)的最佳值是多少?

嘗試添加隱藏層以查看它如何影響結(jié)果。

為什么用單個(gè)神經(jīng)元插入隱藏層是個(gè)壞主意?會(huì)出什么問題?

改變學(xué)習(xí)率如何改變你的結(jié)果?在所有其他參數(shù)固定的情況下,哪個(gè)學(xué)習(xí)率能給你最好的結(jié)果?這與紀(jì)元數(shù)有何關(guān)系?

讓我們聯(lián)合優(yōu)化所有超參數(shù),即學(xué)習(xí)率、時(shí)期數(shù)、隱藏層數(shù)和每層隱藏單元數(shù)。

通過對(duì)所有這些進(jìn)行優(yōu)化可以獲得的最佳結(jié)果是什么?

為什么處理多個(gè)超參數(shù)更具挑戰(zhàn)性?

描述聯(lián)合優(yōu)化多個(gè)參數(shù)的有效策略。

比較框架的速度和從頭開始實(shí)施一個(gè)具有挑戰(zhàn)性的問題。它如何隨著網(wǎng)絡(luò)的復(fù)雜性而變化?

測(cè)量對(duì)齊良好和未對(duì)齊矩陣的張量矩陣乘法的速度。例如,測(cè)試維度為 1024、1025、1026、1028 和 1032 的矩陣。

這在 GPU 和 CPU 之間有何變化?

確定 CPU 和 GPU 的內(nèi)存總線寬度。

嘗試不同的激活函數(shù)。哪一個(gè)效果最好?

網(wǎng)絡(luò)的權(quán)重初始化之間是否存在差異?有關(guān)系嗎?

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

    關(guān)注

    0

    文章

    34

    瀏覽量

    11841
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    807

    瀏覽量

    13199
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    DL:DL單層感知器Perceptron的原理及Perceptron Can not solve XOR problem

    DL:DL單層感知器Perceptron的原理及PerceptronCan not solveXOR problem
    發(fā)表于 12-21 10:35

    上海邏迅門磁感知器系統(tǒng)方案

    `上海邏迅門磁感知器方案`
    發(fā)表于 02-18 13:33

    如何使用Keras框架搭建一個(gè)小型的神經(jīng)網(wǎng)絡(luò)多層感知器

    本文介紹了如何使用Keras框架,搭建一個(gè)小型的神經(jīng)網(wǎng)絡(luò)-多層感知器,并通過給定數(shù)據(jù)進(jìn)行計(jì)算訓(xùn)練,最好將訓(xùn)練得到的模型提取出參數(shù),放在51單片機(jī)上進(jìn)行運(yùn)行。
    發(fā)表于 11-22 07:00

    多層感知器在提高軟件可維護(hù)性上的應(yīng)用

    預(yù)測(cè)分析軟件質(zhì)量可看作是一個(gè)以源代碼度量作為屬性標(biāo)簽、模塊性能作為類標(biāo)簽的分類問題。首次提出將多層感知器應(yīng)用于軟件質(zhì)量預(yù)測(cè),并使用對(duì)稱不定性分析來提高其分類性能。
    發(fā)表于 04-06 00:01 ?20次下載

    對(duì)多層感知器和反向傳播進(jìn)行入門級(jí)的介紹

    本文對(duì)多層感知器和反向傳播進(jìn)行入門級(jí)的介紹。人工神經(jīng)網(wǎng)絡(luò)是一種計(jì)算模型,啟發(fā)自人類大腦處理信息的生物神經(jīng)網(wǎng)絡(luò)。 人工神經(jīng)網(wǎng)絡(luò)是一種計(jì)算模型,啟發(fā)自人類大腦處理信息的生物神經(jīng)網(wǎng)絡(luò)。人工神經(jīng)網(wǎng)絡(luò)在語音識(shí)別、計(jì)算機(jī)視覺和文本處理領(lǐng)域取得了一系列突破,讓機(jī)器學(xué)習(xí)研究和產(chǎn)業(yè)感到了興
    發(fā)表于 11-15 15:26 ?4583次閱讀

    人工智能–多層感知器基礎(chǔ)知識(shí)解讀

    感知器(Perceptron)是ANN人工神經(jīng)網(wǎng)絡(luò)的一個(gè)概念,由Frank Rosenblatt于1950s第一次引入。 MLP多層感知器是一種前向結(jié)構(gòu)的ANN人工神經(jīng)網(wǎng)絡(luò), 多層
    發(fā)表于 07-05 14:45 ?6124次閱讀

    利用人工神經(jīng)網(wǎng)絡(luò)感知器實(shí)現(xiàn)雙足行走機(jī)器人的穩(wěn)定性控制

    本文采用的神經(jīng)網(wǎng)絡(luò)感知器(Perception)是最簡單的人工神經(jīng)網(wǎng)絡(luò),它是FRosenblatt于1958年提出的具有自學(xué)習(xí)能力的感知器。在這種人工神經(jīng)網(wǎng)絡(luò)中,記憶的信息存儲(chǔ)在連接權(quán)上,外部刺激
    的頭像 發(fā)表于 09-20 07:55 ?2032次閱讀
    利用人工神經(jīng)網(wǎng)絡(luò)<b class='flag-5'>感知器</b><b class='flag-5'>實(shí)現(xiàn)</b>雙足行走機(jī)器人的穩(wěn)定性控制

    使用MATLAB編寫單層感知器的函數(shù)免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用MATLAB編寫單層感知器的函數(shù)免費(fèi)下載。
    發(fā)表于 08-13 16:55 ?4次下載

    上海邏迅官網(wǎng)資訊:門磁感知器SG6AD系統(tǒng)架構(gòu)方案有哪些?

    上海邏迅官網(wǎng)資訊:門磁感知器SG6AD系統(tǒng)架構(gòu)方案有哪些? 門磁感知器SG6AD是邏迅公司研發(fā)生產(chǎn)的一種應(yīng)用于物聯(lián)網(wǎng)智能監(jiān)測(cè)感知器。通過磁性感應(yīng)、位移等多種傳感結(jié)合,實(shí)時(shí)監(jiān)測(cè)門的開關(guān)
    發(fā)表于 04-24 10:09 ?890次閱讀

    關(guān)于無線水壓傳感(感知器)SG9A01的屬性介紹

    現(xiàn)今世界是科技突飛猛進(jìn)的時(shí)代,我們不僅僅能夠探索大自然,更能通過大自然的力量改善我們的生活,無線壓力傳感(感知器)就是其中之一,而無線水壓傳感(感知器)更是與我們的生活息息相關(guān)。
    發(fā)表于 10-23 15:25 ?972次閱讀

    無線水壓感知器(傳感)SG9A01的參數(shù)是怎樣的

    現(xiàn)今世界是科技突飛猛進(jìn)的時(shí)代,我們不僅僅能夠探索大自然,更能通過大自然的力量改善我們的生活,無線壓力傳感(感知器)就是其中之一,而無線水壓傳感(感知器)更是與我們的生活息息相關(guān)。
    發(fā)表于 10-23 15:27 ?1175次閱讀

    PyTorch教程5.2多層感知器實(shí)現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程5.2多層感知器實(shí)現(xiàn).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 15:32 ?0次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>5.2</b>之<b class='flag-5'>多層</b><b class='flag-5'>感知器</b>的<b class='flag-5'>實(shí)現(xiàn)</b>

    使用多層感知器進(jìn)行機(jī)器學(xué)習(xí)

    我們將使用一個(gè)極其復(fù)雜的微處理實(shí)現(xiàn)一個(gè)神經(jīng)網(wǎng)絡(luò),該神經(jīng)網(wǎng)絡(luò)可以完成與由少數(shù)晶體管組成的電路相同的事情,這個(gè)想法有些幽默。但與此同時(shí),以這種方式思考這個(gè)問題強(qiáng)調(diào)了單層感知器作為一般分類和函數(shù)逼近工具的不足——如果我們的
    的頭像 發(fā)表于 06-24 11:17 ?554次閱讀
    使用<b class='flag-5'>多層</b><b class='flag-5'>感知器</b>進(jìn)行機(jī)器學(xué)習(xí)

    多層感知器、全連接網(wǎng)絡(luò)和深度神經(jīng)網(wǎng)絡(luò)介紹

    多層感知器(MLP)、全連接網(wǎng)絡(luò)(FCN)和深度神經(jīng)網(wǎng)絡(luò)(DNN)在神經(jīng)網(wǎng)絡(luò)領(lǐng)域中扮演著重要角色,它們之間既存在緊密聯(lián)系,又各具特色。以下將從定義、結(jié)構(gòu)、功能及應(yīng)用等方面詳細(xì)闡述這三者之間的關(guān)系。
    的頭像 發(fā)表于 07-11 17:25 ?4372次閱讀

    多層感知器的基本原理

    多層感知器(MLP, Multi-Layer Perceptron)是一種前饋神經(jīng)網(wǎng)絡(luò),它通過引入一個(gè)或多個(gè)隱藏層來擴(kuò)展單層感知器的功能,從而能夠解決復(fù)雜的非線性問題。BP網(wǎng)絡(luò),即基于反向傳播算法
    的頭像 發(fā)表于 07-19 17:20 ?796次閱讀
    RM新时代网站-首页