寫在前面
本系列博客記錄了作者上手MXNet的全過程。作者在接觸MXNet之前主要使用keras,和一點tensorflow,因此在上手MXNet之前有一點deep learning的項目基礎。主要參考資料爲MXNet官方教程,也閱讀了一些有價值的博客。
博客結構爲:先列出作者對於該階段的期望目標,以及各目標完成過程中的筆記(僅記下個人認爲重要的),再附上學習過程中自己的提問(solved & unsolved,天馬行空的提問,歡迎討論)。
本階段目標
任務 | 預計花時間 | 完成狀態 | 遇到問題 | 補充 |
瞭解MXNet的框架理念與特點 | 1.5hour | https://mxnet-bing.readthedocs.io/en/latest/zh/overview.html#id8 | ||
瞭解MXNet中數據處理格式 | 1.5hour | https://beta.mxnet.io/guide/crash-course/1-ndarray.html | ||
搭建簡單模型 | 5hour | https://beta.mxnet.io/guide/crash-course/2-nn.html | ||
通過與keras等平臺對比,快速加深對MXNet的印象 | 待補充 |
具體筆記
task1 MXNet的特點
- 命令式編程與聲明式編程的結合
命令式編程(imperative programming),嵌入較淺,其中每個語句都按原來的意思執行,例如numpy和Torch
聲明式語言(declarative programming),嵌入較深,既用戶只需要聲明要做什麼,而具體執行則由系統完成。這類系統包括Caffe,theano和剛公佈的TensorFlow
MXNet結合了"Symbol:聲明式的符號表達式"和"NDArray:命令式的張量計算"
- MXNet中幾個庫的使用
名稱 | 用途 |
Symbol | 生成計算圖,符號編程 |
Gluon | |
Module | 模型類,可用於訓練和測試模型 |
task2 NDArray數據
首先需要 from mxnet import nd,mxnet.ndarray與numpy.ndarray相似。
1. 初始化:
from mxnet import nd
a = nd.array([1,2,3])
b = nd.ones((2,3))
c = nd.full((2,3),7) #填充
d = nd.arange(4).reshape((2,2))
2. 運算:
from mxnet import nd
a = nd.array([[1,2,3],[1,2,3],[1,2,3]])
b = nd.ones((3,3))
c = a*b #對應位置乘法
d = nd.dot(a,b) #矩陣相乘
e = nd.maximum(a, c) #求對應位置最大
3. 形狀改變
from mxnet import nd
np.concat
a.reshape
a = mx.nd.array(np.arange(6).reshape(6,1))
b = a.broadcast_to((6,4)) #複製廣播
b.asnumpy()
4. 深拷貝和淺拷貝
b = a.copy() # 深
b = a # 淺。這時修改b也會動a
5. 指定變量在CPU還是GPU上計算
gpu_device=mx.gpu() # Change this to mx.cpu() in absence of GPUs.
a = mx.nd.ones((100,100), mx.cpu())
b = mx.nd.ones((100,100), gpu_device)
6. 讀寫數據
- pickle
import pickle as pkl
import mxnet as mx
a = mx.nd.ones((2, 3))
# pack and then dump into disk
data = pkl.dumps(a) #dumps返回一個序列化的bytes對象,不到文件中去
pkl.dump(data, open('tmp.pickle', 'wb')) #dump到文件
# load from disk and then unpack
data = pkl.load(open('tmp.pickle', 'rb')) #讀取出的data是二進制格式數據
b = pkl.loads(data) #將b從二進制讀取爲正常格式
b.asnumpy()
- save & load (這種方法更好)
通過nd.save和nd.load,寫或讀二進制文件,數據可以和其他語言通用
import mxnet as mx
a = mx.nd.ones((2,3))
b = mx.nd.ones((5,6))
mx.nd.save("temp.ndarray", [a,b])
c = mx.nd.load("temp.ndarray")
task3 搭建模型
1. 生成單層
layer = nn.Dense(2)
2. 生成網絡
\Checkmark
3. 使用類來搭建block(推薦)
將層結構和forward函數分開,可以構建例如dense block\ res block\ vgg block,塊堆疊網絡使用這種結構很方便.
以VGG網絡爲例:
import d2lzh as d2l
from mxnet import gluon, init, nd
from mxnet.gluon import nn
def vgg_block(num_convs, num_channels):
blk = nn.Sequential()
for _ in range(num_convs):
blk.add(nn.Conv2D(num_channels, kernel_size=3,
padding=1, activation='relu'))
blk.add(nn.MaxPool2D(pool_size=2, strides=2))
return blk
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
def vgg(conv_arch):
net = nn.Sequential()
# 卷積層部分
for (num_convs, num_channels) in conv_arch:
net.add(vgg_block(num_convs, num_channels))
# 全連接層部分
net.add(nn.Dense(4096, activation='relu'), nn.Dropout(0.5),
nn.Dense(4096, activation='relu'), nn.Dropout(0.5),
nn.Dense(10))
return net
net = vgg(conv_arch)
task4 和keras對比
問題 | keras | MXNet | 補充 |
模型結構列表打印 |
model.summary() |
print(net) | |
直接獲取網絡中間層weight值 |
layer.weight.data() net.blk[1].weight.data() |
||
畫模型結構圖 | plot_model | ||
爲數據指定是GPU還是CPU |
a = mx.nd.ones((100,100), mx.cpu()) a = mx.nd.ones((100,100), mx.gpu()) |
||
學習過程問題記錄
About | Question | Answer |
torch | torch和pytorch的區別? | |
和keras對比 | 有沒有類似於keras中net.summary()的函數? | |
python |
super(MixMLP, self).__init__(**kwargs) super函數? |
|
python中類的多繼承? | 一個類同時繼承多個類的特徵 | |
pickle | load和loads的區別、dump和dumps的區別 | |
編程方式 | 命令式編程和聲明式的區別? | |
Symbol聲明式和NDArray命令式? |
而
|
|
MXNet | Symbol 和 Gluon的區別? | |
“Symbol API類似於caffe中的網絡配置或者Theano中的符號編程。”怎麼理解? | ||
官方的crash course教程裏,講模型搭建的這一節,第三種方法爲什麼更靈活?爲什麼要設置一個blk然後獲取中間層?不能直接net[4].weight.data()這樣獲取中間層的weight嗎? |
教程中更靈活的意思是在這個類裏面,結構和forward函數分開,這樣在resnet這種有重複性結構的網絡中,容易獲取中間層的輸出? (再想想) |
|
gluon和mxnet的關係?不用gluon的話mxnet能使用嗎? | ||
Apache MXNe什麼意思?加不加前綴的區別? | ||
本階段感想
剛入門MXNet,應該先有一個清晰框架,逐步瞭解遮蓋東西的原理、具體實施以及別的庫的用法。剛看到官方教程的時候腦子有點暈,Symbol\Gluon到底是什麼概念,目前還不清楚。需要結合不同資料自己來提取信息並理解。整理ing
參考資料
- dive into deep learning,基於Apache MXNet對深度學習算法進行實現,內容詳實,代碼實現;中文版《動手學深度學習》
- MXNet官方教程的中文翻譯版本
- github資料,教程、模型以及預訓練weight