pytorch(一)張量基礎及通用操作


1.pytorch主要的包:

  • torch: 最頂層包及張量庫
  • torch.nn: 子包,包括模型及建立神經網絡的可拓展類
  • torch.autograd: 支持所有微分操作的函數子包
  • torch.nn.functional: 其他所有函數功能,包括激活函數,卷積操作,構建損失函數等
  • torch.optim: 所有的優化器包,包括adam,sgd等
  • torch.utils.data: 子包,包括所有處理數據更簡便的功能類,如datasets,dataloader等
  • torchvision: 與torch同level的包,包含一些流行的數據集,模型和圖片變換處理方法。

2.檢測安裝環境

torch.cuda.is_available()
True
torch.version.cuda
'10.0'

3.深度學習及神經網絡利用GPU的原因

神經網絡是一個高度並行的計算任務an embarrassingly parallel task :子任務之間互相獨立

4.tensor是什么

tensor就是n維數組,是神經網絡的基本數據結構
scalar/0--->vector/1--->matrix/2--->tensor/n
只有在二階的數據中才存在row-行和collum-列的概念

5.tensor的階(維度),軸及shape

  • 維度(階,rank):索引到tensor中一個特定的元素需要的index的數目

  • 軸:指tesor特定的某一個維度,如第2維(shape的每個數字代表一個軸)

假設張量t的第一維(軸)長度為3,第二維(軸)長度為4:

  • 表明沿着第一軸可以索引到3個位置(每個位置是(3,)),t[0],t[1],t[2];

  • 沿第二周軸可以索引到3*4=12個位置(每個位置是(1,)---最后一個軸索引出的是一個元素),t[0][0],t[0][1],t[0][2],t[0][3],......

  • shape: 每個軸的長度,因此shape可以表達張量的元素總數。shape至關重要:編碼了張量所有相關的信息,包括維度,軸,索引。
    shape: (3,4)--->第一軸長度為3,第二周長度為4,共 3*4 = 12 元素

張量shape的內涵:(Numbers of one Batch, Channel, Heigh, Width)

  • N-C-H-W-----Pytorch
  • N-H-W-C-----Tesorflow、Keras
tensor.reshape(a,b)#改變shape不改變數據

6.featuremap

特征圖:指神經網絡中間層的輸出
之所以稱特征圖:因為這些輸出表示圖像一些特征,比如邊緣,紋理等,且這些特征隨着網絡的加深變得更復雜。

7.pytorch的torch的創建

t = torch.Tesnor()
type(t)#torch.Tensor

torch.Tensor有3個屬性

  • torch.deveice :cuda:0, cpu。張量計算必須是在相同device上的數據
  • torch.dtype : float-32,double-64,Half-16
  • torch.layout :數據的存儲方式,涉及到空間局部性。

混合精度計算

1.3及以后版本支持混合精度計算

通過numpy數組創建tensor

data = np.array([1,2,3])
o1 = torch.Tensor(data) #tensor([1.,2.,3.]),float類型
o2 = torch.tensor(data) #tensor([1, 2, 3], dtype=torch.int32)
o3 = torch.as_tensor(data) #tensor([1, 2, 3], dtype=torch.int32)
o4 = torch.from_numpy(data) #tensor([1, 2, 3], dtype=torch.int32)
  1. Copy Data(建模訓練)
  • torch.Tensor(data) 劣勢:創建時無dtype配置選項,強制為float32類型。
  • torch.tensor(data) 優勢:創建時具有dtype配置選項,torch.tensor(data, dtype=torch.float32)。
  1. Share Data(可用於優化代碼性能,這里的共享內存必須滿足相同的device前提)
  • torch.as_tensor(data) 優勢:可以接受多種data輸入方式,如tensor等。(共享對於python內建數據類型如list無效,對於代碼性能影響是模型中有大量的tensor和nunmy數據的來回操作)
  • torch.from_numpy(data) 劣勢:只接受numpy的data輸入

不通過data創建特殊張量類型

torch.eyes([2,2]) #單位陣i
torch.zeros()
torch.ones()
torch.rand() #從[0,1]間的 均勻分布 采樣

8.張量操作(一)之變形reshape/view/squeeze/unsqueeze

.shape == .size() #后者要帶括號

reshape/view: 改變tensor的shape

區別:view接受的必須是data底層存儲連續的tensor,因此前面經常跟一個contiguous(),且數據還是原來的數據。reshape則不需要,且reshape()沒那么可控,執行結果可能是源數據的一個copy,也可能不是。
因此 如果需要copy,用clone();如果需要源數據,用view();reshape()這玩意不好控制,最好少用。

t = torch.tensor([[
    [1,1,1,1],
    [2,2,2,2],
    [3,3,3,3]
], dtype=torch.float32])
t.reshape(1,-1).shape    # (1,12),-1表示按元素個數自動推理 t.numel() = 3*4 = 1*x
t.view(1,-1).size()     # (1,12)
t.view(t.numel())
t.flatten()
t.reshape(-1)  # 以上操作結果相同

