Deep Learning學(xué)習(xí)筆記(六)詳解tf.app.flags()和tf.app.run()的源碼

經(jīng)常在程序中看到有tf.app.flagstf.app.run字樣的代碼台汇,這兩段代碼究竟是什么作用譬胎,就讓我們從分析源碼的角度來加深理解充甚!

tf.app.flags

tf.app.flags主要用于處理命令行參數(shù)的解析工作券盅,其實可以理解為一個封裝好了的argparse包(argparse是一種結(jié)構(gòu)化的數(shù)據(jù)存儲格式,類似于Json项郊、XML)∠诳郏現(xiàn)在我們就從源碼來分析它究竟是怎么解析命令行參數(shù)的,應(yīng)該怎么使用它着降!

源碼如下:

不出意外的首先導(dǎo)入了argparse

導(dǎo)入argparse.png

使用argparse的第一步就是創(chuàng)建一個解析器對象差油,告訴它將會有些什么參數(shù)。當程序運行時任洞,該解析器可以用于處理命令行參數(shù)(只能解析參數(shù)蓄喇、獲取參數(shù)、設(shè)置已有參數(shù)的默認值等操作)侈咕。argparse中的解析器類是ArgumentParser公罕。

創(chuàng)建解析器對象.png

定義了_FlagValues類,如我們前面所說耀销,要處理命令行參數(shù)楼眷,就要用解析器類_global_parser里的方法來解析,這里使用了parse_known_args()這個函數(shù)熊尉,其實同parse_args函數(shù)差不多(注:這里說的parse_args()函數(shù)和此處_FlagValues類中定義的_parse_args()函數(shù)不一樣罐柳,前者也是argparse中一種解析參數(shù)的函數(shù)),只是這個函數(shù)在接受到多余的命令行參數(shù)時不會報錯狰住,會原封不動的以一個list形式將其返回张吉。所以此函數(shù)返回的”result“是參數(shù)解析完的數(shù)據(jù),而”unparsed“是那些未被解析的參數(shù)list催植。將命令行傳入的命令和數(shù)據(jù)解析出來以字典的形式放到__dict__['_flags']這個字典中肮蛹,這么做也是為了方便我們后續(xù)直接訪問命令行輸入的命令,因為可以直接通過字典調(diào)用(在tensorflow中其實是通過tf.app.flag.Flags來實現(xiàn)實例化這個類创南,然后再調(diào)用里面解析得到的參數(shù)即可)伦忠。

定義_FlagValue類.png

初始化完了之后,可以看到源碼里是一些setattr/getattr的方法稿辙,也就是一些設(shè)置和獲得解析的命令行參數(shù)的方法昆码。要注意的是,在獲得參數(shù)的時候(getattr)邻储,首先要通過解析字典中的’parsed’來檢驗參數(shù)是否已經(jīng)被解析過赋咽,因為在_parse_flags方法中,只要解析過參數(shù)(也即是運行過該函數(shù))吨娜,那么self.__dict__[‘__parsed’]就會為True(表明解析過參數(shù))脓匿。因為這里是獲取參數(shù),所以出了要判斷參數(shù)是否在字典里的基本要求外萌壳,還要判斷有沒有解析過參數(shù)亦镶,沒有就運行_parse_flags解析參數(shù)日月。其它就比較簡單,這里就不介紹了缤骨!

getattr/setattr.png

后面將上述整個_FlagValues類的實例化阀溶,這樣就方便了我們的訪問操作妓羊。因為我們要訪問命令行輸入的命令時芯丧,就可以直接從這個實例里操作蝴簇。

實例化_FlagValue類.png

注意從這里開始都是在類外定義的方法,所以要調(diào)用就只能通過tf.app.flags.XXX來實現(xiàn)了虱歪。

下面的_define_helper函數(shù)中調(diào)用了_global_parser.add_argument完成對命令行參數(shù)的添加(傳入flag_name蜂绎,default_value,docstring笋鄙,flagtype參數(shù))师枣,可以看到添加參數(shù)使用的是解析器類_global_parser的方法。仔細看這個函數(shù)的參數(shù)萧落,第一個參數(shù)是‘--’+flag_name這個表示我們定義的命令行參數(shù)使用時必須以‘--’開頭践美,比如--flag_int9(具體看后面例子),而第二個參數(shù)default_value是參數(shù)的默認值找岖,第三個參數(shù)docstring保存幫助信息(命令行中輸入 -h激活該參數(shù))陨倡,第四個參數(shù)表示限定了賦予命令行參數(shù)數(shù)據(jù)的類型。

_deine_helper方法.png

