pytorch 60分鐘入門

numpy中的ndarray方法和屬性

1 NumPy數組的維數稱爲秩(rank),一維數組的秩爲1,二維數組的秩爲2,以此類推。這個跟線性代數的秩不太一樣。
2 在NumPy中,每一個線性的數組稱爲是一個軸(axes),秩其實是描述軸的數量。比如說,二維數組相當於是一個一維數組,而這個一維數組中每個元素又是一個一維數組。所以這個一維數組就是NumPy中的軸(axes),而軸的數量——秩,就是數組的維數。
3 Numpy庫中的矩陣模塊爲ndarray對象,有很多屬性:T data, dtype, flags, flat, imag, real, size,itemsize,nbytes,ndim,shape,strides,ctypes,base等等。

數組部分

import numpy as np
x=np.array([[1,2,3],[9,8,7],[6,5,4]])
# 打印信息
print(x)
print x.flags  #返回數組內部的信息
x.flat[2:6]   #將數組變爲1維數組,並獲取其中的一部分數據
x.flat = 4; x   #將值賦給1維數組,再轉化成有原有數組的大小形式
# 數組拼接一
# 首先將數組轉成列表,然後利用列表的拼接函數append()、extend()等進行拼接處理,最後將列表轉成數組。
# 通過list函數來強行轉換一下
a_list.extend(b_list)
# 數組拼接二
# numpy提供了numpy.append(arr, values, axis=None)函數。對於參數規定,要麼一個數組和一個數值;要麼兩個數組,不能三個及以上數組直接append拼接。
a=np.arange(5)
np.append(a,10)
b=np.array([11,22,33])

# 要進行賦值,否則將不進行更改
# numpy的數組沒有動態改變大小的功能,numpy.append()函數每次都會重新分配整個數組,並把原來的數組複製到新數組中。
np.append(a,b)
# 數組拼接三
# 思路:numpy提供了numpy.concatenate((a1,a2,...), axis=0)函數。能夠一次完成多個數組的拼接。其中a1,a2,...是數組類型的參數
a=np.array([1,2,3])
b=np.array([11,22,33])
c=np.array([44,55,66])
np.concatenate((a,b,c),axis=0) ## 默認情況下,axis=0可以不寫
np.concatenate((a,b),axis=1)  #axis=1表示對應行的數組進行拼接
# concatenate()效率更高,適合大規模的數據拼接

flags的信息
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False

ndarray部分

x=np.arange(10)  #隨機生成一個數組,並重新命名一個空間的數組
x.reshape(2,5)	#改變維度
x.size   #獲得數組中元素的個數
x.shape  #獲得數組的(行數,列數)
x.reshape(5,2) #重新改變維度
x.base   #獲得該數組基於另外一個對象數組而來,如下,y是根據x而來
x.ndim  #獲得數組的維數

Ndarray對象的方法

# numpy生成的就是ndarray
ndarray.ptp(axis=None, out=None) : 返回數組的最大值—最小值或者某軸的最大值—最小值
ndarray.clip(a_min, a_max, out=None) : 小於最小值的元素賦值爲最小值,大於最大值的元素變爲最大值。
ndarray.all():如果所有元素都爲真,那麼返回真;否則返回假
ndarray.any():只要有一個元素爲真則返回真
ndarray.swapaxes(axis1, axis2) : 交換兩個軸的元素,如下

