最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Pytorch來擬合函數(shù)方式

 更新時間:2020年01月14日 15:07:09   作者:原我歸來是少年  
今天小編就為大家分享一篇使用Pytorch來擬合函數(shù)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

其實各大深度學(xué)習(xí)框架背后的原理都可以理解為擬合一個參數(shù)數(shù)量特別龐大的函數(shù),所以各框架都能用來擬合任意函數(shù),Pytorch也能。

在這篇博客中,就以擬合y = ax + b為例(a和b為需要擬合的參數(shù)),說明在Pytorch中如何擬合一個函數(shù)。

一、定義擬合網(wǎng)絡(luò)

1、觀察普通的神經(jīng)網(wǎng)絡(luò)的優(yōu)化流程

# 定義網(wǎng)絡(luò)
net = ...
# 定義優(yōu)化器
optimizer = torch.optim.Adam(net.parameters(), lr=0.001, weight_decay=0.0005)
# 定義損失函數(shù)
loss_op = torch.nn.MSELoss(reduction='sum')
# 優(yōu)化
for step, (inputs, tag) in enumerate(dataset_loader):
 # 向前傳播
 outputs = net(inputs)
 # 計算損失
 loss = loss_op(tag, outputs)
 # 清空梯度
 optimizer.zero_grad()
 # 向后傳播
 loss.backward()
 # 更新梯度
 optimizer.step()

上面的代碼就是一般情況下的流程。為了能使用Pytorch內(nèi)置的優(yōu)化器,所以我們需要定義一個一個網(wǎng)絡(luò),實現(xiàn)函數(shù)parameters(返回需要優(yōu)化的參數(shù))和forward(向前傳播);為了能支持GPU優(yōu)化,還需要實現(xiàn)cuda和cpu兩個函數(shù),把參數(shù)從內(nèi)存復(fù)制到GPU上和從GPU復(fù)制回內(nèi)存。

基于以上要求,網(wǎng)絡(luò)的定義就類似于:

class Net:
  def __init__(self):
    # 在這里定義要求的參數(shù)
    pass

  def cuda(self):
    # 傳輸參數(shù)到GPU
    pass

  def cpu(self):
    # 把參數(shù)傳輸回內(nèi)存
    pass

  def forward(self, inputs):
   # 實現(xiàn)向前傳播,就是根據(jù)輸入inputs計算一遍輸出
    pass

  def parameters(self):
   # 返回參數(shù)
    pass

在擬合數(shù)據(jù)量很大時,還可以使用GPU來加速;如果沒有英偉達顯卡,則可以不實現(xiàn)cuda和cpu這兩個函數(shù)。

2、初始化網(wǎng)絡(luò)

回顧本文目的,擬合: y = ax + b, 所以在__init__函數(shù)中就需要定義a和b兩個參數(shù),另外為了實現(xiàn)parameters、cpu和cuda,還需要定義屬性__parameters和__gpu:

  def __init__(self):
    # y = a*x + b
    self.a = torch.rand(1, requires_grad=True) # 參數(shù)a
    self.b = torch.rand(1, requires_grad=True) # 參數(shù)b
    self.__parameters = dict(a=self.a, b=self.b) # 參數(shù)字典
    self.___gpu = False # 是否使用gpu來擬合

要擬合的參數(shù),不能初始化為0! ,一般使用隨機值即可。還需要把requires_grad參數(shù)設(shè)置為True,這是為了支持向后傳播。

3、實現(xiàn)向前傳播

  def forward(self, inputs):
    return self.a * inputs + self.b

非常的簡單,就是根據(jù)輸入inputs計算一遍輸出,在本例中,就是計算一下 y = ax + b。計算完了要記得返回計算的結(jié)果。

4、把參數(shù)傳送到GPU

為了支持GPU來加速擬合,需要把參數(shù)傳輸?shù)紾PU,且需要更新參數(shù)字典__parameters:

  def cuda(self):
    if not self.___gpu:
      self.a = self.a.cuda().detach().requires_grad_(True) # 把a傳輸?shù)絞pu
      self.b = self.b.cuda().detach().requires_grad_(True) # 把b傳輸?shù)絞pu
      self.__parameters = dict(a=self.a, b=self.b) # 更新參數(shù)
      self.___gpu = True # 更新標(biāo)志,表示參數(shù)已經(jīng)傳輸?shù)絞pu了
    # 返回self,以支持鏈?zhǔn)秸{(diào)用
    return self

