paddle2.0之 paddle Tensor 第一集

paddlepaddle2.0— 開啓新夢想

paddlepaddle2.0新的起航,是否是有新手小夥伴對這些很迷茫呢?html

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

傳說中的:能夠new一個對象的python尚未到建立對象的能力。python

據說對象在paddle的加持下已是過去,只需百度和谷歌加上paddle的熟練操做,和paddle實現人機對話指日可待編程

做爲一名paddle小白怎麼辦呢?數組

今天由三歲帶你們一塊兒開啓paddle學習新夢想!網絡

本文對應AIstudio地址:https://aistudio.baidu.com/aistudio/projectdetail/1275635數據結構

三歲白話paddle2.0系列歷史地址

三歲白話paddle2.0系列第一話:起航新徵程(項目):https://aistudio.baidu.com/aistudio/projectdetail/1270135
三歲白話paddle2.0系列第一話:起航新徵程(csdn):https://blog.csdn.net/weixin_45623093/article/details/110198594框架

參考資料:dom

paddlepaddle官方文檔:異步

https://www.paddlepaddle.org.cn/documentation/docs/zh/2.0-rc/guides/01_paddle2.0_introduction/basic_concept/tensor_introduction_cn.htmlide

百度:https://www.baidu.com/s?wd=Tensor

pytorch官方文檔:https://pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html#sphx-glr-beginner-blitz-tensor-tutorial-py

Tensor->張量

paddle中和大多數的深度學習框架同樣Tensor是運算的基礎,那麼什麼是Tensor呢?讓咱們一塊兒來看看吧!

這是paddle提供的一種數據結構和python的幾種內置結構類型有所不一樣,他更相似於C語言的多維數組,和Numpy的array相相似

