當前位置:
首頁 > 最新 > 參數設置相關問題匯總

參數設置相關問題匯總

在使用指南的最後一部分,我們匯總了使用PaddlePaddle過程中的常見問題,本部分推文目錄如下:

2.22:【FAQ】模型配置相關問題匯總

2.23:【FAQ】參數設置相關問題匯總

2.24:【FAQ】本地訓練與預測相關問題匯總

2.25:【FAQ】集群訓練與預測相關問題匯總

2.26:如何貢獻代碼

2.27:如何貢獻文檔

參數設置相關問題匯總

1. 如何選擇SGD演算法的學習率?

在採用sgd/async_sgd進行訓練時,一個重要的問題是選擇正確的learning_rate。如果learning_rate太大,那麼訓練有可能不收斂,如果learning_rate太小,那麼收斂可能很慢,導致訓練時間過長。

通常做法是從一個比較大的learning_rate開始試,如果不收斂,那減少學習率10倍繼續試驗,直到訓練收斂為止。那麼如何判斷訓練不收斂呢?可以估計出如果模型採用不變的輸出最小的cost0是多少。

如果訓練過程的的cost明顯高於這個常數輸出的cost,那麼我們可以判斷為訓練不收斂。舉一個例子,假如我們是三分類問題,採用multi-class-cross-entropy作為cost,數據中0,1,2三類的比例為0.2, 0.5, 0.3, 那麼常數輸出所能達到的最小cost是-(0.2*log(0.2)+0.5*log(0.5)+0.3*log(0.3))=1.03。如果訓練一個pass(或者更早)後,cost還大於這個數,那麼可以認為訓練不收斂,應該降低學習率。

2.如何設置學習率退火(learning rate annealing)?

在相應的優化演算法里設置learning_rate_schedule及相關參數,以使用Adam演算法為例,代碼如下:

optimizer = paddle.optimizer.Adam(

learning_rate=1e-3,

learning_rate_decay_a=0.5,

learning_rate_decay_b=0.75,

learning_rate_schedule="poly",)

PaddlePaddle目前支持8種learning_rate_schedule,這8種learning_rate_schedule及其對應學習率計算方式如下:

「constant」

lr = learning_rate

「poly」

lr = learning_rate * pow(1 + learning_rate_decay_a * num_samples_processed, -learning_rate_decay_b)其中,num_samples_processed為已訓練樣本數,下同。

「caffe_poly」

lr = learning_rate * pow(1.0 - num_samples_processed / learning_rate_decay_a, learning_rate_decay_b)

「exp」

lr = learning_rate * pow(learning_rate_decay_a, num_samples_processed / learning_rate_decay_b)

「discexp」

lr = learning_rate * pow(learning_rate_decay_a, floor(num_samples_processed / learning_rate_decay_b))

「linear」

lr = max(learning_rate - learning_rate_decay_a * num_samples_processed, learning_rate_decay_b)

「manual」

這是一種按已訓練樣本數分段取值的學習率退火方法。使用該learning_rate_schedule時,用戶通過參數learning_rate_args設置學習率衰減因子分段函數,當前的學習率為所設置learning_rate與當前的衰減因子的乘積。以使用Adam演算法為例,代碼如下:

optimizer = paddle.optimizer.Adam(

learning_rate=1e-3,

learning_rate_schedule="manual",

learning_rate_args="1000:1.0,2000:0.9,3000:0.8",)

在該示例中,當已訓練樣本數小於等於1000時,學習率為1e-3 * 1.0;當已訓練樣本數大於1000小於等於2000時,學習率為1e-3 * 0.9;當已訓練樣本數大於2000時,學習率為1e-3 * 0.8。

「pass_manual」

這是一種按已訓練pass數分段取值的學習率退火方法。使用該learning_rate_schedule時,用戶通過參數learning_rate_args設置學習率衰減因子分段函數,當前的學習率為所設置learning_rate與當前的衰減因子的乘積。以使用Adam演算法為例,代碼如下:

optimizer = paddle.optimizer.Adam(

learning_rate=1e-3,

learning_rate_schedule="pass_manual",

learning_rate_args="1:1.0,2:0.9,3:0.8",)

在該示例中,當已訓練pass數小於等於1時,學習率為1e-3 * 1.0;當已訓練pass數大於1小於等於2時,學習率為1e-3 * 0.9;當已訓練pass數大於2時,學習率為1e-3 * 0.8。

3. 如何初始化參數?

