1. 程式人生 > 實用技巧 >pytorch入門到專案(三)tensor的概念以及建立

pytorch入門到專案(三)tensor的概念以及建立

二、張量的簡介與建立

2.1張量的概念

  1. 張量的概念:Tensor
    張量是一個多維陣列,它是標量、向量、矩陣的高維拓展

  2. Tensor與Variable
    Variable是torch.autograd(torch.autograd.Variable)中的資料型別,主要用於封裝Tensor
    進行自動求導
    data:被包裝的Tensor
    grad:data的梯度
    grad_fn:建立Tensor的Function,是自動求導的關鍵
    requires_grad:指示是否需要梯度
    is_leaf:指示是否是葉子節點(張量)

  3. Tensor:PyTorch 0.4.0版開始,Variable併入Tensor
    dtype

    :張量的資料型別,如torch.FloatTensor,torch.cuda.FloatTensor

    torch.float32 or torch.float 代表32-bit floating point較為重要,在卷積層的權值和影象預處理後,都預設為32-bit floating point
    torch.int64 or torch.int代表64-bit integer(signed)也是較為重要的,影象的標籤通常用長整型,在計算交叉熵的損失函式時會用到

    shape:張量的形狀,如(64,3,224,224)
    device:張量所在裝置,GPU/CPU,是加速的關鍵
    torch.Tensor


    data,dtype,shape,device這四個與資料相關
    requires_grad,grad,grad_fu,is_leaf這四個與梯度求導相關

2.2張量的建立

2.2.1直接建立
torch.tensor()

功能:從data建立tensor

  • data:資料,可以是list,numpy的ndarray
  • dtype:資料型別,預設與data的一致,比如輸入的data是ndarray,它的資料型別是numpy的64位整型,那tensor也是64位整型
  • device:所在裝置,cuda/cpu
  • requires_grad:是否需要梯度
  • pin_memory:是否存於鎖頁記憶體,這與轉換效率有關,基本行設定為false
    例子:
torch.tensor(
				data,
				dtype=None,
				requires_grad=False,
				pin_memorty=False)

完整程式碼如下

# ===============lesson 1 ==============
arr = np.ones((3, 3))
print("ndarray 的資料型別是{}".format(arr.dtype))
# t = torch.tensor(arr)
t = torch.tensor(arr, device="cuda")//用gpu會比較慢,因為需要將資料從CPU轉到GPU需要耗時
print(t)

顯示如下:

ndarray 的資料型別是 float64
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], device='cuda:0', dtype=torch.float64)//cuda是用GPU,0是GPU的編號
*torch.from_numpy(ndarray)

功能:從numpy建立tensor
注意事項:從torch.form_numpy建立的tensor於原ndarray共享記憶體,當修改其中一個的資料,另外一個也將會被改動。這裡筆者犯了一個錯誤,就是一開始在修改arr的時候,直接將arr= np.array,這樣的話相當於新賦了一個地址給arr,所以t才不會變。因此他們是共享記憶體的

flag = True
# flag = False
if flag:
    arr = np.array([[1,7,3],[4,5,6]])
    t = torch.from_numpy(arr)
    print(arr)
    print(t)

    # 修改arr
    print("修改arr")
    arr[0,0] = 2
    print(arr)
    print(t)

    # 修改t
    print("修改tensor")
    t[0,0]=9
    print(arr)
    print(t)

顯示為

[[1 7 3]
 [4 5 6]]
tensor([[1, 7, 3],
        [4, 5, 6]], dtype=torch.int32)
修改arr
[[2 7 3]
 [4 5 6]]
tensor([[2, 7, 3],
        [4, 5, 6]], dtype=torch.int32)
修改tensor
[[9 7 3]
 [4 5 6]]
tensor([[9, 7, 3],
        [4, 5, 6]], dtype=torch.int32)

Process finished with exit code 0

2.2.2依據數值建立
01torch.zeros()

