填坑
- 前文的坑讓我蒙了近一個小時,然後出去接了杯水…
原代碼
dics = {
'data': tf.FixedLenFeature(shape=[100], dtype=tf.float32, default_value=0.0),
'label': tf.FixedLenFeature(shape=[2], dtype=tf.float32)
}
修改後
dics = {
'data': tf.FixedLenFeature(shape=[100], dtype=tf.float32),
'label': tf.FixedLenFeature(shape=[2], dtype=tf.float32)
}
- 我還是太年輕,看到維度信息,一直以爲是前面的那個維度參數,沒想過後面填充的問題…
批量處理
tf.train.batch()
tf.train.batch(
tensors,
batch_size,
num_threads=1,
capacity=32,
enqueue_many=False,
shapes=None,
dynamic_pad=False,
allow_smaller_final_batch=False,
shared_name=None,
name=None
)
-
該函數將會使用一個隊列,函數讀取一定數量的tensors送入隊列,然後每次從中選取batch_size個tensors組成一個新的tensors返回出來。
-
capacity參數決定了隊列的長度。
-
num_threads決定了有多少個線程進行入隊操作,如果設置的超過一個線程,它們將從不同文件不同位置同時讀取,可以更加充分的混合訓練樣本。
-
如果enqueue_many參數爲False,則輸入參數tensors爲一個形狀爲[x, y, z]的張量,輸出爲一個形狀爲[batch_size, x, y, z]的張量。如果enqueue_many參數爲True,則輸入參數tensors爲一個形狀爲[, x, y, z]的張量,其中所有的數值相同,輸出爲一個形狀爲[batch_size, x, y, z]的張量。
-
當allow_smaller_final_batch爲True時,如果隊列中的張量數量不足batch_size,將會返回小於batch_size長度的張量,如果爲False,剩下的張量會被丟棄。
tf.train.shuffle_batch()
tf.train.shuffle_batch(
tensors,
batch_size,
capacity,
min_after_dequeue,
num_threads=1,
seed=None,
enqueue_many=False,
shapes=None,
allow_smaller_final_batch=False,
shared_name=None,
name=None
)
再挖一個坑
- 以前是placeholder的代碼風格,現在準備改一改。
loss, train_op, global_step = m.train(xs, ys)
-
該函數類似於上面的tf.train.batch(),同樣創建一個隊列,主要區別是會首先把隊列中的張量進行亂序處理,然後再選取其中的batch_size個張量組成一個新的張量返回。但是新增加了幾個參數。
-
capacity參數依然爲隊列的長度,建議capacity的取值如下:
-
min_after_dequeue + (num_threads + a small safety margin) * batch_size
-
min_after_dequeue這個參數的意思是隊列中,做dequeue(取數據)的操作後,線程要保證隊列中至少剩下min_after_dequeue個數據。如果min_after_dequeue設置的過少,則即使shuffle爲True,也達不到好的混合效果。
- 假設你有一個隊列,現在裏面有m個數據,你想要每次隨機從隊列中取n個數據,則代表先混合了m個數據,再從中取走n個。
- 當第一次取走n個後,隊列就變爲m-n個數據;當你下次再想要取n個時,假設隊列在此期間入隊進來了k個數據,則現在的隊列中有(m-n+k)個數據,則此時會從混合的(m-n+k)個數據中隨機取走n個。
- 如果隊列填充的速度比較慢,k就比較小,那你取出來的n個數據只是與周圍很小的一部分(m-n+k)個數據進行了混合。
因爲我們的目的肯定是想盡最大可能的混合數據,因此設置min_after_dequeue,可以保證每次dequeue後都有足夠量的數據填充盡隊列,保證下次dequeue時可以很充分的混合數據。
- 其他參數和tf.train.batch()相同。
碰到的第二個Bug
ilename_queue = tf.train.string_input_producer([filenames], num_epochs=None,
shuffle=True)
X_batch, y_batch = tf.train.shuffle_batch([X_out, y_out], batch_size=2,
capacity=200, min_after_dequeue=100, num_threads=2)
num_epoch的None和shuffle_batch不兼容??
- 我發現我num_epoch設置成1,2,3…(除了None),都會在sess.run處報錯
- 我最開始一直一維是shuffle_batch的鍋,直到我一行一行排除…
- 最後發現是在sess.run()處出現這個bug
- 最後根據:https://blog.csdn.net/momowenbo/article/details/80473326
# 加上
sess.run(tf.local_variables_initializer())
- 我真是fo了,我就想把自己代碼風格改一下,一下午+一晚上給玩進去了…
第三個坑
InvalidArgumentError (see above for traceback): Cannot assign a device for operation 'accuracy/ArgMax': Could not satisfy explicit device specification '/device:GPU:0' because no supported kernel for GPU devices is available.
部分代碼如下
X_batch, y_batch = tf.train.shuffle_batch([X_out, y_out], batch_size=Config.batch_size,
capacity=Config.batch_size*4+10, min_after_dequeue=Config.batch_size*2, num_threads=2)
with tf.device("/device:GPU:0"):
gpu_config = tf.ConfigProto(gpu_options=tf.GPUOptions(allow_growth=True))
# 結束時自動釋放資源
with tf.Session(config=gpu_config) as sess:
# 激活所有變量
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
print("Train and value start! ")
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
_X_batch, _y_batch = sess.run([X_batch, y_batch])
optim, loss, acc, summaries = textnn_model.train(_X_batch, _y_batch,0.5)
print(sess.run(loss))
當我改爲CPU環境時
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value cnn/conv-maxpool-2/W
[[Node: cnn/conv-maxpool-2/W/read = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](cnn/conv-maxpool-2/W)]]
- 然後我碰到一大堆莫名其妙的BUG,直到我找到一份代碼,根據邏輯對照,然後…
- 參考代碼tensorflow學習筆記——多線程輸入數據處理框架
X_batch, y_batch = tf.train.shuffle_batch([X_out, y_out], batch_size=Config.batch_size,
capacity=Config.batch_size*4+10, min_after_dequeue=Config.batch_size*2, num_threads=2)
optim, loss, acc, summaries = textnn_model.train(X_batch, y_batch, 0.5)
with tf.Session() as sess:
# 激活所有變量
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
print("Train and value start! ")
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
print(sess.run(optim))
- 我把textnn_model.train的位置換到了上面,所有的報錯都沒了…
- 我…自己瞎玩血浪費時間…
趟過上面的坑,基本就沒啥了
- 但是我碰到一個讓我很無語的東西,以前我用yield的時候:
for epoch in range(epoch_ums):
for batch in batch_iter:
........
- 但是我現在循環怎麼寫?
# 總不能:
for i in range(10000):
........
- 暫時有點不清楚怎麼巧妙設置這個值,只能用 epoch * batches 來代替…