怕這才是“深度學習”的正确打開方式!
今日小天帶來的就是天池使用者Clark Wan分享的幹貨——如何使用PAI深度學習TensorFlow讀寫OSS教程~
導語
Python不支援讀取oss的資料, 故所有調用 python Open(), os.path.exist() 等檔案, 檔案夾操作的函數的代碼都無法執行。
如Scipy.misc.imread(), numpy.load() 等。
那如何在PAI讀取資料呢, 通常我們采用兩種辦法。
如果隻是簡單的讀取一張圖檔, 或者一個文本等, 可以使用tf.gfile下的函數, 具體成員函數如下:
tf.gfile.Copy(oldpath, newpath, overwrite=False) # 拷貝檔案
tf.gfile.DeleteRecursively(dirname) # 遞歸删除目錄下所有檔案tf.gfile.Exists(filename) # 檔案是否存在
tf.gfile.FastGFile(name, mode='r') # 無阻塞讀寫檔案tf.gfile.GFile(name, mode='r') # 讀寫檔案
tf.gfile.Glob(filename) # 列出檔案夾下所有檔案, 支援patterntf.gfile.IsDirectory(dirname) # 傳回dirname是否為一個目錄
tf.gfile.ListDirectory(dirname) # 列出dirname下所有檔案
tf.gfile.MakeDirs(dirname) # 在dirname下建立一個檔案夾, 如果父目錄不存在, 會自動建立父目錄. 如果檔案夾已經存在, 且檔案夾可寫, 會傳回成功
tf.gfile.MkDir(dirname) # 在dirname處建立一個檔案夾tf.gfile.Remove(filename) # 删除filename
tf.gfile.Rename(oldname, newname, overwrite=False) # 重命名
tf.gfile.Stat(dirname) # 傳回目錄的統計資料tf.gfile.Walk(top, inOrder=True) # 傳回目錄的檔案樹
具體的文檔可以參照這裡
http://t.cn/EVuwpoc如果是一批一批的讀取檔案, 一般會采用tf.WholeFileReader() 和 tf.train.batch() 或者 tf.train.shuffer_batch();
接下來會重點介紹常用的 tf.gfile.Glob, tf.gfile.FastGFile, tf.WholeFileReader() 和 tf.train.shuffer_batch()
讀取檔案一般有兩步
- 擷取檔案清單
- 讀取檔案
如果是批量讀取, 還有第三步
- 建立batch
從代碼上手: 在使用PAI的時候, 通常需要在右側設定讀取目錄, 代碼檔案等參數, 這些參數都會通過--XXX的形式傳入

tf.flags可以提供這個功能
接下來就分兩種情況:
1.(小規模讀取時建議) tf.gfile.FastGFile()
2.(大批量讀取時建議) tf.WholeFileReader()
解釋下其中重要的部分
tf.train.string_input_producer, 這個是把files轉換成一個隊列, 并且需要 tf.train.start_queue_runners 來啟動隊列;
tf.train.shuffle_batch 參數解釋;
batch_size 批大小, 每次運作這個batch, 傳回多少個資料;
num_threads 運作線程數, 在PAI上4個就好;
capacity 随機取檔案範圍, 比如你的資料集有10000個資料, 你想從5000個>資料中随機取, capacity就設定成5000;
min_after_dequeue 維持隊列的最小長度, 這裡隻要注意不要大于capacity即可。
如果遇到不得不使用第三方庫的情況:
如讀取pkl、npy、tiff可以使用tf.gfile.Copy(FLAGS.buckets,'./檔案名')從OSS拷貝到運作時目錄 ('./') , 然後用直接用第三方庫讀取就可以。
檔案寫入
直接使用tf.gfile.FastGFile()寫入
tf.gfile.FastGFile(FLAGS.checkpointDir + 'example.txt', 'wb').write('hello world')
通過tf.gfile.Copy()拷貝
tf.gfile.Copy('./example.txt', FLAGS.checkpointDir + 'example.txt')
通過這兩種方法, 檔案都會出現在 '輸出目錄/model/example.txt' 下
費用開支
這裡隻讨論讀取檔案所需要的費用開支
原則上來說, PAI不跨區域讀取OSS是不收費的, 但是OSS的API是收費的。 PAI在使用 tf.gile.Glob 的時候會産生GET請求, 在寫入tensorboard 的時候,也會産生PUT請求。 這兩種請求都是按次收費的,具體價格如下:
标準型單價: 0.01元/萬次
低頻通路型單價: 0.1元/萬次
歸檔型單價: 0.1元/萬次
當資料集有幾十萬圖檔, 通過 tf.gile.Glob 一次就需要幾毛錢, 是以減少費用開支的方法就是減少GET請求次數。
這裡給出幾種解決思路:
最好的解決思路, 把所有會使用到的資料, 一并上傳傳到OSS, 然後使用tensorflow拷貝到運作時目錄, 最後通過tensorflow讀取, 這樣是最節省開支的.
通過tfrecords, 在本地, 提前把幾十上百張圖檔通過tfrecords存下來, 這樣讀取的時候可以減少GET請求
把訓練使用的圖檔随着代碼的壓縮包一起傳上去, 不走OSS讀取
三種方法都可以顯著的減少開支.。
除此之外,插播一則天池相關的PAI-DSW産品GPU資源促銷,感興趣的同學抓緊戳!
使用注意
事實上, 每次讀取傳過來的位址就是 oss://你的buckets名字/XXX, 本以為不需要在PAI界面上設定, 直接讀取這個目錄就好, 事實上并不如此。
PAI沒有權限讀取不在資料源目錄和輸出目錄下的檔案, 是以在使用路徑前, 確定他們已經在控制台右側設定過。
另外如果需要寫入檔案到OSS, 可以使用 tf.gfile.fastGFile('OSS路徑', 'wb').write('内容')
OSS路徑推薦使用:FLAGS.checkpointDir以及FLAGS.summaryDIr這樣的形式傳入,經過測試,好像也隻有這兩個目錄下有寫權限;
FLAGS.buckets下所有檔案夾都有讀寫權限。