AIFramework基本概念整理
AIFramework基本概念整理
本文介紹:
? 對天元 MegEngine 框架中的 Tensor, Operator, GradManager 等基本概念有一定的了解;
? 對深度學習中的前向傳播、反向傳播和參數更新的具體過程有更加清晰的認識;
? 通過寫代碼訓練一個線性回歸模型,對上面提到的這些概念進行具體的實踐,加深理解。
請先運行下面的代碼,檢驗環境中是否已經安裝好 MegEngine(訪問官網安裝教程):
[1]:
import megengine
print(megengine.version)
1.3.1
或者可以前往 MegStudio fork 公開項目,無需本地安裝,直接線上體驗(開始學習)
接下來,將學習框架中一些基本模塊的使用,先從最基礎的張量(Tensor)和算子(Operator)開始吧~
張量(Tensor)
真實世界中的很多非結構化的數據,如文字、圖片、音頻、視頻等,都可以表達成更容易被計算機理解的形式。
MegEngine 使用張量(Tensor)來表示數據。類似于 NumPy 中的多維數組(ndarray),張量可以是標量、向量、矩陣或者多維數組。 在 MegEngine 中得到一個 Tensor 的方式有很多:
? 可以通過 megengine.functional.tensor 的 arange(), ones() 等方法來生成 Tensor,functional 模塊會在后面介紹;
? 也可以通過 Tensor() 或 tensor() 方法,傳入 Python list 或者 ndarray 來創建一個 Tensor
[2]:
import numpy as np
import megengine as mge # 習慣將 MegEngine 縮寫為 mge
import megengine.functional as F # 習慣將 functional 縮寫為 F
1. 生成 Python List,然后轉化為 MegEngine Tensor
py_list = range(5)
print(mge.tensor(py_list))
2. 生成 Numpy ndarray,然后轉化為 MegEngine Tensor
np_ndarray = np.arange(5).astype(“float32”)
print(mge.tensor(np_ndarray))
3. 使用 functional 模塊直接生成 MegEngine Tensor
mge_tensor = F.arange(5)
print(mge_tensor)
Tensor([0 1 2 3 4], dtype=int32, device=xpux:0)
Tensor([0. 1. 2. 3. 4.], device=xpux:0)
Tensor([0. 1. 2. 3. 4.], device=xpux:0)
通過 dtype 屬性可以獲取 Tensor 的數據類型,默認為 float32:
? 為了方便,統一使用 NumPy 的 dtype 表示;
? 使用 type() 可以獲取實際的類型,用來區分 ndarray 和 Tensor
[3]:
print(mge_tensor.dtype)
print(type(mge_tensor))
<class ‘numpy.float32’>
<class ‘megengine.tensor.Tensor’>
通過 astype() 方法可以拷貝創建一個指定數據類型的新 Tensor ,原 Tensor 不變:
? MegEngine Tensor 目前不支持轉化成 float64 類型;
? float64 類型的 ndarray 轉化成 Tensor 時會變成 float32 類型
[4]:
new_tensor = mge_tensor.astype(“float16”)
print(new_tensor)
Tensor([0. 1. 2. 3. 4.], dtype=float16, device=xpux:0)
通過 device 屬性,可以獲取 Tensor 當前所在的設備:
? 一般地,如果在創建 Tensor 時不指定 device,其 device 屬性默認為 xpux,表示當前任意一個可用的設備;
? 在 GPU 和 CPU 同時存在時,MegEngine 將自動使用 GPU 作為默認設備進行訓練 .
? 如果需要查詢 Tensor 所在設備,可以使用 Tensor.device ;
? 如果需要改變 Tensor 所在設備,可以使用 Tensor.to 或 functional.copy .
通過 Tensor 自帶的 numpy() 方法,可以拷貝 Tensor 并轉化對應的 ndarray,原 Tensor 不變::
[5]:
print(type(mge_tensor.numpy()))
<class ‘numpy.ndarray’>
可以發現,不同類型之間的轉化比較靈活,但需要注意:
? MegEngine Tensor 沒有 mge.numpy(mge_tensor) 這種用法;
? tensor 是 Tensor 的一個別名(Alias),也可以嘗試直接這樣導入:
[6]:
from megengine import tensor
from megengine import Tensor
print(tensor([1, 2, 3])) # 實際上更希望使用 float32 類型的 Tensor
print(Tensor([1., 2., 3.])) # 因此會習慣性地加上一個點表示這是浮點數
Tensor([1 2 3], dtype=int32, device=xpux:0)
Tensor([1. 2. 3.], device=xpux:0)
通過 shape 屬性,可以獲取 Tensor 的形狀:
[7]:
matrix_tensor = mge.tensor([[1., 2., 3.],
[4., 5., 6.]])
print(matrix_tensor.shape)
(2, 3)
通過 size 屬性,可以獲取 Tensor 中元素的個數:
[8]:
print(matrix_tensor.size) # 2 * 3 = 6
6
通過 item() 方法,可以獲得對應的 Python 標量對象:
[9]:
a = mge.tensor([[5.]]) # 可以多維,但必須確保其中只有一個元素,即 size 為 1
print(a.item(), type(a.item()))
5.0 <class ‘float’>
算子(Operator)
MegEngine 中通過算子 (Operator) 來表示運算。MegEngine 中的算子支持基于 Tensor 的常見數學運算和操作。 比如 Tensor 的元素間(Element-wise)加法、減法和乘法:
[10]:
A = mge.tensor([[2., 4., 2.],
[2., 4., 2.]])
B = mge.tensor([[1., 2., 1.],
[1., 2., 1.]])
print(A + B)
print(A - B)
print(A * B)
print(A / B)
Tensor([[3. 6. 3.]
[3. 6. 3.]], device=xpux:0)
Tensor([[1. 2. 1.]
[1. 2. 1.]], device=xpux:0)
Tensor([[2. 8. 2.]
[2. 8. 2.]], device=xpux:0)
Tensor([[2. 2. 2.]
[2. 2. 2.]], device=xpux:0)
也可以使用 MegEngine 中的 functional 模塊中的各種方法來完成對應計算:
[11]:
import megengine.functional as F
print(F.add(A, B))
print(F.sub(A, B))
print(F.mul(A, B))
print(F.div(A, B))
Tensor([[3. 6. 3.]
[3. 6. 3.]], device=xpux:0)
Tensor([[1. 2. 1.]
[1. 2. 1.]], device=xpux:0)
Tensor([[2. 8. 2.]
[2. 8. 2.]], device=xpux:0)
Tensor([[2. 2. 2.]
[2. 2. 2.]], device=xpux:0)
Tensor 支持 Python 中常見的切片(Slicing)操作:
[12]:
A = mge.tensor([[1., 2., 3.],
[4., 5., 6.]])
print(A[1, :2])
Tensor([4. 5.], device=xpux:0)
使用 reshape() 方法,可以得到修改形狀后的 Tensor:
[13]:
A = mge.tensor([[1., 2., 3.],
[4., 5., 6.]])
print(A.shape)
A = A.reshape(3, 2)
print(A.shape)
(2, 3)
(3, 2)
另外, reshape() 方法的參數允許存在單個維度的缺省值,用 -1 表示。
此時,reshape() 會自動推理該維度的值:
[14]:
A = mge.tensor(np.random.random((2, 3, 4, 5)))
print(A.shape)
A = A.reshape(2, -1, 5)
print(A.shape)
(2, 3, 4, 5)
(2, 12, 5)
在 functional 模塊中提供了更多的算子,比如 Tensor 的矩陣乘可以使用 matmul() 方法:
[15]:
x = mge.tensor([[1., 3., 5.],
[2., 4., 6.]])
w = mge.tensor([[1., 2.],
[3., 4.],
[5., 6.]])
p = F.matmul(x, w)
print§
Tensor([[35. 44.]
[44. 56.]], device=xpux:0)
可以使用 NumPy 的矩陣乘來驗證一下這個結果:
[16]:
import numpy as np
x = np.array([[1., 3., 5.],
[2., 4., 6.]])
w = np.array([[1., 2.],
[3., 4.],
[5., 6.]])
p = np.matmul(x, w)
print§
[[35. 44.]
[44. 56.]]
更多算子可以參考 functional 模塊的 文檔 部分。
現在可以適當休息一下,腦海中回想一下張量(Tensor)和算子(Operator)的概念,然后繼續閱讀教程后面的部分。
計算圖(Computing Graph)
MegEngine 是基于計算圖(Computing Graph)的深度神經網絡學習框架,下面通過一個簡單的數學表達式 y=(w?x)+b 來介紹計算圖的基本概念,如下圖所示:
計算之間的各種流程依賴關系可以構成一張計算圖,從中可以看到,計算圖中存在:
? 數據節點(圖中的實心圈):如輸入數據 x、參數 w 和 b,運算得到的中間數據 p,以及最終的輸出 y;
? 計算節點(圖中的空心圈):圖中 ? 和 + 分別表示計算節點 乘法 和 加法,是施加在數據節點上的運算;
? 邊(圖中的箭頭):表示數據的流向,體現了數據節點和計算節點之間的依賴關系
在深度學習領域,任何復雜的深度神經網絡模型本質上都可以用一個計算圖表示出來。
MegEngine 用張量(Tensor)表示計算圖中的數據節點,用算子(Operator)實現數據節點之間的運算。
可以理解成,神經網絡模型的訓練其實就是在重復以下過程:
? 前向傳播:計算由計算圖表示的數學表達式的值的過程。在上圖中則是:
? 輸入 x 和參數 w 首先經過乘法運算得到中間結果 p,
? 接著 p 和參數 b 經過加法運算,得到右側最終的輸出 y,這就是一個完整的前向傳播過程。
? 反向傳播:根據需要優化的目標(假設這里就為 y),通過鏈式求導法則,對所有的參數求梯度。在上圖中,即計算 ?y?w 和 ?y?b.
? 參數更新:得到梯度后,需要使用梯度下降法(Gradient Descent)對參數做更新,從而達到模型優化的效果。在上圖中,即對 w 和 b 做更新。
模型訓練完成后便可用于測試(或者說推理),此時不需要再對模型本身做任何更改,只需要將數據經過前向傳播得到對應的輸出即可。
鏈式法則計算梯度
例如,為了得到上圖中 y 關于參數 w 的梯度,反向傳播的過程如下圖所示:
? 首先 y=p+b,因此 ?y?p=1
? 接著,反向追溯,p=w?x ,因此,?p?w=x
? 根據鏈式求導法則,?y?w=?y?p??p?w=1?x
? 因此最終 y 關于參數 w 的梯度為 x.
求導器(GradManager)
推導梯度是件枯燥的事情,尤其是當模型的前向傳播計算輸出的過程變得相對復雜時,根據鏈式法則計算梯度會變得異常枯燥無味。 自動求導是深度學習框架對使用者而言最有用的特性之一,它自動地完成了反向傳播過程中根據鏈式法則去推導參數梯度的過程。
MegEngine 的 autodiff 模塊為計算圖中的張量提供了自動求導功能,繼續以上圖的例子進行說明:
[17]:
from megengine.autodiff import GradManager
w = mge.tensor([3.])
x = mge.tensor([2.])
b = mge.tensor(-1.)
gm = GradManager().attach([w, b]) # 新建一個求導器,綁定需要求導的變量,實例通常習慣寫成 gm
with gm: # 開始記錄計算圖
p = F.mul(w, x)
y = p + b
gm.backward(y) # 計算 y 關于參數的導數,過程中不斷地使用鏈式法則
print(w.grad) # 得到結果為 x
print(b.grad) # 得到結果為 1
Tensor([2.], device=xpux:0)
Tensor(1.0, device=xpux:0)
? 可以看到,求出的梯度本身也是 Tensor,GradManager 負責管理和計算梯度(在默認情況下,Tensor 是不需要計算梯度的)。
? 可以使用 attach() 來綁定需要計算梯度的變量(綁定后可使用 detach() 將其取消綁定),使用 backward() 進行梯度的計算。
上面 with 代碼段中的前向運算都會被求導器記錄,有關求導器的原理,可以查看 GradManager 文檔了解細節。
優化器(Optimizer)
應該注意到了,使用參數(Parameter)來稱呼張量(Tensor)w 和 b, 因為與輸入 x 不同,計算圖中的 w 和 b 是需要進行更新/優化的變量。MegEngine 中使用 Parameter 來表示參數(注意沒有小寫形式),Parameter 是 Tensor 的子類,其對象(即網絡參數)可以被優化器更新。
顯然,GradManager 支持對于 Parameter 的梯度計算:
[18]:
w = mge.Parameter([3.])
x = mge.Tensor([2.])
b = mge.Parameter(-1.)
print(type(w))
print(type(b))
gm = GradManager().attach([w, b]) # 這次 attach() 傳入的是 Parameter 而不是 Tensor
with gm:
p = F.mul(w, x)
y = p + b
gm.backward(y)
print(type(w.grad)) # 計算得到的梯度依然是 Tensor
<class ‘megengine.tensor.Parameter’>
<class ‘megengine.tensor.Parameter’>
<class ‘megengine.tensor.Tensor’>
前向傳播和反向傳播的過程完成后,得到了參數對應需要更新的梯度,如 w 相對于輸出 y 的梯度 w.grad.
根據梯度下降的思想,參數 w 的更新規則為:w = w - lr * w.grad, 其中 lr 是學習率(Learning Rate),控制參數更新速度。
P.S: 類似學習率這種,訓練前人為進行設定的,而非由模型學得的參數,通常被稱為超參數(Hyperparameter)。
MegEngine 的 Optimizer 模塊提供了基于各種常見優化策略的優化器,如 Adam 和 SGD 等。
它們都繼承自 Optimizer 基類,主要包含參數梯度的清空 clear_grad() 和參數更新 step() 這兩個方法:
[19]:
import megengine.optimizer as optim # 習慣將 optimizer 縮寫為 optim
optimizer = optim.SGD([w, b], lr=0.01) # 實例化隨機梯度下降(SGD)優化器,傳入 Parameter w 和 b
optimizer.step() # 更新參數值 w = w - lr * w.grad
optimizer.clear_grad() # 將參數的梯度清空,節省內存,以便下一次計算,w.grad 變為 None
print(w, w.grad)
Parameter([2.98], device=xpux:0) None
提示:多次實踐表明,用戶經常忘記在更新參數后做梯度清空操作,因此推薦使用這樣的寫法:optimizer.step().clear_grad()
使用 Numpy 來手動模擬一次參數 w 的更新過程:
[20]:
w = np.array([3.])
dw = np.array([2.]) # 前面已經計算出了 w.grad = x, 這里用 dw 表示
lr = 0.01
w = w - lr * dw
print(w) # 和 optimizer.step() 更新后得到的 w 應該一致
[2.98]
這樣便成功地進行了一次參數更新,在實際訓練模型時,參數的更新會迭代進行很多次,迭代次數 epochs 也是一種超參數,需要人為設定。
損失函數(Loss Function)
深度神經網絡模型的優化過程,實際上就是使用梯度下降算法來優化一個目標函數,從而更新網絡模型中的參數。
但請注意,上面用于舉例的表達式的輸出值其實并不是需要被優化的對象,目標是:模型預測的輸出結果和真實標簽盡可能一致。
已經知道了,通過前向傳播可以得到模型預測的輸出,此時用 損失函數(Loss Function) 來度量模型輸出與真實結果之間的差距。
MegEngine 的 functional 模塊提供了各種常見的損失函數,具體可見 文檔 中的 loss 部分。
對于 w?x+b 這樣的范圍在實數域 R 上的輸出,可以使用均方誤差(Mean Squared Error, MSE)表示模型輸出 ypred 和實際值 yreal 的差距:
?(ypred,yreal)=1n∑i=1n(y^i?yi)2
注:在上面的公式中 (y^i?yi)2 計算的是單個樣本 xi 輸入模型后得到的輸出 y^i 和實際標簽值 yi 的差異,數據集中有 n 個樣本。
[21]:
import megengine.functional as F
pred = np.array([3, 3, 3, 3]).astype(np.float32)
real = np.array([2, 8, 6, 1]).astype(np.float32)
loss = np.mean((pred - real) ** 2) # 根據公式定義計算
print(loss)
loss = F.loss.square_loss(pred, real) # MegEngine 中的實現
print(loss)
9.75
9.75
選定損失函數作為優化目標后,便可在訓練的過程中通過梯度下降不斷地更新參數 w 和 b, 從而達到模型優化的效果:
w?,b?=argminw,b?(w,b).
練習:線性回歸
接下來,用一個非常簡單的例子,幫助將前面提到的概念給聯系起來。
假設有人提供給一些包含數據 data 和標簽 label 的樣本集合 S 用于訓練模型,希望將來給出輸入 x, 模型能對輸出 y 進行較好地預測:
data=[x1,x2,…,xn]label=[y1,y2,…,yn]S={(x1,y1),(x2,y2),…(xn,yn)}
請運行下面的代碼以隨機生成包含 data 和 label 的樣本:
[22]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
def generate_random_examples(n=100, noise=5):
w = np.random.randint(5, 10)
b = np.random.randint(-10, 10)
print("The real w: {}, b: {}".format(w, b))# 初始化 data 和 label
data = np.zeros((n,))
label = np.zeros((n,))# 生成 n 個隨機樣本數據,并添加一定的噪聲干擾
for i in range(n):data[i] = np.random.uniform(-10, 10)label[i] = w * data[i] + b + np.random.uniform(-noise, noise)plt.scatter(data[i], label[i], marker=".") # 將樣本點繪制在坐標圖上# 展示樣本數據的分布
plt.plot()
plt.show()
return data, label
original_data, original_label = generate_random_examples()
The real w: 9, b: 0
通過可視化觀察樣本的分布規律,不難發現,可以:
- 嘗試擬合 y=w?x+b 這樣一個線性模型(均為標量);
- 選擇使用均方誤差損失作為優化目標;
- 通過梯度下降法來更新參數 w 和 b.
Numpy 實現
對于這種非常簡單的模型,完全可以使用 Numpy 進行算法實現,借此了解一下整個模型訓練的流程:
[23]:
設置超參數
epochs = 5
lr = 0.01
獲取數據
data = original_data
label = original_label
n = len(data)
參數初始化
w = 0
b = 0
定義模型
def linear_model(x):
return w * x + b
模型訓練
for epoch in range(epochs):
# 初始化單個 epoch 訓練得到的損失
loss = 0# 梯度初始化,等同于 Optimizer 中的 clear_grad()
sum_grad_w = 0
sum_grad_b = 0# 為了方便理解,這里沒有使用 “向量化實現”,而是使用了 for 循環寫法
for i in range(n):# 前向傳播,主要計算預測值 pred 以及損失值 losspred = linear_model(data[i]) # 通常 pred 為將 data 代入 “模型” 得到的輸出,即 model(data)loss += (pred - label[i]) ** 2 # 等同于對每個樣本使用 F.nn.loss(pred, label) 計算后求和# 反向傳播,根據均方誤差損失計算參數的梯度,這里不解釋推導過程,等同于 gm.backward()sum_grad_w += 2 * (pred - label[i]) * data[i]sum_grad_b += 2 * (pred - label[i])# 計算平均損失,因為對于不同的輸入,求得的損失都會不同,所以通常求和后取平均
loss = loss / n# 計算平均梯度,因為對于不同的輸入,求得的梯度都會不同,所以通常求和后取平均
grad_w = sum_grad_w / n
grad_b = sum_grad_b / n# 更新參數,等同于 Optimizer 中的 step()
w = w - lr * grad_w
b = b - lr * grad_b# 查看參數和損失
print("epoch = {}, w = {:.3f}, b = {:.3f}, loss = {:.3f}".format(epoch, w, b, loss))# 繪圖查看擬合情況
x = np.array([-10, 10])
y = w * x + b
plt.scatter(data, label, marker=".")
plt.plot(x, y, "-b")
plt.show()
epoch = 0, w = 5.965, b = -0.004, loss = 2702.561
epoch = 1, w = 7.992, b = -0.007, loss = 318.817
epoch = 2, w = 8.680, b = -0.009, loss = 43.688
epoch = 3, w = 8.914, b = -0.011, loss = 11.933
epoch = 4, w = 8.994, b = -0.012, loss = 8.268
可以看到,在 5 個 epoch 的迭代訓練中,已經得到了一個擬合狀況不錯的線性模型。
MegEngine 實現
上面的流程,完全可以使用 MegEngine 來實現(有興趣的讀者可以參照上面的注釋,先嘗試自己實現):
[24]:
import megengine as mge
import megengine.functional as F
from megengine.autodiff import GradManager
import megengine.optimizer as optim
設置超參數
epochs = 5
lr = 0.01
獲取數據
data = mge.tensor(original_data)
label = mge.tensor(original_label)
初始化參數
w = mge.Parameter([0.0])
b = mge.Parameter([0.0])
定義模型
def linear_model(x):
return F.mul(w, x) + b
定義求導器和優化器
gm = GradManager().attach([w, b])
optimizer = optim.SGD([w, b], lr=lr)
模型訓練
for epoch in range(epochs):
with gm:
pred = linear_model(data)
loss = F.loss.square_loss(pred, label)
gm.backward(loss)
optimizer.step().clear_grad()
print("epoch = {}, w = {:.3f}, b = {:.3f}, loss = {:.3f}".format(epoch, w.item(), b.item(), loss.item()))
epoch = 0, w = 5.965, b = -0.004, loss = 2702.561
epoch = 1, w = 7.992, b = -0.007, loss = 318.817
epoch = 2, w = 8.680, b = -0.009, loss = 43.688
epoch = 3, w = 8.914, b = -0.011, loss = 11.933
epoch = 4, w = 8.994, b = -0.012, loss = 8.268
應該會得到相同的 w, b 以及 loss 值,下面直線的擬合程度也應該和 Numpy 實現一致:
[25]:
繪圖查看擬合情況
x = np.array([-10, 10])
y = w.numpy() * x + b.numpy()
plt.scatter(data, label, marker=".")
plt.plot(x, y, “-b”)
plt.show()
總結回顧
祝賀完成了入門教程的學習,現在是時候休息一下,做一個簡單的回顧了:
到目前為止,已經掌握了天元 MegEngine 框架中的以下概念:
? 計算圖(Computing Graph):MegEngine 是基于計算圖的框架,計算圖中存在數據節點、計算節點和邊
? 前向傳播:輸入的數據在計算圖中經過計算得到預測值,接著使用損失 loss 表示預測值和實際值的差異
? 反向傳播:根據鏈式法則,得到計算圖中所有參數 w 關于 loss 的梯度 dw ,實現在 autodiff 模塊,由 GradManager 進行管理
? 參數更新:根據梯度下降算法,更新圖中參數,從而達到優化最終 loss 的效果,實現在 optimzer 模塊
? 張量(Tensor):MegEngine 中的基礎數據結構,用來表示計算圖中的數據節點,可以靈活地與 Numpy 數據結構轉化
? 參數(Parameter):用于和張量做概念上的區分,模型優化的過程實際上就是優化器對參數進行了更新
? 超參數(Hype-parameter):其值無法由模型直接經過訓練學得,需要人為(或通過其它方法)設定
? 算子(Operator):基于 Tensor 的各種計算的實現(包括損失函數),實現在 functional 模塊
通過擬合 f(x)=w?x+b 完成了一個最簡單的線性回歸模型的訓練,干得漂亮!
問題思考
MegEngine 打怪升級之旅還沒有結束,在前往下一關之前,嘗試思考一些問題吧。
關于向量化實現:
? 當發現 Python 代碼運行較慢時,通常可以將數據處理移入 NumPy 并采用向量化(Vectorization)寫法,實現最高速度的處理
? 線性模型訓練的 NumPy 寫法中,單個 epoch 訓練內出現了 for 循環,實際上可以采取向量化的實現(參考 MegEngine 實現的寫法)
? 使用向量化的實現,通常計算的效率會更高,因此建議:代碼中能夠用向量化代替 for 循環的地方,就盡可能地使用向量化實現
關于設備:
? 都說 GPU 訓練神經網絡模型速度會比 CPU 訓練快非常多,為什么?
? 可以把 Tensor 指定計算設備為 GPU 或 CPU,而原生 NumPy 只支持 CPU 計算,Tensor 轉化為 ndarray 的過程是什么樣的?
? 訓練的速度是否會受到訓練設備數量的影響呢?可不可以多個設備一起進行訓練?
關于參數與超參數:
? 現在接觸到了兩個超參數 epochs 和 lr, 調整它們的值是否會對模型的訓練產生影響?(不妨自己動手調整試試)
? 更新參數所用的梯度 grad_w,是所有樣本的梯度之和 sum_grad_w 求均值,為什么不在每個樣本反向傳播后立即更新參數 w?
? 看上去得到了一條擬合得很不錯的曲線,但是得到的 b 距離真實的 b 還比較遙遠,為什么?如何解決這種情況?
? 如何選取合適的超參數,對于超參數的選取是否有一定的規律或者經驗可尋?
關于數據集:
? 在線性模型中使用的是從 NumPy 代碼生成的隨機數據,修改數據集的樣本數量 n 和噪聲擾動程度 noise 會有什么影響?
? 對于現實中的數據集,如何轉換成 MegEngine Tensor 的形式進行使用?
? 這中間需要經過什么樣的預處理(Preprocessing)過程,有哪些流程是可以交由框架來完成的?
關于模型:
? 學會了定義了非常簡單的線性模型 linear_model, 更復雜的模型要如何去寫?
? 既然任何神經網絡模型本質上都可以用計算圖來表示,那么神經網絡模型的搭建流程是什么樣的?
關于最佳實踐:
? 在編寫代碼時,經常會有根據前人經驗總結出的最佳實踐(Best Practice)作為參考,例如:
? 參數的更新和梯度的清空可以寫在一起 optimizer.step().clear_grad()
? 在導入某些包的時候,通常有約定俗成的縮寫如 import megengine as mge
? 除此以外,還有什么樣的編程習慣和最佳實踐值得參考?如何將一份玩具代碼整理變成工程化的代碼?
深度學習,簡單開發。鼓勵在實踐中不斷思考,并啟發自己去探索直覺性或理論性的解釋。
總結
以上是生活随笔為你收集整理的AIFramework基本概念整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AICompiler动态shape编译框
- 下一篇: 华为4D成像雷达、智能驾驶平台MDC 8