欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytorch: 自定義網(wǎng)絡(luò)層實(shí)例

 更新時(shí)間:2020年01月07日 13:36:13   作者:xholes  
今天小編就為大家分享一篇Pytorch: 自定義網(wǎng)絡(luò)層實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

自定義Autograd函數(shù)

對(duì)于淺層的網(wǎng)絡(luò),我們可以手動(dòng)的書寫前向傳播和反向傳播過(guò)程。但是當(dāng)網(wǎng)絡(luò)變得很大時(shí),特別是在做深度學(xué)習(xí)時(shí),網(wǎng)絡(luò)結(jié)構(gòu)變得復(fù)雜。前向傳播和反向傳播也隨之變得復(fù)雜,手動(dòng)書寫這兩個(gè)過(guò)程就會(huì)存在很大的困難。幸運(yùn)地是在pytorch中存在了自動(dòng)微分的包,可以用來(lái)解決該問(wèn)題。在使用自動(dòng)求導(dǎo)的時(shí)候,網(wǎng)絡(luò)的前向傳播會(huì)定義一個(gè)計(jì)算圖(computational graph),圖中的節(jié)點(diǎn)是張量(tensor),兩個(gè)節(jié)點(diǎn)之間的邊對(duì)應(yīng)了兩個(gè)張量之間變換關(guān)系的函數(shù)。有了計(jì)算圖的存在,張量的梯度計(jì)算也變得容易了些。例如, x是一個(gè)張量,其屬性 x.requires_grad = True,那么 x.grad就是一個(gè)保存這個(gè)張量x的梯度的一些標(biāo)量值。

最基礎(chǔ)的自動(dòng)求導(dǎo)操作在底層就是作用在兩個(gè)張量上。前向傳播函數(shù)是從輸入張量到輸出張量的計(jì)算過(guò)程;反向傳播是輸入輸出張量的梯度(一些標(biāo)量)并輸出輸入張量的梯度(一些標(biāo)量)。在pytorch中我們可以很容易地定義自己的自動(dòng)求導(dǎo)操作,通過(guò)繼承torch.autograd.Function并定義forward和backward函數(shù)。

forward(): 前向傳播操作??梢暂斎肴我舛嗟膮?shù),任意的python對(duì)象都可以。

backward():反向傳播(梯度公式)。輸出的梯度個(gè)數(shù)需要與所使用的張量個(gè)數(shù)保持一致,且返回的順序也要對(duì)應(yīng)起來(lái)。

# Inherit from Function
class LinearFunction(Function):

  # Note that both forward and backward are @staticmethods
  @staticmethod
  # bias is an optional argument
  def forward(ctx, input, weight, bias=None):
    # ctx在這里類似self,ctx的屬性可以在backward中調(diào)用
    ctx.save_for_backward(input, weight, bias)
    output = input.mm(weight.t())
    if bias is not None:
      output += bias.unsqueeze(0).expand_as(output)
    return output

  # This function has only a single output, so it gets only one gradient
  @staticmethod
  def backward(ctx, grad_output):
    # This is a pattern that is very convenient - at the top of backward
    # unpack saved_tensors and initialize all gradients w.r.t. inputs to
    # None. Thanks to the fact that additional trailing Nones are
    # ignored, the return statement is simple even when the function has
    # optional inputs.
    input, weight, bias = ctx.saved_tensors
    grad_input = grad_weight = grad_bias = None

    # These needs_input_grad checks are optional and there only to
    # improve efficiency. If you want to make your code simpler, you can
    # skip them. Returning gradients for inputs that don't require it is
    # not an error.
    if ctx.needs_input_grad[0]:
      grad_input = grad_output.mm(weight)
    if ctx.needs_input_grad[1]:
      grad_weight = grad_output.t().mm(input)
    if bias is not None and ctx.needs_input_grad[2]:
      grad_bias = grad_output.sum(0).squeeze(0)

    return grad_input, grad_weight, grad_bias

#調(diào)用自定義的自動(dòng)求導(dǎo)函數(shù)
linear = LinearFunction.apply(*args) #前向傳播
linear.backward()#反向傳播
linear.grad_fn.apply(*args)#反向傳播

對(duì)于非參數(shù)化的張量(權(quán)重是常量,不需要更新),此時(shí)可以定義為:

class MulConstant(Function):
  @staticmethod
  def forward(ctx, tensor, constant):
    # ctx is a context object that can be used to stash information
    # for backward computation
    ctx.constant = constant
    return tensor * constant

  @staticmethod
  def backward(ctx, grad_output):
    # We return as many input gradients as there were arguments.
    # Gradients of non-Tensor arguments to forward must be None.
    return grad_output * ctx.constant, None