參數(shù)a和b,都是先調(diào)用detach再調(diào)用requires_grad_,是為了避免錯誤raise ValueError("can't optimize a non-leaf Tensor")(參考:ValueError: can't optimize a non-leaf Tensor?)。

4、把參數(shù)傳輸回內(nèi)存

類似于cuda函數(shù),不做過多解釋。

  def cpu(self):
    if self.___gpu:
      self.a = self.a.cpu().detach().requires_grad_(True)
      self.b = self.b.cpu().detach().requires_grad_(True)
      self.__parameters = dict(a=self.a, b=self.b)
      self.___gpu = False
    return self

5、返回網(wǎng)絡(luò)參數(shù)

為了能使用Pytorch內(nèi)置的優(yōu)化器,就要實現(xiàn)parameters函數(shù),觀察Pytorch里面的實現(xiàn):

  def parameters(self, recurse=True):
    r"""...
    """
    for name, param in self.named_parameters(recurse=recurse):
      yield param

實際上就是使用yield返回網(wǎng)絡(luò)的所有參數(shù),因此本例中的實現(xiàn)如下:

  def parameters(self):
    for name, param in self.__parameters.items():
      yield param

完整的實現(xiàn)將會放在后面。

二、測試

1、生成測試數(shù)據(jù)

def main():
  # 生成虛假數(shù)據(jù)
  x = np.linspace(1, 50, 50)
  # 系數(shù)a、b
  a = 2
  b = 1
  # 生成y
  y = a * x + b
  # 轉(zhuǎn)換為Tensor
  x = torch.from_numpy(x.astype(np.float32))
  y = torch.from_numpy(y.astype(np.float32))

2、定義網(wǎng)絡(luò)

 # 定義網(wǎng)絡(luò)
  net = Net()
  # 定義優(yōu)化器
  optimizer = torch.optim.Adam(net.parameters(), lr=0.001, weight_decay=0.0005)
  # 定義損失函數(shù)
  loss_op = torch.nn.MSELoss(reduction='sum')

3、把數(shù)據(jù)傳輸?shù)紾PU(可選)

 # 傳輸?shù)紾PU
  if torch.cuda.is_available():
    x = x.cuda()
    y = y.cuda()
    net = net.cuda()

4、定義優(yōu)化器和損失函數(shù)

如果要使用GPU加速,優(yōu)化器必須要在網(wǎng)絡(luò)的參數(shù)傳輸?shù)紾PU之后在定義,否則優(yōu)化器里的參數(shù)還是內(nèi)存里的那些參數(shù),傳到GPU里面的參數(shù)不能被更新。 可以根據(jù)代碼來理解這句話。

 # 定義優(yōu)化器
  optimizer = torch.optim.Adam(net.parameters(), lr=0.001, weight_decay=0.0005)
  # 定義損失函數(shù)
  loss_op = torch.nn.MSELoss(reduction='sum')

5、擬合(也是優(yōu)化)

# 最多優(yōu)化20001次
  for i in range(1, 20001, 1):
   # 向前傳播
    out = net.forward(x)
 # 計算損失
    loss = loss_op(y, out)
 # 清空梯度(非常重要)
    optimizer.zero_grad()
 # 向后傳播,計算梯度
    loss.backward()
 # 更新參數(shù)
    optimizer.step()
 # 得到損失的numpy值
    loss_numpy = loss.cpu().detach().numpy()
    if i % 1000 == 0: # 每1000次打印一下?lián)p失
      print(i, loss_numpy)

    if loss_numpy < 0.00001: # 如果損失小于0.00001
     # 打印參數(shù)
     a = net.a.cpu().detach().numpy()
     b = net.b.cpu().detach().numpy()
      print(a, b)
      # 退出
      exit()

6、完整示例代碼

# coding=utf-8
from __future__ import absolute_import, division, print_function
import torch
import numpy as np


class Net:
  def __init__(self):
    # y = a*x + b
    self.a = torch.rand(1, requires_grad=True) # 參數(shù)a
    self.b = torch.rand(1, requires_grad=True) # 參數(shù)b
    self.__parameters = dict(a=self.a, b=self.b) # 參數(shù)字典
    self.___gpu = False # 是否使用gpu來擬合

  def cuda(self):
    if not self.___gpu:
      self.a = self.a.cuda().detach().requires_grad_(True) # 把a傳輸?shù)絞pu
      self.b = self.b.cuda().detach().requires_grad_(True) # 把b傳輸?shù)絞pu
      self.__parameters = dict(a=self.a, b=self.b) # 更新參數(shù)
      self.___gpu = True # 更新標(biāo)志,表示參數(shù)已經(jīng)傳輸?shù)絞pu了
    # 返回self,以支持鏈?zhǔn)秸{(diào)用
    return self

  def cpu(self):
    if self.___gpu:
      self.a = self.a.cpu().detach().requires_grad_(True)
      self.b = self.b.cpu().detach().requires_grad_(True)
      self.__parameters = dict(a=self.a, b=self.b) # 更新參數(shù)
      self.___gpu = False
    return self

  def forward(self, inputs):
    return self.a * inputs + self.b

  def parameters(self):
    for name, param in self.__parameters.items():
      yield param