array([ [0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])

#這個可以用一下
10
(10,)
y
array([ [0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

torch

# 插入代碼塊
x = torch.empty(5, 3) #初始化5*3的矩陣
x = torch.rand(5, 3) #隨機初始化矩陣
x = torch.zeros(5, 3,) #dtype=torch.long) #創建一個0填充的矩陣,數據類型爲long:
x = torch.tensor([5.5, 3]) #創建tensor並使用現有數據初始化:
x = x.new_ones(5, 3, dtype=torch.double)      # new_* 方法來創建對象
x = torch.randn_like(x, dtype=torch.float)    # 覆蓋 dtype!
print(x.size())
torch.Size([5, 3])
torch.Size# `` 返回值是 tuple類型, 所以它支持tuple類型的所有操作.
# 任何 以``_`` 結尾的操作都會用結果替換原變量. 例如: ``x.copy_(y)``, ``x.t_()``, 都會改變 ``x``.
# 你可以使用與NumPy索引方式相同的操作來進行對張量的操作
print(x[:, 1])
torch.view#: 可以改變張量的維度和大小
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  #  size -1 從其他維度推斷
# 譯者注:torch.view 與Numpy的reshape類似
# 如果你有隻有一個元素的張量,使用.item()來得到Python數據類型的數值

NumPy 轉換

1 將一個Torch Tensor轉換爲NumPy數組是一件輕鬆的事,反之亦然。Torch Tensor與NumPy數組共享底層內存地址,修改一個會導致另一個的變化。
將一個Torch Tensor轉換爲NumPy數組
a = torch.ones(5)
b = a.numpy()
a.add_(1)
輸出都是2
2 NumPy Array 轉化成 Torch Tensor

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)

CUDA 張量

1 使用.to 方法 可以將Tensor移動到任何設備中

# is_available 函數判斷是否有cuda可以使用
# ``torch.device``將張量移動到指定的設備中
if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA 設備對象
    y = torch.ones_like(x, device=device)  # 直接從GPU創建張量
    x = x.to(device)                       # 或者直接使用``.to("cuda")``將張量移動到cuda中
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # ``.to`` 也會對變量的類型做更改

Autograd: 自動求導機制

1 autograd包爲張量上的所有操作提供了自動求導。 它是一個在運行時定義的框架,這意味着反向傳播是根據你的代碼來確定如何運行,並且每次迭代可以是不同的。
2 torch.Tensor是這個包的核心類。如果設置 .requires_grad 爲 True,那麼將會追蹤所有對於該張量的操作。 當完成計算後通過調用 .backward(),自動計算所有的梯度, 這個張量的所有梯度將會自動積累到 .grad 屬性。
3 要阻止張量跟蹤歷史記錄,可以調用**.detach()方法將其與計算曆史記錄分離,並禁止跟蹤它將來的計算記錄。
4 Tensor 和 Function互相連接並生成一個非循環圖,它表示和存儲了完整的計算曆史。 每個張量都有一個
.grad_fn屬性,這個屬性引用了一個創建了Tensor的Function(除非這個張量是用戶手動創建的,即,這個張量的 grad_fn 是 None)。
5 如果需要計算導數,你可以在Tensor上調用
.backward()**。 如果Tensor是一個標量(即它包含一個元素數據)則不需要爲backward()指定任何參數, 但是如果它有更多的元素,你需要指定一個gradient 參數來匹配張量的形狀
.requires_grad_( … ) 可以改變現有張量的 requires_grad屬性。 如果沒 有指定的話,默認輸入的flag是 False。

梯度

1 反向傳播 因爲 out是一個純量(scalar),out.backward() 等於out.backward(torch.tensor(1))。

np.mean(x==y)#返回條件成立的佔比
Out[5]: 0.59999999999999998
np.mean(x)#均值
Out[6]: 3.0

x = torch.randn(3, requires_grad=True)
print(x)
y = x * 2
print(y.data)   #求值
while y.data.norm() < 1000:   # p的範數  括號未寫內容默認爲求2範數,關於範數的解釋見下面代碼
    y = y * 2 
print(y)

範數(norm)是數學中的一種基本概念。在泛函分析中,它定義在賦範線性空間中,並滿足一定的條件,即①非負性;②齊次性;③三角不等式。
#它常常被用來度量某個向量空間(或矩陣)中的每個向量的長度或大小。
#常用的三種p-範數推導出的矩陣範數:
#1-範數:║A║1 = max{ ∑|ai1|,∑|ai2|,……,∑|ain| } (列和範數,A每一列元素絕對值之和的最大值)
#(其中∑|ai1|第一列元素絕對值的和∑|ai1|=|a11|+|a21|+…+|an1|,其餘類似);
#2-範數:║A║2 = A的最大奇異值 = (max{ λi(AHA) }) 1/2 (譜範數,即A^HA特徵值λi中最大者λ1的平方根,其中AH爲A的轉置共軛矩陣);
#∞-範數:║A║∞ = max{ ∑|a1j|,∑|a2j|,…,∑|amj| } (行和範數,A每一行元素絕對值之和的最大值)(其中∑|a1j| 爲第一行元素絕對值的和,其餘類似);

2 如果.requires_grad=True但是你又不希望進行autograd的計算, 那麼可以將變量包裹在 with torch.no_grad()中:
grad 計算導數
backward 計算導數

3 autograd function
backward

Neural Networks

神經網絡的典型訓練過程如下:

定義包含一些可學習的參數(或者叫權重)神經網絡模型;
在數據集上迭代;
通過神經網絡處理輸入;
計算損失(輸出結果和正確值的差值大小);
將梯度反向傳播回網絡的參數;
更新網絡的參數,主要使用如下簡單的更新原則: weight = weight - learning_rate * gradient
在這裏插入圖片描述

import torch
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 1 input image channel, 6 output channels, 5x5 square convolution
        # kernel
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # an affine operation: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # Max pooling over a (2, 2) window
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # If the size is a square you can only specify a single number
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:
            num_features *= s
        return num_features


net = Net()
print(net)

代碼解釋

conv2d的功能是:對由多個輸入平面組成的輸入信號進行二維卷積

1
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’)
利用二維卷積,1是batch_size的大小,
Cin 是通道數量也就是6
channel的分類:
最初圖片的樣本是channels,取決於圖片的類型:RGB三通道
卷積完成之後輸出的out_channels 取決於卷積核的數量
卷積核中in_channels,或者是上邊的out_channels,或者是最初的channels
kernel就是卷積核的大小
stride 就是步長,我理解的應該是水平和豎直方向上的步長
通道數量:每個卷積層中卷積核的數量。
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
在這裏插入圖片描述

2 torch.nn.Linear()函數的理解
是用來建立一個單層的網絡
源碼解析:
Linear繼承於nn.Module,內部函數主要有__init__,reset_parameters, forward和extra_repr函數
init(self, in_features, out_features, bias=True)
in_features:前一層網絡神經元的個數
out_features: 該網絡層神經元的個數
以上兩者決定了weight的形狀[out_features , in_features]
bias: 網絡層是否有偏置,默認存在,且維度爲[out_features ],若bias=False,則該網絡層無偏置。
reset_parameters(self)
參數初始化函數
在__init__中調用此函數,權重採用Xvaier initialization 初始化方式初始參數。
forward(self, input)
在Module的__call__函數調用此函數,使得類對象具有函數調用的功能,同過此功能實現pytorch的網絡結構堆疊。
torch.nn.models 是對某種蹭到額封裝,包括網絡結構以及網絡參數和一些操作

3 網絡之間怎麼進行關聯的需要再討論一下

4 forward 函數
取決於 call函數和init函數
https://blog.csdn.net/xu380393916/article/details/97280035
這篇博主講的非常清楚,用代碼告訴你是怎麼運行的
5 Max_pool,Avg_pool
池化函數,減少運算量

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