def flatten(t):
      t = t.reshape(1,-1)
      return t

Squeeze 和 unsqueeze

print(t.reshape([1,12]))
print(t.reshape([1,12]).shape)
# tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
# torch.Size([1, 12])

t.reshape([1,12]).suqueeze()   #無法指定壓縮維度的位置,只能在第0維
t.reshape([1,12]).squeeze().shape
# tensor([1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.])
# torch.Size([12])

t.reshape([1,12]).squeeze().unsqueeze(dim=0)   #可以指定升維的位置
t.reshape([1,12]).squeeze().unsqueeze(dim=0).shape
# tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
# torch.Size([1, 12])

張量的拼接cat

t1 = torch.tensor([
    [1,2],
    [3,4]])

t2 = torch.tensor([
    [5,6],
    [7,8]])
t = torch.cat((t1,t2),dim = 0)  #在第0軸拼接
# tensor([
    [1,2],
    [3,4],
    [5,6],
    [7,8]
  ])
t = torch.cat((t1,t2),dim = 1) #在第1軸拼接
# tensor([[1, 2, 5, 6],
        [3, 4, 7, 8]])

張量堆疊-stack

#stack與cat的區別:stack堆疊會在**指定位置增加一維**,不指定默認位置是0軸。

a=torch.randn((1,3,4,4)) #[N,c,w,h]
b=torch.stack((a,a))
b.shape
# (2, 1, 3, 4, 4)

c=torch.stack((a,a),1)
c.shape
# (1, 2, 3, 4, 4)

d=torch.stack((a,a),2)
d.shape
# (1, 3, 2, 4, 4)

張量沿特定軸展開,參數 start_dim


t = tensor(
[
    [
        [
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]
        ]
    ],
    [
        [
            [2, 2, 2, 2],
            [2, 2, 2, 2],
            [2, 2, 2, 2],
            [2, 2, 2, 2]
        ]
    ],
    [
        [
            [3, 3, 3, 3],
            [3, 3, 3, 3],
            [3, 3, 3, 3],
            [3, 3, 3, 3]
        ]
    ]
])
t.shape #(3,1,4,4)

t.flatten(start_dim = 1).shape
#tensor(3,16) #看它的沿第幾個軸展開,那么之后的軸(axis = 2, 及 axis = 3)都被展開而消失,張量的階由4降低到4-2=2

t.flatten(start_dim=1)
# tensor(
[
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
    [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
]
)

9.張量操作(二)之算術運算(即逐元素操作 element-wise ops ,也稱point-wise.張量的所有代數操作都是逐元素的)

t1 = torch.tensor([
    [1,2],
    [3,4]
], dtype=torch.float32)

t2 = torch.tensor([
    [9,8],
    [7,6]
], dtype=torch.float32)

t1+t2
t1+2
t1 * 2
t1 / 2

逐點操作的基礎----廣播

t1 = torch.tensor([
    [1,1],
    [1,1]
], dtype=torch.float32)
#shape = (2,2)

t2 = torch.tensor([2,4], dtype=torch.float32)  #shape = (2,)



# t1+t2 ??
np.broadcast_to(t2.numpy(), t1.shape)    # 廣播:第1個參數data,第2個參數shape
# array([[2., 4.],[2., 4.]], dtype=float32)

t1 + t2
tensor([[3., 5.],
        [3., 5.]])



#一些利用廣播的函數舉例
t.abs()
t.sqrt()
t.neg()

10.張量操作(三)之 單個tensor的減少reduction(元素)操作

#普通的張量減少(元素)操作
t.sum() #元素求和
t.numel() #元素總數
t.prod()
t.mean()
t.std()  #標准差
#沿軸減少操作
t = torch.tensor([
    [1,1,1,1],
    [2,2,2,2],
    [3,3,3,3]
], dtype=torch.float32)

t.sum(dim = 0) #tensor([6., 6., 6., 6.])

t.sum(dim = 1) #tensor([4., 8., 12.])
#張量最大值的下標索引 argmax
t = torch.tensor([
    [1,0,0,2],
    [0,3,3,0],
    [4,0,0,5]
], dtype=torch.float32)

t.max() #tensor(5.)

#如果不指定軸argmax索引,會默認是從flatten完全展開后得到的索引下標
t.argmax() #tensor(11)

#指定軸argmax索引時
t.max(dim=0)
# tensor([4., 3., 3., 5.])

t.argmax(dim=0)
# tensor([2, 1, 1, 2])

t.max(dim=1)
# tensor([2., 3., 5.])

t.argmax(dim=1)
# tensor([3, 1, 3])
#獲取張量內的元素
t = torch.tensor([
    [1,2,3],
    [4,5,6],
    [7,8,9]
], dtype=torch.float32)

t.mean()
# tensor(5.)

t.mean().item()  # .item()獲取元素作為scalar
# 5.0

t.mean(dim=0).tolist()  # .tolist()轉變為list
# [4.0, 5.0, 6.0]

t.mean(dim=0).numpy() # tensor--->numpy數組
# array([4., 5., 6.], dtype=float32)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM