mxnet深度学习(NDArray)
mxnet深度學(xué)習(xí)(NDArray)
MXNet里面的3個(gè)主要的概念:
NDArray:NDArray提供了矩陣和張量(tensor)運(yùn)算在CPU和GPU上,通過使用并行運(yùn)算的技術(shù)。
Symbol:Symbol使得定義一個(gè)神經(jīng)網(wǎng)絡(luò)變得更加簡(jiǎn)單,并且自動(dòng)提供差異化(用于區(qū)別別的神經(jīng)網(wǎng)絡(luò))。
KVStore: KVStore ?提供數(shù)據(jù)同步在有多個(gè)GPU和CPU的機(jī)器上。NDArray(Numpy風(fēng)格的,可以在CPU和GPU運(yùn)算的張量計(jì)算模塊)
NDArray與numpy.ndarray相似,但是它多了以下兩點(diǎn):
1.多個(gè)設(shè)備支持:所有的操作可以支持GPU和CPU。
2.自動(dòng)并行:所有的操作都是以并行的方式進(jìn)行的。
創(chuàng)建和初始化
我們可以創(chuàng)建NDArray在CPU和GPU上:
>>> import mxnet as mx >>> a = mx.nd.empty((2, 3)) # create a 2-by-3 matrix on cpu >>> b = mx.nd.empty((2, 3), mx.gpu()) # create a 2-by-3 matrix on gpu 0 >>> c = mx.nd.empty((2, 3), mx.gpu(2)) # create a 2-by-3 matrix on gpu 2 >>> c.shape # get shape (2L, 3L) >>> c.context # get device info gpu(2)它們可以初始化通過不同的方式 >>> a = mx.nd.zeros((2, 3)) # create a 2-by-3 matrix filled with 0 >>> b = mx.nd.ones((2, 3)) # create a 2-by-3 matrix filled with 1 >>> b[:] = 2 # set all elements of b to 2 我們可以把值從一個(gè)NDArray到另一個(gè),即使它們?cè)诓煌脑O(shè)備上 >>> a = mx.nd.ones((2, 3)) >>> b = mx.nd.zeros((2, 3), mx.gpu()) >>> a.copyto(b) # copy data from cpu to gpu 我們可以把NDArray轉(zhuǎn)換成numpy.ndarray >>> a = mx.nd.ones((2, 3)) >>> b = a.asnumpy() >>> type(b) <type 'numpy.ndarray'> >>> print b [[ 1. 1. 1.][ 1. 1. 1.]]
反之亦然 >>> import numpy as np >>> a = mx.nd.empty((2, 3)) >>> a[:] = np.random.uniform(-0.1, 0.1, a.shape) >>> print a.asnumpy() [[-0.06821112 -0.03704893 0.06688045][ 0.09947646 -0.07700162 0.07681718]]</pre>
基礎(chǔ)操作
元素級(jí)操作是默認(rèn)的,NDArray執(zhí)行的是元素級(jí)的操作(這和matlab里面和我們線性代數(shù)里面學(xué)的不一樣)
>>> a = mx.nd.ones((2, 3)) * 2 >>> b = mx.nd.ones((2, 3)) * 4 >>> print b.asnumpy() [[ 4. 4. 4.][ 4. 4. 4.]] >>> c = a + b >>> print c.asnumpy() [[ 6. 6. 6.][ 6. 6. 6.]] >>> d = a * b >>> print d.asnumpy() [[ 8. 8. 8.][ 8. 8. 8.]]如果兩個(gè)NDArray在不同的設(shè)備上,我們需要顯示的把他們移到同一個(gè)設(shè)備上。
下面的代碼顯示了在GPU 0操作的例子
>>> a = mx.nd.ones((2, 3)) * 2 >>> b = mx.nd.ones((2, 3), mx.gpu()) * 3 >>> c = a.copyto(mx.gpu()) * b >>> print c.asnumpy() [[ 6. 6. 6.][ 6. 6. 6.]]加載和保存
下面有兩個(gè)方式去保存(加載)數(shù)據(jù)從磁盤上。第一個(gè)方式是pickle,NDArray是pickle compatible,意味著你可以簡(jiǎn)單的把NDArray進(jìn)行pickle,就像在numpy.ndarray里面一樣。
>>> import mxnet as mx >>> import pickle as pkl>>> a = mx.nd.ones((2, 3)) * 2 >>> data = pkl.dumps(a) >>> b = pkl.loads(data) >>> print b.asnumpy() [[ 2. 2. 2.][ 2. 2. 2.]]第二個(gè)方式是直接把一列NDArray以二進(jìn)制的格式存到磁盤中(這時(shí)就不用pickle了)>>> a = mx.nd.ones((2,3))*2 >>> b = mx.nd.ones((2,3))*3 >>> mx.nd.save('mydata.bin', [a, b]) >>> c = mx.nd.load('mydata.bin') >>> print c[0].asnumpy() [[ 2. 2. 2.][ 2. 2. 2.]] >>> print c[1].asnumpy() [[ 3. 3. 3.][ 3. 3. 3.]]
我們還可以存一個(gè)字典(dict)>>> mx.nd.save('mydata.bin', {'a':a, 'b':b}) >>> c = mx.nd.load('mydata.bin') >>> print c['a'].asnumpy() [[ 2. 2. 2.][ 2. 2. 2.]] >>> print c['b'].asnumpy() [[ 3. 3. 3.][ 3. 3. 3.]]
另外,如果設(shè)置了分布式系統(tǒng)比如S3和HDFS,我們可以直接去保存和加載它們(一般都沒有用)>>> mx.nd.save('s3://mybucket/mydata.bin', [a,b]) >>> mx.nd.save('hdfs///users/myname/mydata.bin', [a,b])</pre>
用自動(dòng)并行運(yùn)算?
NDArray可以自動(dòng)并行執(zhí)行操作。這是需要的,當(dāng)我們需要使用多個(gè)資源如CPU,GPU,和CPU-to-GPU的內(nèi)存帶寬。 ? 舉個(gè)栗子,如果我們寫a+=1在b+=1的后面,a是在CPU而b是在GPU,然后我們接下去想并行執(zhí)行它們來提高效率。此外,在CPU和GPU之間進(jìn)行數(shù)據(jù)拷貝的開銷是很昂貴的,所以我們希望把它們和其他的運(yùn)算一起并行計(jì)算。
然而,通過眼睛來找可以并行運(yùn)算的語句是比較累人的。在下面的例子里面,a+=1和c*=3是可以被并行執(zhí)行的,但是a+=1和b*=3必須順序執(zhí)行。
a = mx.nd.ones((2,3)) b = a c = a.copyto(mx.cpu()) a += 1 b *= 3 c *= 3幸運(yùn)的是,MXNet在確保運(yùn)行正確的情況下,可以自動(dòng)解決依賴問題。換句話說,我們可以寫程序就像一個(gè)單一的線程,MXNet將會(huì)自動(dòng)派遣它們到多個(gè)設(shè)備,如具有多個(gè)GPU的顯卡,和多臺(tái)機(jī)器上。
這是通過惰性評(píng)估來實(shí)現(xiàn)的。任何我們寫的操作都是通過一個(gè)中間引擎來發(fā)行的,然后返回。舉個(gè)栗子,如果我們運(yùn)行a+=1,它在執(zhí)行加法操作后立即返回這個(gè)引擎。這個(gè)異步性允許我們發(fā)出更多的操作給引擎,所以它可以決定讀寫依賴并找到最好的并行執(zhí)行它們的方式。
實(shí)際的計(jì)算是當(dāng)我們想把結(jié)果拷貝到其它地方的時(shí)候完成的,比如print a.asnumpy() (復(fù)制到終端)或者mx.nd.save([a])。因此,如果我們想去寫高效的并行的代碼,我們只需要延緩請(qǐng)求結(jié)果的時(shí)間。
總結(jié)
以上是生活随笔為你收集整理的mxnet深度学习(NDArray)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android shell检查是否锁屏_
- 下一篇: 【OpenCV 例程200篇】93. 噪