上面我們已經(jīng)看到了使用_define_helper參數(shù)即可以添加命令行參數(shù)许布,這里源碼中又將其封裝為針對string/int/float/bool類型參數(shù)的特定添加方法**兴革。
DEFINE_string(),這里則由于_define_helper()最后一個type參數(shù)是str蜜唾,上面我們關(guān)于_define_helper參數(shù)的解釋杂曲,說明DEFINE_string()限定了可選參數(shù)輸入必須是string,這也就是為什么這個函數(shù)定義為DEFINE_string()袁余,同理解阅,DEFINE_interger()限定可選參數(shù)必須是int,DEFINE_float()限定可選參數(shù)必須是float泌霍,DEFINE_boolean()限定可選參數(shù)必須是bool。

DEFINE_string方法.png

DEFINE_int方法.png

DEFINE_float方法.png

DEFINE_boolean方法.png

源碼中最后介紹的方法是在程序運行前先將某些命令行參數(shù)加入到”必備參數(shù)“(__required_flags)的字典中述召,以判斷解析完的參數(shù)是否滿足這些必備要求朱转!因為mark_flags_as_required方法會調(diào)用mark_flag_as_required方法,來將當前傳入的參數(shù)加入到__required_flags字典中(_add_required_flag方法)积暖,在最上面解析參數(shù)的方法_parse_flags中藤为,解析完參數(shù)會通過_assert_all_required方法判斷解析到的參數(shù)是否都在_required_flags字典中。

required_flags.png

講了這么多夺刑,具體在tensorflow中我們該怎么使用呢缅疟?
首先我們通過tf.app.flags來調(diào)用這個flags.py文件分别,這樣我們就可以用flags.DEFINE_interger/float()來添加命令行參數(shù),而FLAGS=flags.FLAGS可以實例化這個解析參數(shù)的類從對應(yīng)的命令行參數(shù)取出參數(shù)存淫。
新建test.py文件耘斩,并輸入如下代碼,代碼的功能是創(chuàng)建幾個命令行參數(shù)桅咆,然后把命令行參數(shù)輸出顯示

import tensorflow as tf  

flags = tf.app.flags
flags.DEFINE_string('data_dir', '/tmp/mnist', 'Directory with the MNIST data.')
flags.DEFINE_integer('batch_size', 5, 'Batch size.')
flags.DEFINE_integer('num_evals', 1000, 'Number of batches to evaluate.')
FLAGS = flags.FLAGS

print(FLAGS.data_dir, FLAGS.batch_size, FLAGS.num_evals)
  • 在命令行中輸入test.py -h就可以查看幫助信息括授,也就是Directory with the MNIST data.Batch sizeNumber of batches to evaluate這樣的消息岩饼。
  • 在命令行中輸入test.py --batchsize 10就可以將batch_size的值修改為10荚虚!

tf.app.run()

該函數(shù)一般都是出現(xiàn)在這種代碼中:

if __name__ == '__main__':
    tf.app.run()

上述第一行代碼表示如果當前是從其它模塊調(diào)用的該模塊程序,則不會運行main函數(shù)籍茧!而如果就是直接運行的該模塊程序版述,則會運行main函數(shù)。

具體第二行的功能從源碼開始分析寞冯,源碼如下:


run函數(shù).png

flags_passthrough=f._parse_flags(args=args)這里的parse_flags就是我們tf.app.flags源碼中用來解析命令行參數(shù)的函數(shù)渴析。所以這一行就是解析參數(shù)的功能;

下面兩行代碼也就是tf.app.run的核心意思:執(zhí)行程序中main函數(shù)简十,并解析命令行參數(shù)檬某!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市螟蝙,隨后出現(xiàn)的幾起案子恢恼,更是在濱河造成了極大的恐慌,老刑警劉巖胰默,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件场斑,死亡現(xiàn)場離奇詭異,居然都是意外死亡牵署,警方通過查閱死者的電腦和手機漏隐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奴迅,“玉大人青责,你說我怎么就攤上這事∪【撸” “怎么了脖隶?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長暇检。 經(jīng)常有香客問我产阱,道長,這世上最難降的妖魔是什么块仆? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任构蹬,我火速辦了婚禮王暗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庄敛。我一直安慰自己俗壹,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布铐姚。 她就那樣靜靜地躺著策肝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隐绵。 梳的紋絲不亂的頭發(fā)上之众,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音依许,去河邊找鬼棺禾。 笑死,一個胖子當著我的面吹牛峭跳,可吹牛的內(nèi)容都是我干的膘婶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼蛀醉,長吁一口氣:“原來是場噩夢啊……” “哼悬襟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拯刁,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤脊岳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后垛玻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體割捅,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年帚桩,在試婚紗的時候發(fā)現(xiàn)自己被綠了亿驾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡账嚎,死狀恐怖莫瞬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郭蕉,我是刑警寧澤乏悄,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站恳不,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏开呐。R本人自食惡果不足惜烟勋,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一规求、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卵惦,春花似錦阻肿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至畜疾,卻和暖如春赴邻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啡捶。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工姥敛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞎暑。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓彤敛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親了赌。 傳聞我的和親對象是個殘疾皇子墨榄,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353