動手學習深度學習-pytorch最新版

最近大佬們重新對動手學習深度學習進行修改,加入了pytorch實現的方式,今天發佈了最新版,正在完善中,將自己今天的學習筆記記錄在此,由於全英文的內容,自己翻譯可能不太對,請多多指教!

#!H:\pytorch
# -*- coding:utf-8 -*- 
#Author: Tangzhao
#content:pytorch

# 數據操作

# 導入pytorch
import torch
# 多維數組代表多維的數值,一維數組代表一個矢量,二維數組表示一個矩陣,超過兩位的數組我們稱爲張量(tensors)

# 首先我們創建一個以0開頭的行向量,包括12個元素,默認的數據類型爲float,一個新的數組存儲在主存中,並基於cpu的計算
x = torch.arange(12)  # arange(x) 創建一個x以內的張量
print(x)  # tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

# 獲取張量的形狀可以用x.shape
print(x.shape)  # torch.Size([12])

#  total number of elements in an ndarray
print(x.size())

# 改變張量的形狀
x1 = x.reshape((3,4))  # 括號內的數據爲需要得到的數據形狀,第二維可以不用寫,用-1表示,它會默認隨着第一維的變化而變化
print(x1)
"""
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
"""
x2 = x.reshape((3,-1))
print(x2)
"""
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
"""

# 空方法獲取一塊內存並返回一個矩陣,而不必費心更改其任何項的值。這非常高效,但我們必須小心,因爲條目可能取任意值,包括非常大的值!
x3 = torch.empty(2,3)  # 得到的是一個任意的值,可能爲0,也可能爲很大的數
print(x3)
"""
tensor([[0., 0., 0.],
        [0., 0., 0.]])
"""

# want our matrices initialized either with zeros, ones, some other constant
x4 = torch.zeros(2,3,4)
print(x4)
"""
tensor([[[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]],

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

"""

x5 = torch.ones(2,3,4)
print(x5)
"""
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])
"""

# 當我們構造數組作爲神經網絡的參數時,我們通常會隨機初始化它們的值。下面的代碼片段創建了一個具有shape(3,4)的ndarray。
# 它的每個元素都從均值爲0、標準差爲1的標準高斯(正態)分佈中隨機採樣。
x6 = torch.randn(3, 4)
print(x6)
"""
tensor([[ 1.3997,  0.2624,  1.1852,  0.4023],
        [-0.7597,  0.5661,  0.2412,  1.4060],
        [ 0.7833,  0.9949,  0.3957,  0.8672]])
"""

# :我們還可以通過提供包含數值值的Python列表(或列表的列表)來爲所需的ndarray中的每個元素指定確切的值。
# 在這裏,最外層的列表對應於軸0,而內部列表對應於軸1。
x7 = torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(x7)
"""
ensor([[2, 1, 4, 3],
        [1, 2, 3, 4],
        [4, 3, 2, 1]])
"""

# 2、數據操作
# 2.1、加減乘除:對於相同形狀的數據進行四則運算
x = torch.tensor([1.0,2,4,8])
y = torch.tensor([2.0,2,2,2])
print(x + y)
print(x - y)
print(x * y)
print(x / y)
print(x ** y)
"""
tensor([ 3.,  4.,  6., 10.])
tensor([-1.,  0.,  2.,  6.])
tensor([ 2.,  4.,  8., 16.])
tensor([0.5000, 1.0000, 2.0000, 4.0000])
tensor([ 1.,  4., 16., 64.])
"""

# 同樣地可以用於其它計算
print(torch.exp(x))  # tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

# 將數組疊加
x = torch.arange(12,dtype=torch.float32).reshape(3,4)
y = torch.tensor([[2.0,1,4,3],[1,2,3,4],[4,3,2,1]])
print(torch.cat((x,y),dim = 0))  # 在行上將兩個數組組合
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [ 2.,  1.,  4.,  3.],
        [ 1.,  2.,  3.,  4.],
        [ 4.,  3.,  2.,  1.]])
"""
print(torch.cat((x,y),dim = 1))  # 在列上將兩個數組合並
"""
tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],
        [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],
        [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]])
"""

# 判斷兩個張量相等:對於每個元素的位置,如果x和y的元素值相等,則稱兩個張量相等,而且返回1或者True;否則返回0或者false
print(x == y)
"""
tensor([[False,  True, False,  True],
        [False, False, False, False],
        [False, False, False, False]])
"""

# 將張量所有元素相加得到一個輸出值
print(x.sum())  # tensor(66.)

# 2.1.3、廣播機制
# 上面我們講述對形狀相同的ndarray進行操作,當形狀不同時,可以利用廣播機制自動補全成形狀相同的ndarray(虛擬上)
a = torch.arange(3).reshape((3,1))
print(a)
"""
tensor([[0],
        [1],
        [2]])
"""
b = torch.arange(2).reshape((1,2))
print(b)  # tensor([[0, 1]])

# a是3x1的ndarry,b是1x2的ndarry,採用廣播機制進行運算,a擴展列數,b擴展行數
print(a + b)  # 得到的是一個3行2列
"""
tensor([[0, 1],
        [1, 2],
        [2, 3]])

"""

# 2.1.4、索引和切片:語法與python類似
print(x[-1]) # 取出x的最後一行元素
print(x[1:3])  # 取出最後兩行數據
"""
tensor([ 8.,  9., 10., 11.])
tensor([[ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.]])

"""
# 修改x中的元素
x[1,2] = 9
print(x)
"""
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  9.,  7.],
        [ 8.,  9., 10., 11.]])
"""

x[0:2,:] = 12  # 前兩行所有列的元素值置爲12
print(x)
"""
tensor([[12., 12., 12., 12.],
        [12., 12., 12., 12.],
        [ 8.,  9., 10., 11.]])
"""

# 2.1.5、節約存儲
"""
運行操作可能導致爲主機結果分配新內存。例如,如果我們寫入y = x + y,我們將取消引用y曾經指向的ndarray,而不是指向新分配的內存y。
在下面的示例中,我們使用Python的id()函數來演示這一點,該函數爲我們提供了被引用對象在內存中的確切地址。
運行y = y + x後,我們會發現id(y)指向一個不同的位置。這是因爲Python首先計算y + x,爲結果分配新的內存,然後讓y指向內存中的這個新位置。
"""
before = id(y)
y = y+x
print(id(y) == before)  # False
"""
這可能是不可取的,原因有兩個。首先,我們不想總是分配不必要的內存。在機器學習中,我們可能有幾百兆字節的參數,並且每秒鐘更新一次。
通常,我們希望在適當的地方執行這些更新。其次,我們可能指向來自多個變量的相同參數。如果我們沒有及時更新,
其他引用仍然會指向舊的內存位置,這使得我們的部分代碼可能會無意中引用陳舊的參數
"""
# 如果想指定結果到原來的內存,我們可以使用之前的索引來進行替換操作
z = torch.zeros_like(y)
print('id(z):',id(z))
z[:] = x + y
print('id(z):',id(z))
"""
id(z): 2487647073120
id(z): 2487647073120
"""
# 我們可以使用索引和x+= y來實現上述的效果
before = id(x)
x += y
print(id(x) == before)  # True

# 2.1.6、不同數據類型轉換
# numpy轉換爲tensor
a = x.numpy()
b = torch.tensor(a)
print(type(a),type(b))  # <class 'numpy.ndarray'> <class 'torch.Tensor'>

a = torch.tensor([3.5])
print(a, a.item(), float(a), int(a))  # tensor([3.5000]) 3.5 3.5 3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章