高階導(dǎo)數(shù)

grad_x =t.autograd.grad(y, x, create_graph=True)

grad_grad_x = t.autograd.grad(grad_x[0],x)

自定義Module

計(jì)算圖和自動(dòng)求導(dǎo)在定義復(fù)雜網(wǎng)絡(luò)和求梯度的時(shí)候非常好用,但對(duì)于大型的網(wǎng)絡(luò),這個(gè)還是有點(diǎn)偏底層。在我們構(gòu)建網(wǎng)絡(luò)的時(shí)候,經(jīng)常希望將計(jì)算限制在每個(gè)層之內(nèi)(參數(shù)更新分層更新)。而且在TensorFlow等其他深度學(xué)習(xí)框架中都提供了高級(jí)抽象結(jié)構(gòu)。因此,在pytorch中也提供了類似的包nn,它定義了一組等價(jià)于層(layer)的模塊(Modules)。一個(gè)Module接受輸入張量并得到輸出張量,同時(shí)也會(huì)包含可學(xué)習(xí)的參數(shù)。

有時(shí)候,我們希望運(yùn)用一些新的且nn包中不存在的Module。此時(shí)就需要定義自己的Module了。自定義的Module需要繼承nn.Module且自定義forward函數(shù)。其中forward函數(shù)可以接受輸入張量并利用其它模型或者其他自動(dòng)求導(dǎo)操作來(lái)產(chǎn)生輸出張量。但并不需要重寫backward函數(shù),因此nn使用了autograd。這也就意味著,需要自定義Module, 都必須有對(duì)應(yīng)的autograd函數(shù)以調(diào)用其中的backward。

class Linear(nn.Module):
  def __init__(self, input_features, output_features, bias=True):
    super(Linear, self).__init__()
    self.input_features = input_features
    self.output_features = output_features

    # nn.Parameter is a special kind of Tensor, that will get
    # automatically registered as Module's parameter once it's assigned
    # as an attribute. Parameters and buffers need to be registered, or
    # they won't appear in .parameters() (doesn't apply to buffers), and
    # won't be converted when e.g. .cuda() is called. You can use
    # .register_buffer() to register buffers.
    # (很重要?。。?shù)一定需要梯度!)nn.Parameters require gradients by default.
    self.weight = nn.Parameter(torch.Tensor(output_features, input_features))
    if bias:
      self.bias = nn.Parameter(torch.Tensor(output_features))
    else:
      # You should always register all possible parameters, but the
      # optional ones can be None if you want.
      self.register_parameter('bias', None)

    # Not a very smart way to initialize weights
    self.weight.data.uniform_(-0.1, 0.1)
    if bias is not None:
      self.bias.data.uniform_(-0.1, 0.1)

  def forward(self, input):
    # See the autograd section for explanation of what happens here.
    return LinearFunction.apply(input, self.weight, self.bias)

  def extra_repr(self):
    # (Optional)Set the extra information about this module. You can test
    # it by printing an object of this class.
    return 'in_features={}, out_features={}, bias={}'.format(
      self.in_features, self.out_features, self.bias is not None

Function與Module的異同

Function與Module都可以對(duì)pytorch進(jìn)行自定義拓展,使其滿足網(wǎng)絡(luò)的需求,但這兩者還是有十分重要的不同:

Function一般只定義一個(gè)操作,因?yàn)槠錈o(wú)法保存參數(shù),因此適用于激活函數(shù)、pooling等操作;Module是保存了參數(shù),因此適合于定義一層,如線性層,卷積層,也適用于定義一個(gè)網(wǎng)絡(luò)

Function需要定義三個(gè)方法:init, forward, backward(需要自己寫求導(dǎo)公式);Module:只需定義init和forward,而backward的計(jì)算由自動(dòng)求導(dǎo)機(jī)制構(gòu)成

可以不嚴(yán)謹(jǐn)?shù)恼J(rèn)為,Module是由一系列Function組成,因此其在forward的過(guò)程中,F(xiàn)unction和Variable組成了計(jì)算圖,在backward時(shí),只需調(diào)用Function的backward就得到結(jié)果,因此Module不需要再定義backward。

Module不僅包括了Function,還包括了對(duì)應(yīng)的參數(shù),以及其他函數(shù)與變量,這是Function所不具備的。

