MXNet深度學(xué)習(xí)實(shí)戰(zhàn)》—3 MXNet基礎(chǔ)

      網(wǎng)友投稿 948 2025-04-04

      CHAPTER 3

      第3章

      MXNet基礎(chǔ)

      相信很多程序員在學(xué)習(xí)一門新的編程語言或者框架時,都會先了解下該語言或者該框架涉及的數(shù)據(jù)結(jié)構(gòu),畢竟當(dāng)你清晰地了解了數(shù)據(jù)結(jié)構(gòu)之后才能更加優(yōu)雅地編寫代碼,MXNet同樣也是如此。在MXNet框架中你至少需要了解這三駕馬車:NDArray、Symbol和Module。這三者將會是你今后在使用MXNet框架時經(jīng)常用到的接口。那么在搭建或者訓(xùn)練一個深度學(xué)習(xí)算法時,這三者到底扮演了一個什么樣的角色呢?這里可以做一個簡單的比喻,假如將從搭建到訓(xùn)練一個算法的過程比作是一棟房子從建造到裝修的過程,那么NDArray就相當(dāng)于是鋼筋水泥這樣的零部件,Symbol就相當(dāng)于是房子每一層的設(shè)計,Module就相當(dāng)于是房子整體框架的搭建。

      還記得我們在引入深度學(xué)習(xí)框架時提到的命令式編程(imperative programming)和符號式編程(symbolic programming)嗎?在本章中你將實(shí)際感受二者的區(qū)別,因?yàn)镹DArray接口采用的是命令式編程的方式,而Symbol接口采用的是符號式編程的方式。

      3.1 NDArray

      NDArray是MXNet框架中數(shù)據(jù)流的基礎(chǔ)結(jié)構(gòu),NDArray的官方文檔地址是:https://mxnet.apache.org/api/python/ndarray/ndarray.html,與NDArray相關(guān)的接口都可以在該文檔中查詢到。在了解NDArray之前,希望你先了解下Python中的NumPy庫(http://www.numpy.org/),因?yàn)橐环矫嬖诖蟛糠稚疃葘W(xué)習(xí)框架的Python接口中,NumPy庫的使用頻率都非常高;另一方面大部分深度學(xué)習(xí)框架的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)設(shè)計都借鑒了NumPy。在NumPy庫中,一個最基本的數(shù)據(jù)結(jié)構(gòu)是array,array表示多維數(shù)組,NDArray與NumPy庫中的array數(shù)據(jù)結(jié)構(gòu)的用法非常相似,可以簡單地認(rèn)為NDArray是可以運(yùn)行在GPU上的NumPy array。

      接下來,我會介紹在NDArray中的一些常用操作,并提供其與NumPy array的對比,方便讀者了解二者之間的關(guān)系。

      首先,導(dǎo)入MXNet和NumPy,然后通過NDArray初始化一個二維矩陣,代碼如下:

      import mxnet as mx

      import numpy as np

      a = mx.nd.array([[1,2],[3,4]])

      print(a)

      輸出結(jié)果如下:

      [[1. 2.]

      [3. 4.]]

      接著,通過NumPy array初始化一個相同的二維矩陣,代碼如下:

      b = np.array([[1,2],[3,4]])

      print(b)

      輸出結(jié)果如下:

      [[1 2]

      [3 4]]

      實(shí)際使用中常用縮寫mx代替mxnet,mx.nd代替mxnet.ndarray,np代替numpy,本書后續(xù)篇章所涉及的代碼默認(rèn)都采取這樣的縮寫。

      再來看看NumPy array和NDArray常用的幾個方法對比,比如打印NDArray的維度信息:

      print(a.shape)

      輸出結(jié)果如下:

      (2, 2)

      打印NumPy array的維度信息:

      print(b.shape)

      輸出結(jié)果如下:

      (2, 2)

      打印NDArray的數(shù)值類型:

      print(a.dtype)

      輸出結(jié)果如下:

      打印Numpy array的數(shù)值類型:

      print(b.dtype)

      輸出結(jié)果如下:

      int64

      在使用大部分深度學(xué)習(xí)框架訓(xùn)練模型時默認(rèn)采用的都是float32數(shù)值類型,因此初始化一個NDArray對象時默認(rèn)的數(shù)值類型是float32。

      如果你想要初始化指定數(shù)值類型的NDArray,那么可以通過dtype參數(shù)來指定,代碼如下:

      c=mx.nd.array([[1,2],[3,4]], dtype=np.int8)

      print(c.dtype)

      輸出結(jié)果如下:

      如果你想要初始化指定數(shù)值類型的NumPy array,則可以像如下這樣輸入代碼:

      d = np.array([[1,2],[3,4]], dtype=np.int8)

      print(d.dtype)

      輸出結(jié)果如下:

      int8

      在NumPy的array結(jié)構(gòu)中有一個非常常用的操作是切片(slice),這種操作在NDArray中同樣也可以實(shí)現(xiàn),具體代碼如下:

      c = mx.nd.array([[1,2,3,4],[5,6,7,8]])

      print(c[0,1:3])

      輸出結(jié)果如下:

      [2. 3.]

      在NumPy array中可以這樣實(shí)現(xiàn):

      d = np.array([[1,2,3,4],[5,6,7,8]])

      print(d[0,1:3])

      輸出結(jié)果如下:

      [2 3]

      在對已有的NumPy array或NDArray進(jìn)行復(fù)制并修改時,為了避免影響到原有的數(shù)組,可以采用copy()方法進(jìn)行數(shù)組復(fù)制,而不是直接復(fù)制,這一點(diǎn)非常重要。下面以NDArray為例來看看采用copy()方法進(jìn)行數(shù)組復(fù)制的情況,首先打印出c的內(nèi)容:

      print(c)

      輸出結(jié)果如下:

      [[1. 2. 3. 4.]

      [5. 6. 7. 8.]]

      然后調(diào)用c的copy()方法將c的內(nèi)容復(fù)制到f,并打印f的內(nèi)容:

      f = c.copy()

      print(f)

      輸出結(jié)果如下:

      [[1. 2. 3. 4.]

      [5. 6. 7. 8.]]

      《MXNet深度學(xué)習(xí)實(shí)戰(zhàn)》—3 MXNet基礎(chǔ)

      修改f中的一個值,并打印f的內(nèi)容:

      f[0,0] = -1

      print(f)

      輸出結(jié)果如下,可以看到此時對應(yīng)位置的值已經(jīng)被修改了:

      [[-1. 2. 3. 4.]

      [ 5. 6. 7. 8.]]

      那么c中對應(yīng)位置的值有沒有被修改呢?可以打印此時c的內(nèi)容:

      print(c)

      輸出結(jié)果如下,可以看到此時c中對應(yīng)位置的值并沒有被修改:

      [[1. 2. 3. 4.]

      [5. 6. 7. 8.]]

      接下來看看如果直接將c復(fù)制給e,會有什么樣的情況發(fā)生:

      e = c

      print(e)

      輸出結(jié)果如下:

      [[1. 2. 3. 4.]

      [5. 6. 7. 8.]]

      修改e中的一個值,并打印e的內(nèi)容:

      e[0,0] = -1

      print(e)

      輸出內(nèi)容如下:

      [[-1. 2. 3. 4.]

      [ 5. 6. 7. 8.]]

      此時再打印c的內(nèi)容:

      print(c)

      輸出結(jié)果如下,可以看到對應(yīng)位置的值也發(fā)生了改變:

      [[-1. 2. 3. 4.]

      [ 5. 6. 7. 8.]]

      實(shí)際上,NumPy array和NDArray之間的轉(zhuǎn)換也非常方便,NDArray轉(zhuǎn)NumPy array可以通過調(diào)用NDArray對象的asnumpy()方法來實(shí)現(xiàn):

      g=e.asnumpy()

      print(g)

      輸出結(jié)果如下:

      [[-1. 2. 3. 4.]

      [ 5. 6. 7. 8.]]

      NumPy array轉(zhuǎn)NDArray可以通過mxnet.ndarray.array()接口來實(shí)現(xiàn):

      print(mx.nd.array(g))

      輸出結(jié)果如下:

      [[-1. 2. 3. 4.]

      [ 5. 6. 7. 8.]]

      ?

      前面曾提到過NDArray和NumPy array最大的區(qū)別在于NDArray可以運(yùn)行在GPU上,從前面打印出來的NDArray對象的內(nèi)容可以看到,最后都有一個@cpu,這說明該NDArray對象是初始化在CPU上的,那么如何才能將NDArray對象初始化在GPU上呢?首先,調(diào)用NDArray對象的context屬性可以得到變量所在的環(huán)境:

      print(e.context)

      輸出結(jié)果如下:

      cpu(0)

      然后,調(diào)用NDArray對象的as_in_context()方法指定變量的環(huán)境,例如這里將環(huán)境指定為第0塊GPU:

      e = e.as_in_context(mx.gpu(0))

      print(e.context)

      輸出結(jié)果如下:

      gpu(0)

      環(huán)境(context)是深度學(xué)習(xí)算法中比較重要的內(nèi)容,目前常用的環(huán)境是CPU或GPU,在深度學(xué)習(xí)算法中,數(shù)據(jù)和模型都要在同一個環(huán)境中才能正常進(jìn)行訓(xùn)練和測試。MXNet框架中NDArray對象的默認(rèn)初始化環(huán)境是CPU,在不同的環(huán)境中,變量初始化其實(shí)就是變量的存儲位置不同,而且存儲在不同環(huán)境中的變量是不能進(jìn)行計算的,比如一個初始化在CPU中的NDArray對象和一個初始化在GPU中的NDArray對象在執(zhí)行計算時會報錯:

      f = mx.nd.array([[2,3,4,5],[6,7,8,9]])

      print(e+f)

      顯示結(jié)果如下,從報錯信息可以看出是2個對象的初始化環(huán)境不一致導(dǎo)致的:

      mxnet.base.MXNetError: [11:14:13] src/imperative/./imperative_utils.h:56: Check failed: inputs[i]->ctx().dev_mask() == ctx.dev_mask() (1 vs. 2) Operator broadcast_add require all inputs live on the same context. But the first argument is on gpu(0) while the 2-th argument is on cpu(0)

      下面將f的環(huán)境也修改成GPU,再執(zhí)行相加計算:

      f = f.as_in_context(mx.gpu(0))

      print(e+f)

      輸出結(jié)果如下:

      [[? 1.?? 5.?? 7.?? 9.]

      [ 11.? 13.? 15.? 17.]]

      NDArray是MXNet框架中使用最頻繁也是最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),是可以在CPU或GPU上執(zhí)行命令式操作(imperative operation)的多維矩陣,這種命令式操作直觀且靈活,是MXNet框架的特色之一。因?yàn)樵谑褂肕XNet框架訓(xùn)練模型時,幾乎所有的數(shù)據(jù)流都是通過NDArray數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,因此熟悉該數(shù)據(jù)結(jié)構(gòu)非常重要。

      TensorFlow 深度學(xué)習(xí)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:WPS表格怎么套用樣式教程(wps中如何套用表格樣式)
      下一篇:這個時候就可以制作一個Excel表格的下拉菜單(excel下拉菜單怎么做)
      相關(guān)文章
      亚洲暴爽av人人爽日日碰| 亚洲福利一区二区精品秒拍| 亚洲欧洲国产精品你懂的| 亚洲色成人WWW永久网站| 久久国产成人亚洲精品影院| 亚洲精品在线视频| 亚洲另类少妇17p| 亚洲男女内射在线播放| 亚洲精品老司机在线观看| 亚洲av无码专区在线观看素人| 亚洲综合av一区二区三区不卡 | 亚洲伊人成无码综合网| 亚洲AV网站在线观看| 小说专区亚洲春色校园| 一本久久综合亚洲鲁鲁五月天| 极品色天使在线婷婷天堂亚洲| 欧美亚洲精品一区二区| 亚洲AV无码一区二区三区网址| 亚洲AV无码资源在线观看| 亚洲爆乳无码精品AAA片蜜桃| 亚洲日韩精品国产3区| 亚洲中文字幕乱码一区| 亚洲爆乳无码专区www| 色偷偷亚洲男人天堂| 亚洲国产小视频精品久久久三级| 亚洲午夜精品第一区二区8050| 亚洲日韩国产成网在线观看| 在线精品亚洲一区二区三区| 亚洲人成人一区二区三区| 亚洲AV综合色区无码另类小说| 亚洲视频中文字幕| 亚洲人6666成人观看| 亚洲五月综合缴情婷婷| 亚洲成av人在线观看网站| 亚洲国产成人久久精品99| 日韩亚洲变态另类中文| 亚洲av无码一区二区三区乱子伦| 久久精品国产亚洲AV无码麻豆| 亚洲一区二区三区在线观看蜜桃| 亚洲乱码av中文一区二区| 亚洲成人高清在线|