MXNet學習筆記——0 MXNet概念、數據、模型初建

寫在前面

本系列博客記錄了作者上手MXNet的全過程。作者在接觸MXNet之前主要使用keras,和一點tensorflow,因此在上手MXNet之前有一點deep learning的項目基礎。主要參考資料爲MXNet官方教程,也閱讀了一些有價值的博客。

博客結構爲:先列出作者對於該階段的期望目標,以及各目標完成過程中的筆記(僅記下個人認爲重要的),再附上學習過程中自己的提問(solved & unsolved,天馬行空的提問,歡迎討論)。


本階段目標

任務 預計花時間 完成狀態 遇到問題 補充
瞭解MXNet的框架理念與特點 1.5hour \checkmark   https://mxnet-bing.readthedocs.io/en/latest/zh/overview.html#id8
瞭解MXNet中數據處理格式 1.5hour \checkmark   https://beta.mxnet.io/guide/crash-course/1-ndarray.html
搭建簡單模型 5hour \checkmark   https://beta.mxnet.io/guide/crash-course/2-nn.html
通過與keras等平臺對比,快速加深對MXNet的印象   \checkmark   待補充

具體筆記

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 補充
模型結構列表打印

\checkmark

model.summary()

print(net)  
直接獲取網絡中間層weight值 \times

\checkmark

layer.weight.data()

net.blk[1].weight.data()

 
畫模型結構圖 plot_model    
爲數據指定是GPU還是CPU

\times

\checkmark

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命令式?

SymbolNDArray均爲多維數組提供了類似於c = a + b這樣的計算符

NDArray提供了命令式編程的接口,其中的計算是逐句評估的。

Symbol更加接近聲明式編程,使用時我們需要提前聲明計算,然後才使用數據評估。這類例子包括正則表達式和SQL語句。

 

NDArray的優點:

  • 直截了當的
  • 更易於使用自然語言特性(循環和判別結構等)以及第三方庫(numpy等)
  • 利於一步步進行代碼debug

Symbol的優點:

  • 提供了NDArray中幾乎所有的函數,例如+*sinreshape
  • 利於保存加載和可視化
  • 利於後端進行計算和內存的優化
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

參考資料

  1. dive into deep learning,基於Apache MXNet對深度學習算法進行實現,內容詳實,代碼實現;中文版《動手學深度學習》
  2. MXNet官方教程中文翻譯版本
  3. github資料,教程、模型以及預訓練weight

 

 

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