module 是 pytorch 組織神經(jīng)網(wǎng)絡(luò)的基本方式。Module 包含了模型的參數(shù)以及計(jì)算邏輯。Function 承載了實(shí)際的功能,定義了前向和后向的計(jì)算邏輯。

Module 是任何神經(jīng)網(wǎng)絡(luò)的基類,pytorch 中所有模型都必需是 Module 的子類。 Module 可以套嵌,構(gòu)成樹狀結(jié)構(gòu)。一個(gè) Module 可以通過(guò)將其他 Module 做為屬性的方式,完成套嵌。

Function 是 pytorch 自動(dòng)求導(dǎo)機(jī)制的核心類。Function 是無(wú)參數(shù)或者說(shuō)無(wú)狀態(tài)的,它只負(fù)責(zé)接收輸入,返回相應(yīng)的輸出;對(duì)于反向,它接收輸出相應(yīng)的梯度,返回輸入相應(yīng)的梯度。

在調(diào)用loss.backward()時(shí),使用的是Function子類中定義的backward()函數(shù)。

以上這篇Pytorch: 自定義網(wǎng)絡(luò)層實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • python計(jì)算最小優(yōu)先級(jí)隊(duì)列代碼分享

    python計(jì)算最小優(yōu)先級(jí)隊(duì)列代碼分享

    python計(jì)算最小優(yōu)先級(jí)隊(duì)列代碼分享,大家參考使用吧
    2013-12-12
  • Python 高級(jí)教程之線程進(jìn)程和協(xié)程的代碼解析

    Python 高級(jí)教程之線程進(jìn)程和協(xié)程的代碼解析

    這篇文章主要介紹了Python 高級(jí)教程之線程進(jìn)程和協(xié)程的代碼解析,包括使用線程模塊的簡(jiǎn)單示例,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 手把手教你配置JupyterLab 環(huán)境的實(shí)現(xiàn)

    手把手教你配置JupyterLab 環(huán)境的實(shí)現(xiàn)

    這篇文章主要介紹了手把手教你配置JupyterLab 環(huán)境,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • django的settings中設(shè)置中文支持的實(shí)現(xiàn)

    django的settings中設(shè)置中文支持的實(shí)現(xiàn)

    這篇文章主要介紹了django的settings中設(shè)置中文支持的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Selenium定時(shí)刷新網(wǎng)頁(yè)的實(shí)現(xiàn)代碼

    Selenium定時(shí)刷新網(wǎng)頁(yè)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Selenium定時(shí)刷新網(wǎng)頁(yè)的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • 結(jié)束運(yùn)行python的方法

    結(jié)束運(yùn)行python的方法

    在本篇文章里小編給大家分享的是關(guān)于結(jié)束運(yùn)行python的方法以及相關(guān)代碼,有需要的朋友們跟著學(xué)習(xí)下。
    2020-06-06
  • Python寫捕魚達(dá)人的游戲?qū)崿F(xiàn)

    Python寫捕魚達(dá)人的游戲?qū)崿F(xiàn)

    這篇文章主要介紹了Python寫捕魚達(dá)人的游戲?qū)崿F(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Python 中類的構(gòu)造方法 __New__的妙用

    Python 中類的構(gòu)造方法 __New__的妙用

    這篇文章主要介紹了Python 中類的構(gòu)造方法 New的妙用,Python 的類中,所有以雙下劃線__包起來(lái)的方法,叫魔術(shù)方法,魔術(shù)方法在類或?qū)ο蟮哪承┦录l(fā)出后可以自動(dòng)執(zhí)行,讓類具有神奇的魔力。下面就來(lái)學(xué)習(xí)文章的詳細(xì)內(nèi)容把
    2021-10-10
  • 基于Python實(shí)現(xiàn)自動(dòng)用小寫字母替換文件后綴的大寫字母

    基于Python實(shí)現(xiàn)自動(dòng)用小寫字母替換文件后綴的大寫字母

    本文介紹基于Python語(yǔ)言,基于一個(gè)大文件夾,遍歷其中的多個(gè)子文件夾,對(duì)于每一個(gè)子文件夾中的大量文件,批量將其文件的名稱或后綴名中的字母由大寫修改為小寫的方法,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-04-04
  • 基于ID3決策樹算法的實(shí)現(xiàn)(Python版)

    基于ID3決策樹算法的實(shí)現(xiàn)(Python版)

    下面小編就為大家?guī)?lái)一篇基于ID3決策樹算法的實(shí)現(xiàn)(Python版)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05

最新評(píng)論