咱們能夠很是方便的讀取到位置上的內容,可是不可以輕易的給已經生成的Tensor添加成員或者生成維度(優缺點

全部的修改都須要經過新建在把數據處理後複製進去(paddle對此做了必定程度的封裝,便於使用)

數學上的張量(圖解)

在數學上張量就是向量這個你們就有數了,但也多是多維的向量,向量的向量,向量的向量的向量,……反覆套娃

 

paddle Tensor的建立

# 導入paddle
import paddle

建立相似於vector的1-D Tensor,其rank爲1

建立一個向量維度是一

# 可經過dtype來指定Tensor數據類型,不然會建立float32類型的Tensor
rank_1_tensor = paddle.to_tensor([2.0, 3.0, 4.0], dtype='float64')
print(rank_1_tensor)
Tensor(shape=[3], dtype=float64, place=CPUPlace, stop_gradient=True,
       [2., 3., 4.])

結果解析

shape=[3]:一維長度爲3;

dtype=float64:類型是64位的;

place=CPUPlace:使用的是cpu;

stop_gradient=True:不求導,不參加梯度更新;

[2., 3., 4.]內容是[2., 3., 4.]

建立一個標量

這裏使用兩種辦法獲得的結果是同樣的!

int_0 = paddle.to_tensor(2)
int_1 = paddle.to_tensor([2])
print(f"整型標量:{int_0},{int_1}")
float_0 = paddle.to_tensor(2.0, dtype='float64')
float_1 = paddle.to_tensor([2.0], dtype='float64')
print(f"浮點型標量:{float_0},{float_1}")
整型標量:Tensor(shape=[1], dtype=int64, place=CPUPlace, stop_gradient=True,
       [2]),Tensor(shape=[1], dtype=int64, place=CPUPlace, stop_gradient=True,
       [2])
浮點型標量:Tensor(shape=[1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [2.]),Tensor(shape=[1], dtype=float64, place=CPUPlace, stop_gradient=True,
       [2.])

建立一個二維的張量(矩陣)

法方法和一維的同樣,可是能夠對比結果,看到一維和二維的差距明顯

rank_2_tensor = paddle.to_tensor([[1.0, 2.0, 3.0],
                                  [4.0, 5.0, 6.0]])
print(rank_2_tensor)
Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
       [[1., 2., 3.],
        [4., 5., 6.]])

建立多維矩陣

方法同樣,就是把裏面的內容進行必定程度的修改,把矩陣的維度進行必定的提升

# Tensor能夠有任意數量的軸(也稱爲維度)
rank_3_tensor = paddle.to_tensor([[[1, 2, 3, 4, 5],
                                   [6, 7, 8, 9, 10]],
                                  [[11, 12, 13, 14, 15],
                                   [16, 17, 18, 19, 20]]])
print(rank_3_tensor)
Tensor(shape=[2, 2, 5], dtype=int64, place=CPUPlace, stop_gradient=True,
       [[[1, 2, 3, 4, 5],
         [ 6,  7,  8,  9, 10]],

        [[11, 12, 13, 14, 15],
         [16, 17, 18, 19, 20]]])

利用圖片對上面的一維、二維、三維Tensor進行解釋

不一樣rank的Tensor可視化表示

Tensor與Numpy array的相互轉換

因爲Tensor與Numpy array在表現上極爲類似,轉換也便存在可能

使用Tensor.numpy()便可輕鬆裝換由Tensor轉換成Numpy

使用paddle.to_tensor(Numpy array(xxx))能夠把Numpy轉換成Tensor

建立的 Tensor 與原 Numpy array 具備相同的 shape 與 dtype。

import numpy
# 對rank_3_tensor進行轉換(Tensor->Numpy)
rank_3_tensor.numpy()
array([[[ 1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10]],

       [[11, 12, 13, 14, 15],
        [16, 17, 18, 19, 20]]], dtype=int64)

 


# 使用Numpy轉換成Tensor
#生成一維
rank_1_tensor = paddle.to_tensor(numpy.array([1.0, 2.0]))
#生成二維
rank_2_tensor = paddle.to_tensor(numpy.array([[1.0, 2.0],
                                              [3.0, 4.0]]))
#生成隨機的三維
rank_3_tensor = paddle.to_tensor(numpy.random.rand(3, 2))
print(f'生成一維:{rank_1_tensor}生成二維:{rank_2_tensor}生成隨機的三維:{rank_3_tensor}')
生成一維:Tensor(shape=[2], dtype=float64, place=CPUPlace, stop_gradient=True,
       [1., 2.])生成二維:Tensor(shape=[2, 2], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[1., 2.],
        [3., 4.]])生成隨機的三維:Tensor(shape=[3, 2], dtype=float64, place=CPUPlace, stop_gradient=True,
       [[0.47932373, 0.27477318],
        [0.15932428, 0.56038360],
        [0.30284743, 0.91852095]])

對虛數的支持

在深度學習中虛數的存在也是不可或缺的對虛數的包涵也是頗有必要的

Tensor不只支持 floats、ints 類型數據,也支持 complex numbers 數據!

rank_2_complex_tensor = paddle.to_tensor([[1+1j, 2+2j],
                                          [3+3j, 4+4j]])
print(rank_2_complex_tensor)
ComplexTensor[real]: generated_tensor_1.real
  - place: CPUPlace
  - shape: [2, 2]
  - layout: NCHW
  - dtype: float
  - data: [1 2 3 4]
ComplexTensor[imag]: generated_tensor_1.imag
  - place: CPUPlace
  - shape: [2, 2]
  - layout: NCHW
  - dtype: float
  - data: [1 2 3 4]

查看結果能夠發現它把實部和虛部進行了分開的展現

實部:
ComplexTensor[real]: generated_tensor_1.real
  - place: CPUPlace
  - shape: [2, 2]
  - layout: NCHW
  - dtype: float
  - data: [1 2 3 4]
虛部:
ComplexTensor[imag]: generated_tensor_1.imag
  - place: CPUPlace
  - shape: [2, 2]
  - layout: NCHW
  - dtype: float
  - data: [1 2 3 4]

