一文讀懂PyTorch張量基礎(附代碼)

一文讀懂PyTorch張量基礎(附代碼)

翻譯:和中華

校對:丁楠雅

本文約1000字,建議閱讀5分鐘。

本文介紹了PyTorch Tensor最基礎的知識以及如何跟Numpy的ndarray互相轉換。

本文介紹了PyTorch中的Tensor類,它類似於Numpy中的ndarray,它構成了在PyTorch中構建神經網絡的基礎。

我們已經知道張量到底是什麼了,並且知道如何用Numpy的ndarray來表示它們,現在我們看看如何在PyTorch中表示它們。

自從Facebook在2017年初將PyTorch開源以來,它已經在機器學習領域取得了令人矚目的成績。它可能沒有像TensorFlow那樣被廣泛採用 --- 它的最初發布時間早於PyTorch一年,背後有Google的支持,並且當神經網絡工具迎來新的潮流時,它已經將自己確立為了金牌標準。但PyTorch在研究領域受到了廣泛的關注,這種關注大部分來自與Torch本身的關係,以及它的動態計算圖。

一文讀懂PyTorch張量基礎(附代碼)

儘管最近我的注意力都在PyTorch上,但這篇文章並不是PyTorch的教程。它更多地是介紹PyTorch的Tensor類,這與Numpy的ndarray類似。

張量基礎

讓我們來看一下PyTorch的張量基礎知識,從創建張量開始(使用Tensor類):

import torch

# Create a Torch tensor

t = torch.Tensor([[1, 2, 3], [4, 5, 6]])

t

tensor([[ 1., 2., 3.],

[ 4., 5., 6.]])

你可以使用兩種方式轉置一個張量:

# Transpose

t.t()

# Transpose (via permute)

t.permute(-1,0)

兩者都會產生如下輸出結果:

tensor([[ 1., 4.],

[ 2., 5.],

[ 3., 6.]])

請注意,兩種方式都不會導致原始張量的改變。

用view重新塑造張量:

# Reshape via view

t.view(3,2)

tensor([[ 1., 2.],

[ 3., 4.],

[ 5., 6.]])

另一個例子:

# View again...

t.view(6,1)

tensor([[ 1.],

[ 2.],

[ 3.],

[ 4.],

[ 5.],

[ 6.]])

很明顯,Numpy所遵循的數學約定延續到了PyTorch張量中(我具體指的是行和列的標記符號)。

創建一個張量並用零填充(你可以用ones()來完成類似的操作):

# Create tensor of zeros

t = torch.zeros(3, 3)

t

tensor([[ 0., 0., 0.],

[ 0., 0., 0.],

[ 0., 0., 0.]])

從正態分佈中隨機取數並創建張量:

# Create tensor from normal distribution randoms

t = torch.randn(3, 3)

t

tensor([[ 1.0274, -1.3727, -0.2196],

[-0.7258, -2.1236, -0.8512],

[ 0.0392, 1.2392, 0.5460]])

Tensor對象的形狀、維度和數據類型:

# Some tensor info

print('Tensor shape:', t.shape) # t.size() gives the same

print('Number of dimensions:', t.dim())

print('Tensor type:', t.type()) # there are other types

Tensor shape: torch.Size([3, 3])

Number of dimensions: 2

Tensor type: torch.FloatTensor

除了在數學概念上,ndarray和Tensor在編程和實例化上也有相似之處。

你可以像切片ndarrays一樣切片PyTorch張量,任何使用其他Python結構的人應該都熟悉這一點:

# Slicing

t = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Every row, only the last column

print(t[:, -1])

# First 2 rows, all columns

print(t[:2, :])

# Lower right most corner

print(t[-1:, -1:])

tensor([ 3., 6., 9.])

tensor([[ 1., 2., 3.],

[ 4., 5., 6.]])

tensor([[ 9.]])

PyTorch張量和Numpy ndarray之間轉換

你可以輕鬆地從ndarray創建張量,反之亦然。這些操作很快,因為兩個結構的數據將共享相同的內存空間,因此不涉及複製。這顯然是一種有效的方法。

# Numpy ndarray PyTorch tensor

import numpy as np

# ndarray to tensor

a = np.random.randn(3, 5)

t = torch.from_numpy(a)

print(a)

print(t)

print(type(a))

print(type(t))

[[-0.52192738 -1.11579634 1.26925835 0.10449378 -1.02894372]

[-0.78707263 -0.05350072 -0.65815075 0.18810677 -0.52795765]

[-0.41677548 0.82031861 -2.46699201 0.60320375 -1.69778546]]

tensor([[-0.5219, -1.1158, 1.2693, 0.1045, -1.0289],

[-0.7871, -0.0535, -0.6582, 0.1881, -0.5280],

[-0.4168, 0.8203, -2.4670, 0.6032, -1.6978]], dtype=torch.float64)

# tensor to ndarray

t = torch.randn(3, 5)

a = t.numpy()

print(t)

print(a)

print(type(t))

print(type(a))

tensor([[-0.1746, -2.4118, 0.4688, -0.0517, -0.2706],

[-0.8402, -0.3289, 0.4170, 1.9131, -0.8601],

[-0.6688, -0.2069, -0.8106, 0.8582, -0.0450]])

[[-0.17455131 -2.4117854 0.4688457 -0.05168453 -0.2706456 ]

[-0.8402392 -0.3289494 0.41703534 1.9130518 -0.86014426]

[-0.6688193 -0.20693372 -0.8105542 0.8581988 -0.04502954]]

基本張量操作

這裡有幾個張量操作,你可以將它與Numpy的實現進行比較。

首先是叉積(cross product):

# Compute cross product

t1 = torch.randn(4, 3)

t2 = torch.randn(4, 3)

t1.cross(t2)

tensor([[ 2.6594, -0.5765, 1.4313],

[ 0.4710, -0.3725, 2.1783],

[-0.9134, 1.6253, 0.7398],

[-0.4959, -0.4198, 1.1338]])

下面是矩陣的積:

# Compute matrix product

t = (torch.Tensor([[2, 4], [5, 10]]).mm(torch.Tensor([[10], [20]])))

t

tensor([[ 100.],

[ 250.]])

最後,對應元素的乘法:

# Elementwise multiplication

t = torch.Tensor([[1, 2], [3, 4]])

t.mul(t)

tensor([[ 1., 4.],

[ 9., 16.]])

關於GPU的一句話

PyTorch張量具有固有的GPU支持。指定使用GPU內存和CUDA內核來存儲和執行張量計算非常簡單;cuda軟件包可以幫助確定GPU是否可用,並且該軟件包的cuda方法為GPU分配了一個張量。

# Is CUDA GPU available?

torch.cuda.is_available()

# How many CUDA devices?

torch.cuda.device_count()

# Move to GPU

t.cuda()

原文鏈接:https://www.kdnuggets.com/2018/05/pytorch-tensor-basics.html

譯者簡介

一文讀懂PyTorch張量基礎(附代碼)

和中華,留德軟件工程碩士。由於對機器學習感興趣,碩士論文選擇了利用遺傳算法思想改進傳統kmeans。目前在杭州進行大數據相關實踐。加入數據派THU希望為IT同行們儘自己一份綿薄之力,也希望結交許多志趣相投的小夥伴。


分享到:


相關文章: