【機(jī)器學(xué)習(xí)】PyTorch 基本網(wǎng)絡(luò)實(shí)現(xiàn)

地點(diǎn):鑒主
時(shí)間:2017-1130
本文主要記錄學(xué)習(xí) Pytorch Tutorials 過程中的筆記及相關(guān)問題。

PyTorch 的相關(guān)背景就不做介紹了,網(wǎng)上很多。
在實(shí)際的使用過程中來看,對(duì)比之前用過的 TensorFlow 和 Keras 而言,使用 PyTorch 就像是在寫一個(gè)普通的 Python 程序,而不是像 TF 和 Keras 一樣限制頗多,因此在使用的過程中,相比于其他框架能夠很清楚自己做的是什么,非常的新手友好。

PyTorch 基本概念

機(jī)器學(xué)習(xí)方面的幾個(gè)重要概念在 PyTorch 主要通過 Tensors, Autograd, nn module 進(jìn)行體現(xiàn)。

Tensors

Numpy 是一個(gè)很好的計(jì)算工具,但是它無法使用 GPUs 加速數(shù)值計(jì)算,因此性能不能滿足要求。
首先引入最基本的 PyTorch 概念: Tensor. Tensor 是一個(gè) n 維數(shù)組,同時(shí) PyTorch 提供了多種函數(shù)對(duì)它進(jìn)行操作。與 Numpy.array 相同的是, PyTorch 的 Tensors 不包含任何 深度學(xué)習(xí),計(jì)算圖或者梯度 這些科學(xué)計(jì)算的工具。
然而不同于 numpy 的是,PyTorch 的 Tensors 能夠利用 GPUs 來進(jìn)行加速數(shù)值計(jì)算。在 GPU 上運(yùn)行 PyTorch 的 Tensor, 我們需要將它簡(jiǎn)單轉(zhuǎn)換一下數(shù)據(jù)格式。

# -*- coding: utf-8 -*-

import torch

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor # 在 GPU 上運(yùn)行調(diào)用的函數(shù)

# N is 批數(shù)目; D_in is 輸入維數(shù);
# H is 隱藏層維數(shù); D_out is 輸出層維數(shù).
N, D_in, H, D_out = 64, 1000, 100, 10

# 創(chuàng)建隨機(jī)輸入輸出數(shù)據(jù)
x = torch.randn(N, D_in).type(dtype)
y = torch.randn(N, D_out).type(dtype)

# 隨機(jī)初始化權(quán)重文件
w1 = torch.randn(D_in, H).type(dtype)
w2 = torch.randn(H, D_out).type(dtype)

# 設(shè)置學(xué)習(xí)率
learning_rate = 1e-6

for t in range(500):
    # 前向傳播,計(jì)算預(yù)測(cè)的 y 值 
    h = x.mm(w1)
    h_relu = h.clamp(min=0)
    y_pred = h_relu.mm(w2)

    # 計(jì)算并且輸出 loss 值
    loss = (y_pred - y).pow(2).sum()
    print(t, loss)

    # 基于 loss 值 反向傳播計(jì)算 w1 和 w2 的梯度
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.t().mm(grad_y_pred)
    grad_h_relu = grad_y_pred.mm(w2.t())
    grad_h = grad_h_relu.clone()
    grad_h[h < 0] = 0
    grad_w1 = x.t().mm(grad_h)

    # 使用梯度下降更新權(quán)值
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

可以看出,在實(shí)際的操作上面,其使用方法和 numpy 非常相似。

Autograd

上面的例子實(shí)現(xiàn)了前向傳播和反向傳播,這是神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)。在實(shí)際的過程中,我們可以使用 Automatic Differentiation 來自動(dòng)計(jì)算神經(jīng)網(wǎng)絡(luò)的反向傳播值。PyTorch 中的 autograd 包就是用于提供這個(gè)功能。

When using autograd, the forward pass of your network will define a computational graph; nodes in the graph will be Tensors, and edges will be functions that produce output Tensors from input Tensors. Backpropagating through this graph then allows you to easily compute gradients.
當(dāng)使用 autograd 時(shí),你網(wǎng)絡(luò)中的前向傳播將會(huì)定義一個(gè)計(jì)算圖,在這個(gè)圖中的每個(gè)節(jié)點(diǎn)都是張量,邊可以提供從輸入張量到輸出張量的處理功能。隨后圖中的反向傳播過程能夠讓你簡(jiǎn)單計(jì)算梯度。