若是檢測到輸入數據包含complex numbers,則會自動建立一個ComplexTensor,ComplexTensor是Paddle中一種特殊的數據結構, 其包含實部(real)與虛部(imag)兩個形狀與數據類型相同的Tensor。

其結構可視化表示爲:

Tensor報錯

Tensor只支持規則的矩陣,對於非規則的會拋出異常!

也就是同一個維度上大小、類型要相同!

# 維數不對會報錯!
rank_2_tensor = paddle.to_tensor([[1.0, 2.0],
                                  [4.0, 5.0, 6.0]])

以上會出現報錯

ValueError: 
	Faild to convert input data to a regular ndarray :
	 - Usually this means the input data contains nested lists with different lengths.

建立一個指定shape的Tensor

Paddle提供了一些API

paddle.zeros([m, n])                # 建立數據全爲0,shape爲[m, n]的Tensor
paddle.ones([m, n])                 # 建立數據全爲1,shape爲[m, n]的Tensor
paddle.full([m, n], 10)             # 建立數據全爲10,shape爲[m, n]的Tensor
paddle.arrange(start, end, step)    # 建立從start到end,步長爲step的Tensor
paddle.linspace(start, end, num)    # 建立從start到end,元素個數固定爲num的Tensor

Tensor的shape(形狀)

名稱 屬性
shape tensor的每一個維度上的元素數量
rank tensor的維度的數量,例如vector的rank爲1,matrix的rank爲2.
axis/dimension tensor某個特定的維度
size tensor中所有元素的個數

舉例說明shape之間的關係

rank_4_tensor = paddle.ones([2, 3, 4, 5])
print(rank_4_tensor)
print("Data Type of every element:", rank_4_tensor.dtype)
print("Number of dimensions:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements number along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements number along the last axis of tensor:", rank_4_tensor.shape[-1])
Tensor(shape=[2, 3, 4, 5], dtype=float32, place=CPUPlace, stop_gradient=True,
       [[[[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]],

         [[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]],

         [[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]],

         [[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]],

         [[1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.],
          [1., 1., 1., 1., 1.]]]])
Data Type of every element: VarType.FP32
Number of dimensions: 4
Shape of tensor: [2, 3, 4, 5]
Elements number along axis 0 of tensor: 2
Elements number along the last axis of tensor: 5

解析結果

Data Type of every element: VarType.FP32

數據類型是32位的

Number of dimensions: 4

維度是4維

Shape of tensor: [2, 3, 4, 5]

大小是[2, 3, 4, 5]

Elements number along axis 0 of tensor: 2

0維度的數量

Elements number along the last axis of tensor: 5

最後一個維度的數量

圖解:

改變維度

以前提過Tensor的維度和數量不可以隨意更改和添加,paddle在這裏就封裝了一個reshape接口來改變Tensor的shape

# 新建3維數據
rank_3_tensor = paddle.to_tensor([[[1, 2, 3, 4, 5],
                                   [6, 7, 8, 9, 10]],
                                  [[11, 12, 13, 14, 15],
                                   [16, 17, 18, 19, 20]],
                                  [[21, 22, 23, 24, 25],
                                   [26, 27, 28, 29, 30]]])
print("rank_3_tensor:", rank_3_tensor)
print("the shape of rank_3_tensor:", rank_3_tensor.shape)
# 對數據進行維度修改
rank_3_tensor = paddle.reshape(rank_3_tensor, [2, 5, 3])
print("rank_3_tensor:", rank_3_tensor)
print("After reshape:", rank_3_tensor.shape)
rank_3_tensor: Tensor(shape=[3, 2, 5], dtype=int64, place=CPUPlace, stop_gradient=True,
       [[[1, 2, 3, 4, 5],
         [ 6,  7,  8,  9, 10]],

        [[11, 12, 13, 14, 15],
         [16, 17, 18, 19, 20]],

        [[21, 22, 23, 24, 25],
         [26, 27, 28, 29, 30]]])