def main():

  # 生成虛假數(shù)據(jù)
  x = np.linspace(1, 50, 50)

  # 系數(shù)a、b
  a = 2
  b = 1

  # 生成y
  y = a * x + b

  # 轉(zhuǎn)換為Tensor
  x = torch.from_numpy(x.astype(np.float32))
  y = torch.from_numpy(y.astype(np.float32))

  # 定義網(wǎng)絡(luò)
  net = Net()

  # 傳輸?shù)紾PU
  if torch.cuda.is_available():
    x = x.cuda()
    y = y.cuda()
    net = net.cuda()

  # 定義優(yōu)化器
  optimizer = torch.optim.Adam(net.parameters(), lr=0.001, weight_decay=0.0005)

  # 定義損失函數(shù)
  loss_op = torch.nn.MSELoss(reduction='sum')

  # 最多優(yōu)化20001次
  for i in range(1, 20001, 1):
    # 向前傳播
    out = net.forward(x)
    # 計算損失
    loss = loss_op(y, out)
    # 清空梯度(非常重要)
    optimizer.zero_grad()
    # 向后傳播,計算梯度
    loss.backward()
    # 更新參數(shù)
    optimizer.step()
    # 得到損失的numpy值
    loss_numpy = loss.cpu().detach().numpy()
    if i % 1000 == 0: # 每1000次打印一下?lián)p失
      print(i, loss_numpy)

    if loss_numpy < 0.00001: # 如果損失小于0.00001
      # 打印參數(shù)
      a = net.a.cpu().detach().numpy()
      b = net.b.cpu().detach().numpy()
      print(a, b)
      # 退出
      exit()


if __name__ == '__main__':
  main()

以上這篇使用Pytorch來擬合函數(shù)方式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python sys模塊常用方法解析

    Python sys模塊常用方法解析

    這篇文章主要介紹了Python sys模塊常用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • python 連接sqlite及簡單操作

    python 連接sqlite及簡單操作

    本文通過實例代碼給大家介紹了python 連接sqlite及簡單操作,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-06-06
  • Tensorflow實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的詳細代碼

    Tensorflow實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的詳細代碼

    這篇文章主要為大家詳細介紹了Tensorflow實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的詳細代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • python中如何使用正則表達式提取數(shù)據(jù)

    python中如何使用正則表達式提取數(shù)據(jù)

    這篇文章主要介紹了python中如何使用正則表達式提取數(shù)據(jù)問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Python使用Bokeh庫實現(xiàn)炫目的交互可視化

    Python使用Bokeh庫實現(xiàn)炫目的交互可視化

    Bokeh是一個用于創(chuàng)建交互式可視化圖形的強大Python庫,它不僅易于使用,而且功能強大,適用于各種數(shù)據(jù)可視化需求,本文將介紹Bokeh庫的繪圖可視化基礎(chǔ)入門,需要的可以了解下
    2024-03-03
  • django 信號調(diào)度機制詳解

    django 信號調(diào)度機制詳解

    這篇文章主要介紹了django 信號調(diào)度機制詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Python Pandas高級教程之時間處理

    Python Pandas高級教程之時間處理

    我們發(fā)現(xiàn)關(guān)于時間日期的簡單計算很多功能都是datetime庫提供的,那么pandas有沒有提供跟日期時間有關(guān)的函數(shù),通過下面文章來了解下,這篇文章主要給大家介紹了關(guān)于Python Pandas高級教程之時間處理的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • Python UnicodeEncodeError: ''gbk'' codec can''t encode character 解決方法

    Python UnicodeEncodeError: ''gbk'' codec can''t encode chara

    這篇文章主要介紹了Python UnicodeEncodeError: 'gbk' codec can't encode character 解決方法,需要的朋友可以參考下
    2015-04-04
  • python將excel轉(zhuǎn)換為csv的代碼方法總結(jié)

    python將excel轉(zhuǎn)換為csv的代碼方法總結(jié)

    在本篇文章里小編給大家分享了關(guān)于python如何將excel轉(zhuǎn)換為csv的實例方法和代碼內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2019-07-07
  • Python 制作詞云的WordCloud參數(shù)用法說明

    Python 制作詞云的WordCloud參數(shù)用法說明

    這篇文章主要介紹了Python 制作詞云的WordCloud參數(shù)用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評論

綦江县| 常德市| 兰坪| 吴堡县| 桦南县| 玉龙| 普定县| 施秉县| 仁化县| 揭东县| 慈溪市| 观塘区| 云安县| 铜川市| 梓潼县| 朝阳县| 九龙县| 长寿区| 石柱| 清流县| 石城县| 广昌县| 永清县| 团风县| 嘉兴市| 攀枝花市| 阿拉尔市| 昌图县| 潼关县| 行唐县| 河西区| 东山县| 赤壁市| 莆田市| 富裕县| 四平市| 辽阳市| 无极县| 图木舒克市| 龙口市| 广水市|