稀疏矩陣用于python的keras和theano

稀疏矩陣

稀疏矩陣(sparse matrix)是由于矩陣中存在大量0,從而可以采用特別的存儲(chǔ)技巧來(lái)壓縮內(nèi)存。
由于在工作需要將一個(gè)150666569x9860的超大矩陣作為數(shù)據(jù),來(lái)訓(xùn)練NN模型,所以采用稀疏矩陣的方式,將這個(gè)超大矩陣壓縮,從而使得能夠放入內(nèi)存中。
python的稀疏矩陣在scipy包中,而theano同時(shí)支持的是csc_matrix,和csr_matrix。

from scipy.sparse import csc_matrix,csr_matrix

這兩種稀疏矩陣的選擇取決于要稀疏的矩陣的情況,如果row比column多,就用csc_matrix,反之則用csr_matrix,更具體的可以看這里。我們當(dāng)然就選擇scs_matrix

構(gòu)建稀疏矩陣

有兩種方法構(gòu)建矩陣,一種方法是用3個(gè)list,分別記錄非0元素的行序列, 列序列,還有該元素本身。

row = np.array([0, 2, 2, 0, 1, 2])
col = np.array([0, 0, 1, 2, 2, 2])
data = np.array([1, 2, 3, 4, 5, 6])
sparse_matrix=csc_matrix((data, (row, col)), shape=(3, 3))
sparse_matrix.toarray()
output:array([[1, 0, 4], 
              [0, 0, 5], 
              [2, 3, 6]])

另一種方法也是用3個(gè)list,看例子來(lái)詳解下

indptr = np.array([0, 2, 3, 6])
indices = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
csc_matrix((data, indices, indptr), shape=(3, 3)).toarray()
output:
array([[1, 0, 4], 
      [0, 0, 5],
      [2, 3, 6]])

在csc_matrix中indptr的差值代表每列有幾個(gè)非0元素,比如2-0=2,代表第一列有2個(gè)非0元素,在哪里是看indices這個(gè)list,它記錄了行的序列,元素本身則在data list中。
知道這個(gè)原理,我們可以自己寫一個(gè)合并兩個(gè)csc_matrix的函數(shù):

def concatenate_csc_matrices_by_columns(matrix1, matrix2):
    new_data = np.concatenate((matrix1.data, matrix2.data))
    new_indices = np.concatenate((matrix1.indices, matrix2.indices))
    new_ind_ptr = matrix2.indptr + len(matrix1.data)
    new_ind_ptr = new_ind_ptr[1:]
    new_ind_ptr = np.concatenate((matrix1.indptr, new_ind_ptr))
    return csc_matrix((new_data, new_indices, new_ind_ptr))

很明顯的看到,第二種存儲(chǔ)稀疏矩陣的方式,更節(jié)省空間。但是第一種更淺顯易懂。

將稀疏矩陣用于theano

以deeplearning tutorial的mlp為例,如果輸入的training_x數(shù)據(jù)為稀疏矩陣,那么需要改一下幾個(gè)地方:

  1. Symbolic declaration:
    將原來(lái)的x = T.matrix('x')改成:
x = theano.sparse.csc_matrix('x')
  1. 將Hiddenlayer的lin_out改成:
 lin_output = theano.sparse.dot(input, self.W) + self.b

其他只要跟原來(lái)的模型保持一致就可以了。

theano改起來(lái)還是很容易的,這主要是因?yàn)閠heano本身支持稀疏矩陣。

將稀疏矩陣用于keras

Keras is a minimalist, highly modular neural networks library, written in Python and capable of running on top of either TensorFlow or Theano.
keras是一個(gè)高度模塊化的深度學(xué)習(xí)框架,用起來(lái)非常方便,只需要關(guān)注模型本身就行。
要使得稀疏矩陣能在keras中用,只需要對(duì)keras的training.py這個(gè)文件做些修改就行。

  1. 將所有l(wèi)en(ins[0])替換成ins[0].shape[0]
  2. 在用SGD的時(shí)候,將每批batch選出來(lái)的樣本還原成正常的矩陣,這樣的方式,使得內(nèi)存不會(huì)被占用很多。要實(shí)現(xiàn)這個(gè),只需要在每次調(diào)用slice_X這個(gè)函數(shù)之后,插入如下代碼,將ins_batch變成正常矩陣就可以。
    代碼如下:
if sps.issparse(ins_batch[0]):    
      ins_batch[0] = ins_batch[0].toarray()
if sps.issparse(ins_batch[1]):    
      ins_batch[1] = ins_batch[1].toarray()

總結(jié)

  1. keras很好用
  2. keras是用python實(shí)現(xiàn)的,查看源代碼很方便,修改起來(lái)也很方便
  3. 這次因?yàn)檫@個(gè)稀疏矩陣的需求,研究了下theano和keras,收獲頗豐,以后有機(jī)會(huì)還是應(yīng)該多看看源代碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容