私はtensorflowを初めて使用しますが、ウェブ全体で、彼らが宣伝するチュートリアルや他の多くのチュートリアルを既に実行しています。 MNIST画像上に少し畳み込みニューラルネットワークを作成しました。特別なことは何もありませんが、自分の画像でテストしたいと思います。ここで問題が発生します。いくつかのフォルダーを作成しました。各フォルダの名前は、内部の画像が属するクラス(ラベル)です。
画像の形状は異なります。つまり、固定サイズはありません。
Tensorflowで使用するためにそれらをどのようにロードできますか?
ここStackStackflowと他のQ/Aサイトの両方で、多くのチュートリアルと回答をフォローしました。しかし、それでも、私はこれを行う方法を理解していませんでした。
_tf.data
_ API(tensorflow 1.4以降)は、このようなものに最適です。パイプラインは次のようになります。
tf.data.Dataset
_オブジェクトを作成しますshuffle
/repeat
データセット。map
すべての画像を同じサイズにするいくつかの関数を使用します。batch
;prefetch
は、ネットワークが現在のバッチを処理している間に、前処理の後続のデータバッチを収集するようにプログラムに指示します。そして初期データセットを作成する方法はいくつかあります(より詳細な回答については here を参照)
Tensorflowバージョン1.12以降をサポートする Tensorflow datasets は、tfrecordデータセットを作成するための比較的単純なAPIを提供し、データのダウンロード、シャーディング、統計生成、およびその他の機能も自動的に処理します。
たとえば、 この画像分類データセットの実装 。そこにはたくさんの本のようなもの(ダウンロードURL、引用など)がありますが、技術的な部分はfeatures
を指定して__generate_examples
_関数を書くことです
_features = tfds.features.FeaturesDict({
"image": tfds.features.Image(shape=(_TILES_SIZE,) * 2 + (3,)),
"label": tfds.features.ClassLabel(
names=_CLASS_NAMES),
"filename": tfds.features.Text(),
})
...
def _generate_examples(self, root_dir):
root_dir = os.path.join(root_dir, _TILES_SUBDIR)
for i, class_name in enumerate(_CLASS_NAMES):
class_dir = os.path.join(root_dir, _class_subdir(i, class_name))
fns = tf.io.gfile.listdir(class_dir)
for fn in sorted(fns):
image = _load_tif(os.path.join(class_dir, fn))
yield {
"image": image,
"label": class_name,
"filename": fn,
}
_
より低いレベルの操作を使用してtfrecords
を生成することもできます。
tf.data.Dataset.map
_およびtf.py_func(tion)
を介して画像をロードするまたは、以下のように_tf.data.Dataset.map
_内のファイル名から画像ファイルをロードできます。
_image_paths, labels = load_base_data(...)
Epoch_size = len(image_paths)
image_paths = tf.convert_to_tensor(image_paths, dtype=tf.string)
labels = tf.convert_to_tensor(labels)
dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))
if mode == 'train':
dataset = dataset.repeat().shuffle(Epoch_size)
def map_fn(path, label):
# path/label represent values for a single example
image = tf.image.decode_jpeg(tf.read_file(path))
# some mapping to constant size - be careful with distorting aspec ratios
image = tf.image.resize_images(out_shape)
# color normalization - just an example
image = tf.to_float(image) * (2. / 255) - 1
return image, label
# num_parallel_calls > 1 induces intra-batch shuffling
dataset = dataset.map(map_fn, num_parallel_calls=8)
dataset = dataset.batch(batch_size)
# try one of the following
dataset = dataset.prefetch(1)
# dataset = dataset.apply(
# tf.contrib.data.prefetch_to_device('/gpu:0'))
images, labels = dataset.make_one_shot_iterator().get_next()
_
私は分散環境で作業したことがありませんが、tfrecords
に対してこのアプローチを使用することによるパフォーマンスの低下には気づきませんでした。さらにカスタムロード関数が必要な場合は、 _tf.py_func
_ も確認してください。
ディレクトリから画像とラベルを読み込むためのサンプル入力パイプラインスクリプト。この後、前処理(画像のサイズ変更など)を行うことができます。
import tensorflow as tf
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once("/home/xxx/Desktop/stackoverflow/images/*/*.png"))
image_reader = tf.WholeFileReader()
key, image_file = image_reader.read(filename_queue)
S = tf.string_split([key],'/')
length = tf.cast(S.dense_shape[1],tf.int32)
# adjust constant value corresponding to your paths if you face issues. It should work for above format.
label = S.values[length-tf.constant(2,dtype=tf.int32)]
label = tf.string_to_number(label,out_type=tf.int32)
image = tf.image.decode_png(image_file)
# Start a new session to show example output.
with tf.Session() as sess:
# Required to get the filename matching to run.
tf.initialize_all_variables().run()
# Coordinate the loading of image files.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in xrange(6):
# Get an image tensor and print its value.
key_val,label_val,image_tensor = sess.run([key,label,image])
print(image_tensor.shape)
print(key_val)
print(label_val)
# Finish off the filename queue coordinator.
coord.request_stop()
coord.join(threads)
ファイルディレクトリ
./images/1/1.png
./images/1/2.png
./images/3/1.png
./images/3/2.png
./images/2/1.png
./images/2/2.png
出力:
(881, 2079, 3)
/home/xxxx/Desktop/stackoverflow/images/3/1.png
3
(155, 2552, 3)
/home/xxxx/Desktop/stackoverflow/images/2/1.png
2
(562, 1978, 3)
/home/xxxx/Desktop/stackoverflow/images/3/2.png
3
(291, 2558, 3)
/home/xxxx/Desktop/stackoverflow/images/1/1.png
1
(157, 2554, 3)
/home/xxxx/Desktop/stackoverflow/images/1/2.png
1
(866, 936, 3)
/home/xxxx/Desktop/stackoverflow/images/2/2.png
2