ビッグ感謝のようなもの。
私の最大の問題は、キューのランナーだったようです。ファイル名のキューをFIFOQueue
に置き換え、手動でファイル名をエンキューすると、うまくいきましたが、shuffle_batch
キューも使用していたため、次のディレクトリのファイル名キューを空にしようとしたときにこれがうんざりになりました。ロックアップを引き起こすかキューを壊すので、私はこのキューを空にすることができませんでした。管理できるベストは、以前のディレクトリからの残り物を保持しながら新しいイメージでいっぱいにすることでした。最後に私はそれをRandomShuffleQueue
に置き換え、ファイル名と同じ方法で手動でエンキューします。私はこれがイメージの十分な十分な混合を与えていると思うし、問題のために過労ではない。スレッディングはありませんが、私がそれをやめた直後には、より簡単になりました。
私は以下のように私の最終的な解決策を含めました。どんな提案も歓迎!
import os
import tensorflow as tf
import numpy as np
from itertools import cycle
output_dir = '/my/output/dir'
my_dirs = [
[
'/path/to/datasets/blacksquares/black_square_100x100.png',
'/path/to/datasets/blacksquares/black_square_200x200.png',
'/path/to/datasets/blacksquares/black_square_300x300.png'
],
[
'/path/to/datasets/whitesquares/white_square_100x100.png',
'/path/to/datasets/whitesquares/white_square_200x200.png',
'/path/to/datasets/whitesquares/white_square_300x300.png',
'/path/to/datasets/whitesquares/white_square_400x400.png'
],
[
'/path/to/datasets/mixedsquares/black_square_200x200.png',
'/path/to/datasets/mixedsquares/white_square_200x200.png'
]
]
# set vars
patch_size = (100, 100, 1)
batch_size = 20
queue_capacity = 1000
# setup filename queue
filename_queue = tf.FIFOQueue(
capacity=queue_capacity,
dtypes=tf.string,
shapes=[[]]
)
filenames_placeholder = tf.placeholder(dtype='string', shape=(None))
filenames_enqueue_op = filename_queue.enqueue_many(filenames_placeholder)
# read file and preprocess
image_reader = tf.WholeFileReader()
key, file = image_reader.read(filename_queue)
uint8image = tf.image.decode_png(file)
cropped_image = tf.random_crop(uint8image, patch_size) # take a random 100x100 crop
float_image = tf.div(tf.cast(cropped_image, tf.float32), 255) # put pixels in the [0,1] range
# setup shuffle batch queue for training images
images_queue = tf.RandomShuffleQueue(
capacity=queue_capacity,
min_after_dequeue=0, # allow queue to become completely empty (as we need to empty it)
dtypes=tf.float32,
shapes=patch_size
)
images_enqueue_op = images_queue.enqueue(float_image)
# setup simple computation - calculate an average image patch
input = tf.placeholder(shape=(None,) + patch_size, dtype=tf.float32)
avg_image = tf.Variable(np.random.normal(loc=0.5, scale=0.5, size=patch_size).astype(np.float32))
loss = tf.nn.l2_loss(tf.sub(avg_image, input))
train_op = tf.train.AdamOptimizer(2.).minimize(loss)
# start session and initialize variables
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
# note - no need to start any queue runners as I've done away with them
for dir_index, image_paths in enumerate(my_dirs):
image_paths_cycle = cycle(image_paths)
# reset the optimisation and training vars
sess.run(tf.initialize_all_variables())
num_epochs = 1000
for i in range(num_epochs):
# keep the filename queue at capacity
size = sess.run(filename_queue.size())
image_paths = []
while size < queue_capacity:
image_paths.append(next(image_paths_cycle))
size += 1
sess.run(filenames_enqueue_op, feed_dict={filenames_placeholder: image_paths})
# keep the shuffle batch queue at capacity
size = sess.run(images_queue.size())
while size < queue_capacity:
sess.run([images_enqueue_op])
size += 1
# get next (random) batch of training images
batch = images_queue.dequeue_many(batch_size).eval()
# run train op
_, result, loss_i = sess.run([train_op, avg_image, loss], feed_dict={input: batch})
print('Iteration {:d}. Loss: {:.2f}'.format(i, loss_i))
# early stopping :)
if loss_i < 0.05:
break
# empty filename queue and verify empty
size = sess.run(filename_queue.size())
sess.run(filename_queue.dequeue_many(size))
size = sess.run(filename_queue.size())
assert size == 0
# empty batch queue and verify empty
size = sess.run(images_queue.size())
sess.run(images_queue.dequeue_many(size))
size = sess.run(filename_queue.size())
assert size == 0
# save the average image output
result_image = np.clip(result * 255, 0, 255).astype(np.uint8)
with open(os.path.join(output_dir, 'result_' + str(dir_index)), 'wb') as result_file:
result_file.write(tf.image.encode_png(result_image).eval())
print('Happy days!')
exit(0)
これはresult_0
ouputs - 黒四角、result_1
- 白四角及びresult_2
- (ほとんど)灰色正方形。
ありがとうございました!私はあなたが言うようにそれを稼働させようとしましたが、バッチを取得しようとすると吊り下がります。このようなサウンドは、 'filename_queue'が' shuffle_batch'キューに入っているので、別のキューに入ってくるキューによって引き起こされますか? – lopsided
フル・キューにエンキューしようとしているとき、または空のキューからデキューしようとしているときにハングします。既にキュー内にある要素の数を確認するには "sess.run([filename_queue.size()])"を試してください –
また、tf.batchもキューであるためキューランナーを起動する必要があります –