功能:依size建立全0張量

  • size:張量的形狀,如(3,3)、(3,244,244)
  • out:輸出的張量
  • layout:記憶體中佈局形式,有strided,sparse_coo等,通常我們直接使用預設的strided即可,是稀疏張量的時候用sparse_coo
  • device:所在裝置,gpu/cpu
  • requires_grad:是否需要梯度
    例子:
torch.zeros.(*size,
			out=None,
			dtype=None,
			layout=torch.strided,
			device=None,
			requires_grad=False	)

tips:python中用id()來顯示資料在記憶體中的地址

flag = True
# flag = False
if flag:
    out_t = torch.tensor([1])
    t= torch.zeros([3,3],out=out_t)

    print(t)
    print(out_t)
    print(id(out_t),id(t),id(t)==id(out_t))

輸出內容如下:

tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])
1672141164992 1672141164992 True

即表示out屬性是給一個變數名而已,地址都是一樣的

02torch.zeros_like()

功能:依input形狀建立全0張量

  • input:建立與input同形狀的全0張量
  • dtype:資料型別
  • layout:記憶體中佈局形式
torch.zeros_like(input,
				dtype=None, 
				layout=None,
				device=None,
				requires_grad=False)
03torch.ones()
04torch.ones_like()

功能:依input形狀建立全1張量

  • size:張量的形狀,如(3,3),(3,224,224)
  • dtype:資料型別
  • layout:記憶體中佈局形式
  • device:所在裝置,gpu/cpu
  • requires_grad:是否需要梯度
    例子
