一文帶你瞭解深度學習的前置預備知識(中)

語言: CN / TW / HK

theme: devui-blue

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第2天,點選檢視活動詳情

在這篇文章中我們主要講解一下 資料的操作 以及 資料預處理

資料操作

為了完成各種操作,我們需要某種方法來儲存和操作資料。一般來說,需要做兩件重要的事情: (1)獲取資料;
(2)在將資料讀入計算機後對其進行處理。

張量建立

在這一小節,我們介紹下 $n$維陣列,也稱為 張量(tensor)。現有的比較流行的深度學習框架(PyTorch 和TensorFlow中為Tensor),這些框架中的張量類可以更好的使用GPU進行加速計算,而且支援自動微分。

張量表示由一個數值組成的陣列,這個陣列可能有多個維度。 - 具有一個軸的張量對應數學上的向量(vector); - 具有兩個軸的張量對應數學上的矩陣(matrix); - 具有兩個軸以上的張量沒有特殊的數學名稱。

1. 張量的建立

張量中的每個值都稱為 張量的元素(element)。

(1)行向量

使用arange建立一個行向量x,這個行向量包含從0開始的前12個整數,它們被預設建立為浮點數。

``` import torch # 使用PyTorch框架,注意匯入名稱寫 torch 而不是pytorch

x = torch.arange(12) x # tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) ``` (2)矩陣

除了向量,我們也可以 使用全0、全1、其他常量或者從特定分佈中隨機取樣的數字 來初始化一個矩陣。例如我們建立一個形狀為(2,3,4)的張量,其中所有元素都設定為0。

``` torch.zeros((2, 3, 4))

執行結果

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.]]])

`` 那麼同樣我們只要使用torch.ones((2,3,4))`就可以建立一個全為1的2維3行4列的矩陣。

2. 張量的訪問以及修改

  • 通過張量的shape屬性來訪問張量的 形狀(沿每個軸的長度)

x.shape # 執行結果為 torch.Size([12])

  • 使用reshape函式改變一個張量的形狀而不改變元素數量和元素值

```

把張量x從形狀為(12,)的行向量轉換為形狀為(3,4)的矩陣。

X = x.reshape(3, 4) print(X)

執行結果

tensor([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])

`` 對於已經指定了行和列的張量,我們也可以在改變的位置放置'-1' ,令張量自動計算維度。使用x.reshape(-1,4)x.reshape(3,-1)來取代x.reshape(3,4)`

  • 通過檢查張量的大小(size)可以得到張量中元素的總數。

print(x.numel) # 12 print(X.numel) # 12 注意:
轉換後的張量雖然被當做一個 3行4列 的矩陣使用,但這個矩陣裡面的值與轉換前的張量是相同的。這裡要重點記憶一下,雖然張量的形狀發生了改變,但其元素值並沒有變。
改變張量的形狀,並不會改變張量的大小。

張量運算

1. 按元素計算
對於任意具有相同形狀的張量,常見的標準算術運算子(+-*/**)都可以被升級為按元素運算。我們可以在同一形狀的任意兩個張量上呼叫按元素操作。

``` x = torch.tensor([1.0, 2, 4, 8]) y = torch.tensor([2, 2, 2, 2]) x + y, x - y, x * y, x / y, 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.])) ``` 2. 線性代數運算(向量點積、矩陣乘法)
對於這部分知識呢,我們在 下一篇文章中 詳細闡述。

3. 張量連結
將多個張量 連結(concatenate)在一起,把它們端對端地疊成一個更大的張量。 我們只需要提供張量列表,並給出沿哪個軸連結。 ``` 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]]) torch.cat((X, Y), dim=0) # 沿行(軸 0) 的長度連結 , 3+3 6行 torch.cat((X, Y), dim=1) # 沿列(軸 1)的長度連結 , 4+4 8列

執行結果

(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.]]), 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.]]))

```

廣播機制

在上面的部分中,我們看到了如何在相同形狀的兩個張量上執行按元素操作。但是在某些情況下,即使形狀不同,我們仍然可以通過呼叫廣播機制(broadcasting mechanism)來執行按元素操作

工作方式如下:首先,通過適當複製元素來擴充套件一個或兩個陣列,以便在轉換之後,兩個張量具有相同的形狀。其次,對生成的陣列執行按元素操作。大多數情況下,沿著陣列中長度為1(列)的軸進行廣播,如下例子:

``` a = torch.arange(3).reshape((3, 1)) b = torch.arange(2).reshape((1, 2)) a, b # 執行結果 (tensor([[0], [1], [2]]), tensor([[0, 1]]))

# 廣播機制
a + b # 矩陣a複製列,矩陣b複製行,然後再按元素相加。

 tensor([[0, 1], 
         [1, 2], 
         [2, 3]])

```

資料預處理

我們前面介紹了處理儲存在張量中資料的各種技術,但是為了能用深度學習來解決現實世界的問題,我們經常是從預處理原始資料開始,而不是從那些準備好的張量格式資料開始。在Python中常用的資料分析工具中,通常使用pandas軟體包,它可以很好的與張量相容。因此,本部分我們主要介紹使用pandas預處理原始資料並將原始資料轉換為張量格式的步驟。

讀取資料集

我們首先建立一個人工資料集,並存儲在csv(逗號分隔值)檔案

``` import os

os.makedirs(os.path.join('..', 'data'), exist_ok=True) data_file = os.path.join('..', 'data', 'student.csv') with open(data_file, 'w') as f: f.write('Age,Marry,Income\n') # 列名 f.write('20,0,10000\n') # 每行表示一個數據樣本 f.write('18,0,8000\n') f.write('NA,1,6000\n') f.write('NA,1,6000\n') ```

處理缺失值

“NaN”項代表缺失值。為了處理缺失的資料,典型的方法包括插值刪除。其中插值用替代值代替缺失值,而刪除則忽略缺失值。

這裡我們使用插值。通過位置索引iloc,將data分成inputsoutputs,其中前者為data的前兩列,後者為data的最後一列。對於inputs中缺少的數值,我們用同一列的均值替換“NaN”項。

``` inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] inputs = inputs.fillna(inputs.mean()) print(inputs)

執行結果

Age Marry 0 20.0 0 1 18.0 0 2 19.0 1 3 19.0 1 ```

轉換為張量

現在inputsoutputs中的所有條目都是數值型別,我們可以將其轉換為張量格式。

``` import torch

X, y = torch.tensor(inputs.values), torch.tensor(outputs.values) X, y ```

總結

資料預處理的方式還有很多,讀者可以查詢下其餘資料瞭解其他的資料預處理技術。下篇我們主要講解一下線性代數的運算知識,可以關注我,帶你瞭解更多知識。