the shape of rank_3_tensor: [3, 2, 5]
rank_3_tensor: Tensor(shape=[2, 5, 3], dtype=int64, place=CPUPlace, stop_gradient=True,
       [[[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12],
         [13, 14, 15]],

        [[16, 17, 18],
         [19, 20, 21],
         [22, 23, 24],
         [25, 26, 27],
         [28, 29, 30]]])
After reshape: [2, 5, 3]
  1. -1 表示這個維度的值是從Tensor的元素總數和剩餘維度推斷出來的。所以,有且只有一個維度能夠被設置爲-1。
  2. 0 表示實際的維數是從Tensor的對應維數中複製出來的,所以shape中0的索引值不能超過x的維度。

# reshape爲[-1]時,會將tensor按其在計算機上的內存分佈展平爲1-D Tensor。
print("Tensor flattened to Vector:", paddle.reshape(rank_3_tensor, [-1]).numpy())
Tensor flattened to Vector: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30]

paddle Tensor的dtype

Tensor的數據類型,能夠經過 Tensor.dtype 來查看,dtype支持:‘bool’,‘float16’,‘float32’,‘float64’,‘uint8’,‘int8’,‘int16’,‘int32’,‘int64’。


# 查看rank_3_tensor的類型
rank_3_tensor.dtype
VarType.INT64

dtype類型的指定

經過Python元素建立的Tensor,能夠經過dtype來進行指定,若是未指定:

對於python整型數據,則會建立int64型Tensor

對於python浮點型數據,默認會建立float32型Tensor

若是對浮點型默認的類型進行修改可使用set_default_type進行調整

經過Numpy array建立的Tensor,則與其原來的dtype保持相同。

改變dtype(類型)

paddle一樣提供了接口改變類型,能夠更好的同於「實戰」

# 生成一個浮點型32位的張量
float32_tensor = paddle.to_tensor(1.0)
print('float32_tensor', float32_tensor.dtype)
# 轉換成浮點型64位
float64_tensor = paddle.cast(float32_tensor, dtype='float64')
print("Tensor after cast to float64:", float64_tensor.dtype)
# 轉換成整型64位
int64_tensor = paddle.cast(float32_tensor, dtype='int64')
print("Tensor after cast to int64:", int64_tensor.dtype)
float32_tensor VarType.FP32
Tensor after cast to float64: VarType.FP64
Tensor after cast to int64: VarType.INT64

Tensor的place

初始化Tensor時能夠經過place來指定其分配的設備位置,可支持的設備位置有三種:CPU/GPU/固定內存

其中固定內存也稱爲不可分頁內存或鎖頁內存,其與GPU之間具備更高的讀寫效率,而且支持異步傳輸,這對網絡總體性能會有進一步提高,但其缺點是分配空間過多時可能會下降主機系統的性能,由於其減小了用於存儲虛擬內存數據的可分頁內存。

# 建立CPU上的Tensor
cpu_tensor = paddle.to_tensor(1, place=paddle.CPUPlace())
print(cpu_tensor)
Tensor(shape=[1], dtype=int64, place=CPUPlace, stop_gradient=True,
       [1])

 

# 建立GPU上的Tensor
gpu_tensor = paddle.to_tensor(1, place=paddle.CUDAPlace(0))
print(gpu_tensor)
# 建立固定內存上的Tensor
pin_memory_tensor = paddle.to_tensor(1, place=paddle.CUDAPinnedPlace())
ory_tensor = paddle.to_tensor(1, place=paddle.CUDAPinnedPlace())
print(pin_memory_tensor)

好了還有內容就下次吧!

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

預告 白話paddle2.0-re—Tensor的……

這裏是三歲,就到這裏了,下次見!

本文同步分享在 博客「三歲學編程」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索