FROM:?http://blog.csdn.net/u012162613/article/details/43169019
DeepLearning tutorial(2)機器學習算法在訓練過程中保存參數
@author:wepon
@blog:http://blog.csdn.net/u012162613/article/details/43169019
參考:pickle — Python object serialization、DeepLearning Getting started
一、python讀取"***.pkl.gz"文件
用到python里的gzip以及cPickle模塊,簡單的使用代碼如下,如果想詳細了解可以參考上面給出的鏈接。
[python] view plaincopy
??import?cPickle,?gzip??f?=?gzip.open('mnist.pkl.gz',?'rb')??train_set,?valid_set,?test_set?=?cPickle.load(f)??f.close()??
其實就是分兩步,先讀取gz文件,再讀取pkl文件。pkl文件的應用正是下文要講的,我們用它來保存機器學習算法訓練過程中的參數。
二、機器學習算法在訓練過程中如何保存參數?
我們知道,機器學習算法的計算量特別大,跑起程序來少則幾十分鐘,多則幾小時甚至幾天,中間如果有什么狀況(比如電腦過熱重啟、程序出現一些小bug...)程序就會中斷,如果你沒把參數定時保存下來,前面的訓練就當白費了,所以很有必要在程序中加入定時保存參數的功能,這樣下次訓練就可以將參數初始化為上次保存下來的結果,而不是從頭開始隨機初始化。
那么如何保存模型參數?可以將參數深復制,或者調用python的數據永久存儲cPickle模塊,原理不多說,直接使用就行。(注:python里有cPickle和pickle,cPickle基于c實現,比pickle快。)
直接用一個例子來說明如何使用:
[python] view plaincopy
a=[1,2,3]??b={4:5,6:7}????import?cPickle??write_file=open('/home/wepon/ab','wb')??cPickle.dump(a,write_file,-1)??cPickle.dump(b,write_file,-1)??write_file.close()??????read_file=open('/home/wepon/ab','rb')??a_1=cPickle.load(read_file)??b_1=cPickle.load(read_file)??print?a,b??read_file.close()??
在deeplearning算法中,因為用到GPU,經常是將參數聲明為shared變量,因此必須用上get_value()、set_value,例如有w、v、u三個shared變量,使用代碼如下:
[python] view plaincopy
import?cPickle????write_file?=?open('path',?'wb')????cPickle.dump(w.get_value(borrow=True),?write_file,?-1)????cPickle.dump(v.get_value(borrow=True),?write_file,?-1)????cPickle.dump(u.get_value(borrow=True),?write_file,?-1)???write_file.close()??????read_file?=?open('path')??w.set_value(cPickle.load(read_file),?borrow=True)??v.set_value(cPickle.load(read_file),?borrow=True)??u.set_value(cPickle.load(read_file),?borrow=True)??read_file.close()??
一個實例
下面我以一個實際的例子來說明如何在程序中加入保存參數的功能。以deeplearnig.net上的邏輯回歸為例,它的代碼地址:logistic_sgd.py。這個程序是將邏輯回歸用于MNIST分類,程序運行過程并不會保存參數,甚至運行結束時也不保存參數。怎么做可以保存參數?
在logistic_sgd.py代碼里最后面的sgd_optimization_mnist()函數里,有個while循環,里面有一句代碼:
[python] view plaincopy
if?this_validation_loss?<?best_validation_loss:??
這句代碼的意思就是判斷當前的驗證損失是否小于最佳的驗證損失,是的話,下面會更新best_validation_loss,也就是說當前參數下,模型比之前的有了優化,因此我們可以在這個if語句后面加入保存參數的代碼:
[python] view plaincopy
save_params(classifier.W,classifier.b)??
save_params函數定義如下:
[python] view plaincopy
def?save_params(param1,param2):??????import?cPickle??????write_file?=?open('params',?'wb')???????cPickle.dump(param1.get_value(borrow=True),?write_file,?-1)??????cPickle.dump(param2.get_value(borrow=True),?write_file,?-1)??????write_file.close()??
當然參數的個數根據需要去定義。在logistic_sgd.py中參數只有classifier.W,classifier.b,因此這里定義為save_params(param1,param2)。
在logistic_sgd.py里我加入了save_params(classifier.W,classifier.b),運行了3次epoch,中斷掉程序,在代碼所在的文件夾下,多出了一個params文件,我們來看看這個文件里是什么東西:
[python] view plaincopy
import?cPickle??f=open('params')??w=cPickle.load(f)??b=cPickle.load(f)??????array([-0.0888151?,??0.16875755,?-0.03238435,?-0.06493175,??0.05245609,??????????0.1754718?,?-0.0155049?,??0.11216578,?-0.26740651,?-0.03980861])??
也就是說,params文件確實保存了我們訓練過程中的參數。
那么如何用保存下來的參數來初始化我們的模型的參數呢?
在logistic_sgd.py中的class LogisticRegression(object)下,self.W和self.b本來是初始化為0的,我們可以在下面加上幾行代碼,這樣就可以用我們保存下來的params文件來初始化參數了:
[python] view plaincopy
class?LogisticRegression(object):??????def?__init__(self,?input,?n_in,?n_out):??????????self.W?=?theano.shared(??????????????value=numpy.zeros(??????????????????(n_in,?n_out),??????????????????dtype=theano.config.floatX??????????????),??????????????name='W',??????????????borrow=True??????????)??????????self.b?=?theano.shared(??????????????value=numpy.zeros(??????????????????(n_out,),??????????????????dtype=theano.config.floatX??????????????),??????????????name='b',??????????????borrow=True??????????)??????????if?os.path.exists('params'):??????????f=open('params')??????????self.W.set_value(cPickle.load(f),?borrow=True)??????????self.b.set_value(cPickle.load(f),?borrow=True) ?
總結
以上是生活随笔為你收集整理的DeepLearning tutorial(2)机器学习算法在训练过程中保存参数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。