在實(shí)際的使用中非常簡(jiǎn)單。我們將 PyTorch 的 Tensors 包裝進(jìn) Variable ; 一個(gè) Varible 展示了計(jì)算圖中的一個(gè)節(jié)點(diǎn)。如果 x 是一個(gè) Variable ,x.data 既是張量,x.grad 是另一個(gè) Variable,其中包含了通過變換值求出的 x 梯度。

PyTorch Variable 的操作基本和 PyTorch Tensors 一樣。區(qū)別在于使用 Variable 定義的是一個(gè)計(jì)算圖,允許網(wǎng)絡(luò)自動(dòng)求梯度。

隨后使用 Variables 和 autograd 來實(shí)現(xiàn)上文的神經(jīng)網(wǎng)絡(luò), 現(xiàn)在我們不需要再實(shí)現(xiàn)上文的 backward pass 過程。

import torch
from torch.autograd import Variable

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor  # gpu 運(yùn)行時(shí)的代碼

# N is 批數(shù)目; D_in is 輸入維數(shù);
# H is 隱藏層維數(shù); D_out is 輸出層維數(shù).
N, D_in, H, D_out = 64, 1000, 100, 10

# 創(chuàng)建隨機(jī) Tensors 來保存  輸入和輸出, 隨后將它們包進(jìn) Variables 
# 設(shè)置 requires_grad = False 來表示我們無需計(jì)算梯度
# with respect to these Variables during the backward pass.
x = Variable(torch.randn(N, D_in).type(dtype), requires_grad=False)
y = Variable(torch.randn(N, D_out).type(dtype), requires_grad=False)

# 為權(quán)值創(chuàng)建隨機(jī) Tensor, 并且將它們包進(jìn) Variables 
# 設(shè)置 requires_grad = True 表示我們需要計(jì)算梯度 
# respect to these Variables during the backward pass.
w1 = Variable(torch.randn(D_in, H).type(dtype), requires_grad=True)
w2 = Variable(torch.randn(H, D_out).type(dtype), requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    # Forward pass: 使用 Variables 中的值計(jì)算 y;這個(gè)操作和我們使用 Tensors 計(jì)算
    # 時(shí)一樣, 但是我們不需要保持對(duì)中間值的引用,因?yàn)槲覀儫o需動(dòng)手實(shí)現(xiàn) backward pass .
    y_pred = x.mm(w1).clamp(min=0).mm(w2)

    # 使用 Variable 中的函數(shù)計(jì)算并且輸出 loss 值 
    # 此時(shí) loss 值是一個(gè) shape (1, ) 的 Variable,并且 loss.data 是一個(gè)形狀為 (1, ) 的 Tensor。
    # loss.data[0] 是一個(gè)保存 loss 值的標(biāo)量
    loss = (y_pred - y).pow(2).sum()
    print(t, loss.data[0])

    # 使用 autograd 計(jì)算 backward pass. 這個(gè)調(diào)用將會(huì)計(jì)算 loss 值的梯度,依據(jù)的是
    # 所有 requires_grad = True 的 Variable。
    # After this call w1.grad and w2.grad will be Variables holding the gradient
    # of the loss with respect to w1 and w2 respectively.
    loss.backward()

    # 使用 梯度下降更新權(quán)值;w1.data 和 w2.data 是 Tensors。
    # w1.grad 和 w2.grad 是 Variable; w1.grad.data 和 w2.grad.data 是 Tensors
    w1.data -= learning_rate * w1.grad.data
    w2.data -= learning_rate * w2.grad.data

    # 更新權(quán)值之后將梯度歸 0
    w1.grad.data.zero_()
    w2.grad.data.zero_()

PyTorch : Variables and autograd

nn module

PyTorch CNN

為了進(jìn)行實(shí)際操作,用 PyTorch 構(gòu)建一個(gè) CNN 是很常見的方法。
首先需要導(dǎo)入基本的包。

參考

http://pytorch.org/tutorials/beginner/pytorch_with_examples.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容