torch.ones(*size,   
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
torch.ones_like(input, 
			dtype=None, 
			layout=None, 
			device=None, 
			requires_grad=False)
05torch.full()
06torch.full_like()

功能:依input形狀建立指定資料的張量

  • size:張量的形狀,如(3,3)
  • fill_value:張量的值
    例子
torch.full(size, 
			fill_value, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
flag = True
# flag = False
if flag:

    t= torch.full([3,3],11)

    print(t)

顯示內容如下

tensor([[11, 11, 11],
        [11, 11, 11],
        [11, 11, 11]])

07torch.arange()

功能:建立等差的1維張量
注意事項:數值區間維[start,end)這裡注意是半閉半開的,也就是end是取不到的

  • start:數列的起始值
  • end:數列的結束值
  • step:數列公差,預設為1
torch.arange(start=0, 
			end, 
			step=1, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
flag = True
# flag = False
if flag:
    t= torch.arange(1,11,2)//11是取不到的,半閉半開
    print(t)
tensor([1, 3, 5, 7, 9])//是一維的張量
08torch.linspace()

功能:建立均分的1維張量
注意事項:數值區間為[start,end]//此時是閉合區間

  • start:數列起始值
  • end:數列結束值
  • steps:數列長度
torch.linspace(start, 
				end, 
				steps=100, 
				out=None, 
				dtype=None, 
				layout=torch.strided, 
				device=None, 
				requires_grad=False)
flag = True
# flag = False
if flag:
    t= torch.linspace(1,11,4,dtype=torch.int)
    print(t)
tensor([ 1,  4,  7, 11], dtype=torch.int32)
09torch.logspace()

功能:建立對數均分的1維張量
注意事項:長度為steps,底為base

  • start:數列起始值
  • end:數列結束值
  • steps:數列長度
  • base:對數函式的底,預設為10
torch.logspace(start, 
				end, 
				steps=100, 
				base=10.0, 
				out=None, 
				dtype=None, 
				layout=torch.strided, 
				device=None, 
				requires_grad=False)
10torch.eye()

功能:建立單位對角矩陣(2維張量)
注意事項:預設為方陣

  • n:矩陣行數
  • m:矩陣列數
torch.eye(n, 
			m=None, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
flag = True
# flag = False
if flag:
    t= torch.eye(4)
    print(t)
tensor([[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.],
        [0., 0., 0., 1.]])
2.2.3依據概率建立
01torch.normal()

功能:生成正態分佈(高斯分佈)

  • mean:均值
  • std:標準差
torch.normal(mean, 
			std, 
			out=None)

四種模式

mean為標量,std為標量
mean為標量,std為張量
mean為張量,std為標量
mean為張量,std為張量

torch.normal(mean, 
			std, 
			out=None)
			torch.normal(mean, 
			std, 
			size,
			out=None)
02*torch.randn() *
03*torch.randn_like() *

功能:生成標準正態分佈

  • size : 張量的形狀
torch.randn(*size, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 	
			device=None, 
			requires_grad=False)
flag = True
# flag = False
if flag:
    t1 = torch.arange(1,5,dtype=torch.float)
    t2 = torch.arange(1,5,dtype=torch.float)

    tt=torch.normal(t1,t2)
    print("mean = {}\nstd = {}".format(t1,t2))
    print(tt)

tt是怎麼樣生成的呢?是通過mean=1,std=1生成的0.5543的高斯分佈的值(正態分佈),以此類推

mean = tensor([1., 2., 3., 4.])
std = tensor([1., 2., 3., 4.])
tensor([0.5543, 3.1875, 3.4800, 4.7976])
flag = True
# flag = False
if flag:
    # mean:張量,std:張量
    # t1 = torch.arange(1,5,dtype=torch.float)
    # t2 = torch.arange(1,5,dtype=torch.float)
    # tt = torch.normal(t1, t2)
    # print("mean = {}\nstd = {}".format(t1, t2))
    # print(tt)
    '''
    mean = tensor([1., 2., 3., 4.])
    std = tensor([1., 2., 3., 4.])
    tensor([ 2.8870, -0.8132,  4.5278, -3.5147])
    '''

    # mean:標量,std:標量
    # t1 = 1
    # t2 = 1
    # tt = torch.normal(t1, t2, (4,))# 此時需要加上維數
    # print("mean = {}\nstd = {}".format(t1, t2))
    # print(tt)
    '''        
    mean = 1
    std = 1
    tensor([1.5022, 1.5284, 1.2761, 0.5369])
    '''

    # mean:張量,std:標量
    # t1 = torch.arange(1,5,dtype=torch.float)
    # t2 = 1
    # tt=torch.normal(t1,t2)
    # print("mean = {}\nstd = {}".format(t1,t2))
    # print(tt)
    '''
    mean = tensor([1., 2., 3., 4.])
    std = 1
    tensor([1.0856, 1.3022, 0.3630, 3.4465])
    '''
    # mean:標量,std:張量
    # t1 = 1
    # t2 = torch.arange(1,5,dtype=torch.float)
    # tt=torch.normal(t1,t2)
    # print("mean = {}\nstd = {}".format(t1,t2))
    # print(tt)
    '''
    mean = 1
    std = tensor([1., 2., 3., 4.])
    tensor([1.8799, 2.3412, 5.7135, 8.4491])
    '''
04torch.rand()
05torch.rand_like()

功能:在區間[0, 1)上,生成均勻分佈

06torch.randint ()
07torch.randint_like()

功能:區間[low, high)生成整數均勻分佈

  • size : 張量的形狀
torch.rand(*size, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
torch.randint(low=0, 
			high, 
			size, 
			out=None, 
			dtype=None, 
			layout=torch.strided, 
			device=None, 
			requires_grad=False)
08torch.randperm()

功能:生成生成從0到n-1的隨機排列

  • n : 張量的長度
    經常用來設定亂序的索引
09torch.bernoulli()

功能:以input為概率,生成伯努力分佈
(0-1分佈,兩點分佈)

  • input : 概率值
torch.randperm(n,
				out=None,
				dtype=torch.int64,
				layout=torch.strided,
				device=None,
				requires_grad=False)
torch.bernoulli(input, 
				*, 
				generator=None, 
				out=None)