MXNet深度學習實戰》—3.3 Module

      網友投稿 614 2025-04-01

      3.3 Module


      在MXNet框架中,Module是一個高級的封裝模塊,可用來執行通過Symbol模塊定義的網絡模型的訓練,與Module相關的接口介紹都可以參考Module的官方文檔地址:https://mxnet.apache.org/api/python/module/module.html。Module接口提供了許多非常方便的方法用于模型訓練,只需要將準備好的數據、超參數等傳給對應的方法就能啟動訓練。

      在3.2節,我們用Symbol接口定義了一個網絡結構sym,接下來我們將基于這個網絡結構介紹Module模塊,首先來看看如何通過Module模塊執行模型的預測操作。通過mxnet.module.Module()接口初始化一個Module對象,在初始化時需要傳入定義好的網絡結構sym并指定運行環境,這里設置為GPU環境。然后執行Module對象的bind操作,這個bind操作與Symbol模塊中的bind操作類似,目的也是將網絡結構添加到執行器,使得定義的靜態圖能夠真正運行起來,因為這個過程涉及顯存分配,因此需要提供輸入數據和標簽的維度信息才能執行bind操作,讀者可以在命令行通過“$ watch nvidia-smi”命令查看執行bind前后,顯存的變化情況。bind操作中還存在一個重要的參數是for_training,這個參數默認是True,表示接下來要進行的是訓練過程,因為我們這里只需要進行網絡的前向計算操作,因此將該參數設置為False。最后調用Module對象的init_params()方法初始化網絡結構的參數,初始化的方式是可以選擇的,這里采用默認方式,至此,一個可用的網絡結構執行器就初始化完成了。初始化網絡結構執行器的代碼具體如下:

      mod = mx.mod.Module(symbol=sym, context=mx.gpu(0))

      mod.bind(data_shapes=[('data',(8,3,28,28))],

      label_shapes=[('softmax_label',(8,))],

      for_training=False)

      mod.init_params()

      接下來隨機初始化一個4維的輸入數據,該數據的維度需要與初始化Module對象時設定的數據維度相同,然后通過mxnet.io.DataBatch()接口封裝成一個批次數據,之后就可以作為Module對象的forward()方法的輸入了,執行完前向計算后,調用Module對象的get_outputs()方法就能得到模型的輸出結果,具體代碼如下:

      data = mx.nd.random.uniform(0,1,shape=(8,3,28,28))

      mod.forward(mx.io.DataBatch([data]))

      print(mod.get_outputs()[0])

      輸出結果如下,因為輸入數據的批次大小是8,網絡的全連接層輸出節點數是2,因此輸出的維度是8*2:

      [[ 0.50080067? 0.4991993 ]

      [ 0.50148612? 0.49851385]

      [ 0.50103837? 0.4989616 ]

      [ 0.50171131? 0.49828872]

      [ 0.50254387? 0.4974561 ]

      [ 0.50104254? 0.49895743]

      [ 0.50223148? 0.49776852]

      [ 0.49780959? 0.50219035]]

      接下來介紹如何通過Module模塊執行模型的訓練操作,代碼部分與預測操作有較多地方是相似的,具體代碼見代碼清單3-1(本書中的代碼清單都可以在本書的項目代碼地址中找到:https://github.com/miraclewkf/MXNet-Deep-Learning-in-Action),接下來詳細介紹代碼內容。

      1)使用mxnet.io.NDArrayIter()接口初始化得到訓練和驗證數據迭代器,這里為了演示采用隨機初始化的數據,實際應用中要讀取有效的數據,不論讀取的是什么樣的數據,最后都需要封裝成數據迭代器才能提供給模型訓練。

      2)用mxnet.module.Module()接口初始化得到一個Module對象,這一步至少要輸入一個Symbol對象,另外這一步還可以指定訓練環境是CPU還是GPU,這里采用GPU。

      3)調用Module對象的bind()方法將準備好的數據和網絡結構連接到執行器構成一個完整的計算圖。

      4)調用Module對象的init_params()方法初始化網絡的參數,因為前面定義的網絡結構只是一個架子,里面沒有參數,因此需要執行參數初始化。

      5)調用Module對象的init_optimizer()方法初始化優化器,默認采用隨機梯度下降法(stochastic gradient descent,SGD)進行優化。

      6)調用mxnet.metric.create()接口創建評價函數,這里采用的是準確率(accuracy)。

      7)執行5次循環訓練,每次循環都會將所有數據過一遍模型,因此在循環開始處需要執行評價函數的重置操作、數據的初始讀取等操作。

      8)此處的while循環只有在讀取完訓練數據之后才會退出,該循環首先會調用Module對象的forward()方法執行模型的前向計算,這一步就是輸入數據通過每一個網絡層的參數進行計算并得到最后結果。

      9)調用Module對象的backward()方法執行模型的反向傳播計算,這一步將涉及損失函數的計算和梯度的回傳。

      10)調用Module對象的update()方法執行參數更新操作,參數更新的依據就是第9步計算得到的梯度,這樣就完成了一個批次(batch)數據對網絡參數的更新。

      11)調用Module對象的update_metric()方法更新評價函數的計算結果。

      12)讀取下一個批次的數據,這里采用了Python中的try和except語句,表示如果try包含的語句執行出錯,則執行except包含的語句,這里用來標識是否讀取到了數據集的最后一個批次。

      13)調用評價對象的get_name_value()方法并打印此次計算的結果。

      14)調用Module對象的get_params()方法讀取網絡參數,并利用這些參數初始化Module對象了。

      15)調用數據對象的reset()方法進行重置,這樣在下一次循環中就可以從數據的最初始位置開始讀取了。

      代碼清單3-1 通過Module模塊訓練模型

      import mxnet as mx

      import logging

      data = mx.sym.Variable('data')

      conv = mx.sym.Convolution(data=data, num_filter=128, kernel=(3,3), pad=(1,1),

      name='conv1')

      bn = mx.sym.BatchNorm(data=conv, name='bn1')

      relu = mx.sym.Activation(data=bn, act_type='relu', name='relu1')

      pool = mx.sym.Pooling(data=relu, kernel=(2,2), stride=(2,2), pool_type='max',

      name='pool1')

      fc = mx.sym.FullyConnected(data=pool, num_hidden=2, name='fc1')

      sym = mx.sym.SoftmaxOutput(data=fc, name='softmax')

      data = mx.nd.random.uniform(0,1,shape=(1000,3,224,224))

      label = mx.nd.round(mx.nd.random.uniform(0,1,shape=(1000)))

      train_data = mx.io.NDArrayIter(data={'data':data},

      label={'softmax_label':label},

      batch_size=8,

      shuffle=True)

      print(train_data.provide_data)

      print(train_data.provide_label)

      mod = mx.mod.Module(symbol=sym,context=mx.gpu(0))

      mod.bind(data_shapes=train_data.provide_data,

      label_shapes=train_data.provide_label)

      mod.init_params()

      mod.init_optimizer()

      eval_metric = mx.metric.create('acc')

      for epoch in range(5):

      end_of_batch = False

      eval_metric.reset()

      data_iter = iter(train_data)

      next_data_batch = next(data_iter)

      while not end_of_batch:

      data_batch = next_data_batch

      mod.forward(data_batch)

      mod.backward()

      mod.update()

      mod.update_metric(eval_metric, labels=data_batch.label)

      try:

      next_data_batch = next(data_iter)

      mod.prepare(next_data_batch)

      except StopIteration:

      end_of_batch = True

      eval_name_vals = eval_metric.get_name_value()

      print("Epoch:{} Train_Acc:{:.4f}".format(epoch, eval_name_vals[0][1]))

      arg_params, aux_params = mod.get_params()

      mod.set_params(arg_params, aux_params)

      train_data.reset()

      假設你拉取了本書的項目代碼,項目代碼的根目錄用“~/”表示,因為該腳本保存在“~/chapter3-baseKnowledge-of-MXNet/Module_code3-1.py”中,因此可以通過如下命令運行該腳本:

      $ cd ~/chapter3-baseKnowledge-of-MXNet

      $ python Module_code3-1.py

      成功運行時可以得到如下結果:

      Epoch:0 Train_Acc:0.5090

      Epoch:1 Train_Acc:0.7010

      Epoch:2 Train_Acc:0.9620

      Epoch:3 Train_Acc:0.9860

      Epoch:4 Train_Acc:0.9950

      mx.mod是mxnet.module常用的縮寫,后續篇章默認采用縮寫形式。

      代碼清單3-1中的代碼其實從mod.bind()方法這一行到最后都可以用Module模塊中的fit()方法來實現。fit()方法不僅封裝了上述的bind操作、參數初始化、優化器初始化、模型的前向計算、反向傳播、參數更新和計算評價指標等操作,還提供了保存訓練結果等其他操作,因此fit()方法將是今后使用MXNet訓練模型時經常調用的方法。下面這段代碼就演示了fit()方法的調用,前面兩行設置命令行打印訓練信息,這三行代碼可以直接替換代碼清單3-1中從mod.bind()那一行到最后的所有代碼。在fit()方法的輸入參數中,train_data參數是訓練數據,num_epoch參數是訓練時整個訓練集的迭代次數(也稱epoch數量)。需要注意的是,將所有train_data過一遍模型才算完成一個epoch,因此這里設定為將這個訓練集數據過5次模型才完成訓練。

      logger = logging.getLogger()

      logger.setLevel(logging.INFO)

      mod.fit(train_data=train_data, num_epoch=5)

      簡化版的代碼如代碼清單3-2所示。

      代碼清單3-2 通過Module模塊訓練模型(簡化版)

      import mxnet as mx

      import logging

      data = mx.sym.Variable('data')

      conv = mx.sym.Convolution(data=data, num_filter=128, kernel=(3,3), pad=(1,1),

      name='conv1')

      bn = mx.sym.BatchNorm(data=conv, name='bn1')

      relu = mx.sym.Activation(data=bn, act_type='relu', name='relu1')

      pool = mx.sym.Pooling(data=relu, kernel=(2,2), stride=(2,2), pool_type='max',

      name='pool1')

      fc = mx.sym.FullyConnected(data=pool, num_hidden=2, name='fc1')

      sym = mx.sym.SoftmaxOutput(data=fc, name='softmax')

      data = mx.nd.random.uniform(0,1,shape=(1000,3,224,224))

      label = mx.nd.round(mx.nd.random.uniform(0,1,shape=(1000)))

      train_data = mx.io.NDArrayIter(data={'data':data},

      label={'softmax_label':label},

      batch_size=8,

      shuffle=True)

      print(train_data.provide_data)

      《MXNet深度學習實戰》—3.3 Module

      print(train_data.provide_label)

      mod = mx.mod.Module(symbol=sym,context=mx.gpu(0))

      logger = logging.getLogger()

      logger.setLevel(logging.INFO)

      mod.fit(train_data=train_data, num_epoch=5)

      該腳本代碼保存在“~/chapter3-baseKnowledge-of-MXNet/Module_code3-2.py”中,下面使用如下命令運行該腳本:

      $ cd ~/chapter3-baseKnowledge-of-MXNet

      $ python Module_code3-2.py

      從下面打印出來的訓練結果可以看到,輸出結果與代碼清單3-1的輸出結果基本吻合:

      INFO:root:Epoch[0] Train-accuracy=0.515000

      INFO:root:Epoch[0] Time cost=4.618

      INFO:root:Epoch[1] Train-accuracy=0.700000

      INFO:root:Epoch[1] Time cost=4.425

      INFO:root:Epoch[2] Train-accuracy=0.969000

      INFO:root:Epoch[2] Time cost=4.428

      INFO:root:Epoch[3] Train-accuracy=0.988000

      INFO:root:Epoch[3] Time cost=4.410

      INFO:root:Epoch[4] Train-accuracy=0.999000

      INFO:root:Epoch[4] Time cost=4.425

      上面的演示代碼中只設定了fit()方法的幾個輸入,其實fit()方法的輸入還有很多,實際使用中可根據具體要求設定不同的輸入參數,本書后面的章節還會進行詳細介紹。

      得益于MXNet的靜態圖設計和對計算過程的優化,你會發現MXNet的訓練速度相較于大部分深度學習框架要快,而且顯存占用非常少!這使得你能夠在單卡或單機多卡上使用更大的batch size訓練相同的模型,這對于復雜模型的訓練非常有利,有時候甚至還會影響訓練結果。

      機器學習 深度學習

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎樣將Excel中圖表復制為圖片
      下一篇:WPS演示中連續閃爍
      相關文章
      亚洲国产成人久久笫一页| 在线精品自拍亚洲第一区| 亚洲性久久久影院| 久久精品国产亚洲av瑜伽| 亚洲日韩一区二区一无码| 亚洲a级片在线观看| 亚洲人成免费电影| 亚洲香蕉久久一区二区三区四区| 亚洲码一区二区三区| 亚洲欧洲尹人香蕉综合| 亚洲成人黄色在线| 亚洲avav天堂av在线网爱情| 亚洲黄色激情视频| 亚洲真人无码永久在线观看| 亚洲中文字幕乱码熟女在线| 亚洲欧美日韩一区二区三区| 亚洲精品人成网线在线播放va| 亚洲精品无码av片| 精品国产亚洲一区二区三区在线观看| 欧美色欧美亚洲另类二区| 国产成人精品亚洲一区| 亚洲高清国产拍精品青青草原 | 久久亚洲2019中文字幕| 国产L精品国产亚洲区久久| 国产亚洲精品自在线观看| 亚洲国产一成人久久精品| 亚洲乱亚洲乱淫久久| 亚洲第一页在线观看| 亚洲精品人成网在线播放影院 | 亚洲AV无码久久精品狠狠爱浪潮| 亚洲V无码一区二区三区四区观看 亚洲αv久久久噜噜噜噜噜 | 风间由美在线亚洲一区| www.亚洲精品| 亚洲中文字幕无码永久在线| 亚洲va久久久噜噜噜久久天堂| 亚洲国产精品久久久久| 亚洲免费视频播放| 亚洲国产精品嫩草影院| 国产a v无码专区亚洲av| 久久久影院亚洲精品| 亚洲日产2021三区在线|