雖然tf官方但願用戶把 train , val 程序分開寫,但實際開發中,明顯寫在一塊兒比較簡單舒服,但在保存數據到 summary 時, val 部分和 train 部分不太同樣,會有一些問題,下面討論如何在這種狀況下記錄 train/val 的 summary 。網絡
假設訓練時的主要代碼結構以下:spa
losssummary = ...
othersummary = ...
trainsummaries = tf.summary.merge([losssummary, othersummary])
for i in range(self.batchnum):
batching data...
... ... step ... trainsummaryresults = sess.run(... , trainsummaries)
trainfilewriter.addsummary(trainsummaryresults) if step % self.saveinter == 0:
... # save checkpoint if step % self.dispinter == 0:
... # display training process if step % self.testinter == 0:
... # run model on test data
保存 train 部分的 summary 很簡單,tf的示例代碼也給了不少,先利用 sess.run 計算出 trainsummaryresults ,即當前 batch 的統計數據,而後保存到文件scala
但在 val 部分時,通常都在全部驗證數據上獲取 loss , accuracy 等 summary 數據,再保存到文件。這樣只有兩種方法:設計
1. val 部分的 batchsize 改成驗證集大小
2. batchsize 不變,對全部 batch 上獲取的 loss , accuracy 計算平均code
第一種方法存在的問題是,若是驗證集數據較大, batchsize 會設置的較大,可能會引發內存or顯存溢出,這個無法解決。blog
第二種方法存在的問題是,無法按照train部分的作法作,由於要的是整個驗證數據的平均值,而不是每一個 batch 的值,這個有辦法解決。內存
在設計模型結構的時候,不管是 train 仍是 val ,網絡結構都是同樣的,每次只能計算一個 batch 的 loss , accuracy ,無法單獨爲驗證集修改。因而我想到了以下投機取巧的方法:先利用循環計算驗證集每一個 batch 的 loss , accuracy ,進行累加,記爲 averageloss 和 averageaccuracy ,而後進行以下操做:開發
testsummaries = tf.Summary() lossval = testsummaries.value.add() lossval.tag = 'loss' lossval.simplevalue = averageloss / batchnum accval = testsummaries.value.add() accval.tag = 'accuracy' accval.simplevalue = averageaccuracy / batchnum testfilewriter.addsummary(testsummaries, step)
其實就是本身建立一個 test_summaries ,把須要的東西填進去,模仿利用 sess.run 生成的 train_summary_results ,再保存到文件。你們若是感興趣能夠把 train_summary_results 打印出來,其實就是這麼個結構。目前我只保存過 scalar ,可是其餘值應該也能夠這麼保存。it