默認情況下,PaddlePaddle使用均值0,標準差為 (frac{sqrt}) 來初始化參數。其中 (d) 為參數矩陣的寬度。這種初始化方式在一般情況下不會產生很差的結果。如果用戶想要自定義初始化方式,PaddlePaddle目前提供兩種參數初始化的方式:

高斯分布。將param_attr設置成param_attr=ParamAttr(initial_mean=0.0, initial_std=1.0)

均勻分布。將param_attr設置成param_attr=ParamAttr(initial_max=1.0, initial_min=-1.0)

比如設置一個全連接層的參數初始化方式和bias初始化方式,可以使用如下代碼:

hidden = fc_layer(input=ipt, param_attr=ParamAttr(initial_max=1.0, initial_min=-1.0),

bias_attr=ParamAttr(initial_mean=1.0, initial_std=0.0))

上述代碼將bias全部初始化為1.0, 同時將參數初始化為[1.0, -1.0]的均勻分布。

4. 如何共享參數?

PaddlePaddle的參數使用名字name作為參數的ID,相同名字的參數,會共享參數。設置參數的名字,可以使用ParamAttr(name="YOUR_PARAM_NAME")來設置。更方便的設置方式,是使得要共享的參數使用同樣的 ParamAttr 對象。

簡單的全連接網路,參數共享的配置示例為:

這裡hidden_a和hidden_b使用了同樣的parameter和bias。並且softmax層的兩個輸入也使用了同樣的參數softmax_param。

5.如何載入預訓練參數?

對載入預訓練參數的層,設置其參數屬性is_static=True,使該層的參數在訓練過程中保持不變。以embedding層為例,代碼如下:

從模型文件將預訓練參數載入numpy.array,在創建parameters後,使用parameters.set()載入預訓練參數。PaddlePaddle保存的模型參數文件前16位元組為頭信息,用戶將參數載入numpy.array時須從第17位元組開始。以embedding層為例,代碼如下:

6. PaddlePaddle是否支持維數可變的數據輸入?

PaddlePaddle保存的模型參數文件內容由16位元組頭信息和網路參數兩部分組成。頭信息中,1~4位元組表示PaddlePaddle版本信息,請直接填充0;5~8位元組表示每個參數佔用的位元組數,當保存的網路參數為float類型時為4,double類型時為8;9~16位元組表示保存的參數總個數。

將PaddlePaddle保存的模型參數還原回明文時,可以使用相應數據類型的numpy.array載入具體網路參數,此時可以跳過PaddlePaddle模型參數文件的頭信息。若在PaddlePaddle編譯時,未指定按照double精度編譯,默認情況下按照float精度計算,保存的參數也是float類型。這時在使用numpy.array時,一般設置dtype=float32。示例如下:

defread_parameter(fname, width):

s =open(fname).read()

# skip header

vec = np.fromstring(s[16:], dtype=np.float32)

# width is the size of the corresponding layer

np.savetxt(fname +".csv", vec.reshape(width, -1),

fmt="%.6f", delimiter=",")

將明文參數轉化為PaddlePaddle可載入的模型參數時,首先構造頭信息,再寫入網路參數。下面的代碼將隨機生成的矩陣轉化為可以被PaddlePaddle載入的模型參數。

7. A protocol message was rejected because it was too big?

如果在訓練NLP相關模型時,出現以下錯誤:

[libprotobuf ERROR google/protobuf/io/coded_stream.cc:171] A protocol message was rejected because it was too big (more than67108864bytes). To increase the limit (or to disable these warnings), see CodedInputStream::SetTotalBytesLimit() in google/protobuf/io/coded_stream.h.

F120514:59:50.29517414703TrainerConfigHelper.cpp:59] Check failed: m->conf.ParseFromString(configProtoStr)

可能的原因是:傳給dataprovider的某一個args過大,一般是由於直接傳遞大字典導致的。錯誤的define_py_data_sources2類似:

src_dict =dict()

for line_count, line inenumerate(open(src_dict_path,"r")):

src_dict[line.strip()] = line_count

define_py_data_sources2(

train_list,

test_list,

module="dataprovider",

obj="process",

args={"src_dict": src_dict})

解決方案是:將字典的地址作為args傳給dataprovider,然後在dataprovider裡面根據該地址載入字典。即define_py_data_sources2應改為:

define_py_data_sources2(

train_list,

test_list,

module="dataprovider",

obj="process",

args={"src_dict_path": src_dict_path})

end

*原創貼,版權所有,未經許可,禁止轉載

*值班小Paddle:wangp

*歡迎在留言區分享您的觀點


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 PaddlePaddle 的精彩文章:

單雙層RNN API對比介紹
【使用指南】用pip安裝paddlepaddle

TAG:PaddlePaddle |