2017-05-18 11 views
0

목표는 TfRecords의 데이터베이스를 작성하는 것이 었습니다. 감안할 때 : 나는 각각 7500 이미지를 포함하는 23 개의 폴더와 23 개의 텍스트 파일을 가지고 있으며 각각 7500 개의 이미지에 대한 기능을 설명하는 7500 줄이 각각의 폴더에 있습니다. 문자열 목록에서 TfRecords 생성 및 디코딩 후 tensorflow에서 그래프 공급

는이 코드를 통해 데이터베이스를 만든 : 따라서

import tensorflow as tf 
import numpy as np 
from PIL import Image 

def _Float_feature(value): 
    return tf.train.Feature(float_list=tf.train.FloatList(value=[value])) 

def _bytes_feature(value): 
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) 

def _int64_feature(value): 
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) 

def create_image_annotation_data(): 
    # Code to read images and features. 
    # images represent a list of numpy array of images, and features_labels represent a list of strings 
    # where each string represent the whole set of features for each image. 
    return images, features_labels 

# This is the starting point of the program. 
# Now I have the images stored as list of numpy array, and the features as list of strings. 
images, annotations = create_image_annotation_data() 

tfrecords_filename = "database.tfrecords" 
writer = tf.python_io.TFRecordWriter(tfrecords_filename) 

for img, ann in zip(images, annotations): 

    # Note that the height and width are needed to reconstruct the original image. 
    height = img.shape[0] 
    width = img.shape[1] 

    # This is how data is converted into binary 
    img_raw = img.tostring() 
    example = tf.train.Example(features=tf.train.Features(feature={ 
     'height': _int64_feature(height), 
     'width': _int64_feature(width), 
     'image_raw': _bytes_feature(img_raw), 
     'annotation_raw': _bytes_feature(tf.compat.as_bytes(ann)) 
    })) 

    writer.write(example.SerializeToString()) 

writer.close() 

reconstructed_images = [] 

record_iterator = tf.python_io.tf_record_iterator(path=tfrecords_filename) 

for string_record in record_iterator: 
    example = tf.train.Example() 
    example.ParseFromString(string_record) 

    height = int(example.features.feature['height'] 
       .int64_list 
       .value[0]) 

    width = int(example.features.feature['width'] 
       .int64_list 
       .value[0]) 

    img_string = (example.features.feature['image_raw'] 
        .bytes_list 
        .value[0]) 

    annotation_string = (example.features.feature['annotation_raw'] 
         .bytes_list 
         .value[0]) 

    img_1d = np.fromstring(img_string, dtype=np.uint8) 
    reconstructed_img = img_1d.reshape((height, width, -1)) 
    annotation_reconstructed = annotation_string.decode('utf-8') 

, tfRecords에 이미지와 텍스트를 변환 후와 파이썬에서 문자열로 읽고 NumPy와와 (이진 텍스트)로 이미지를 변환 할 수있는 후 , 나는 filename_queue를 사용하여 여분의 마일을 읽으려고 시도했다. (목적은 한 번에 한 데이터의 평화로운 데이터 배치를 그래프에 제공하는 것이었고, 그 목적은 다음을 통해 큐 대기열에 넣고 대기열에서 빼는 것이었다. 따라서 서로 다른 스레드가 네트워크를 더 빠르게 훈련시킵니다.)

따라서 나는 foll 때문에 코드 : OutOfRangeError (역 추적을 위해 상기 참조) : 마지막

import tensorflow as tf 
import numpy as np 
import time 

image_file_list = ["database.tfrecords"] 
batch_size = 16 

# Make a queue of file names including all the JPEG images files in the relative 
# image directory. 
filename_queue = tf.train.string_input_producer(image_file_list, num_epochs=1, shuffle=False) 

reader = tf.TFRecordReader() 

# Read a whole file from the queue, the first returned value in the tuple is the 
# filename which we are ignoring. 
_, serialized_example = reader.read(filename_queue) 

features = tf.parse_single_example(
     serialized_example, 
     # Defaults are not specified since both keys are required. 
     features={ 
      'height': tf.FixedLenFeature([], tf.int64), 
      'width': tf.FixedLenFeature([], tf.int64), 
      'image_raw': tf.FixedLenFeature([], tf.string), 
      'annotation_raw': tf.FixedLenFeature([], tf.string) 
     }) 

image = tf.decode_raw(features['image_raw'], tf.uint8) 
annotation = tf.decode_raw(features['annotation_raw'], tf.float32) 

height = tf.cast(features['height'], tf.int32) 
width = tf.cast(features['width'], tf.int32) 

image = tf.reshape(image, [height, width, 3]) 

# Note that the minimum after dequeue is needed to make sure that the queue is not empty after dequeuing so that 
# we don't run into errors 
''' 
min_after_dequeue = 100 
capacity = min_after_dequeue + 3 * batch_size 
ann, images_batch = tf.train.batch([annotation, image], 
            shapes=[[1], [112, 112, 3]], 
            batch_size=batch_size, 
            capacity=capacity, 
            num_threads=1) 
''' 

# Start a new session to show example output. 
with tf.Session() as sess: 
    merged = tf.summary.merge_all() 
    train_writer = tf.summary.FileWriter('C:/Users/user/Documents/tensorboard_logs/New_Runs', sess.graph) 

    # Required to get the filename matching to run. 
    tf.global_variables_initializer().run() 

    # Coordinate the loading of image files. 
    coord = tf.train.Coordinator() 
    threads = tf.train.start_queue_runners(coord=coord) 

    for steps in range(16): 
     t1 = time.time() 
     annotation_string, batch, summary = sess.run([annotation, image, merged]) 
     t2 = time.time() 
     print('time to fetch 16 faces:', (t2 - t1)) 
     print(annotation_string) 
     tf.summary.image("image_batch", image) 
     train_writer.add_summary(summary, steps) 

    # Finish off the filename queue coordinator. 
    coord.request_stop() 
    coord.join(threads) 

는, 상기 코드를 실행 한 후, I가 다음 오류있어 FIFOQueue '_0_input_producer'폐쇄 및 보유 불충분 요소는 (1, 현재 크기를 요청한 0) [[노드 : ReaderReadV2 = ReaderReadV2 [_device = "/ 직업 : 로컬 호스트/복제 : 0/작업 : 0/CPU : 0"] (TFRecordReaderV2, input_producer)]]

또 다른 질문 :

  1. 바이너리 데이터베이스 (tfrecords)를 디코딩하여 "파이썬 문자열 데이터 구조"로 저장된 기능을 검색하는 방법.
  2. tf.train.batch을 사용하여 네트워크에 공급할 예제 배치를 만드는 방법.

고맙습니다! 도움을 주시면 감사하겠습니다.

답변

1

이 문제를 해결하려면 queue runner과 함께 coordinator을 모두 Session 내에서 초기화해야했습니다. 또한 에포크의 수는 내부적으로 제어되므로 global variable이 아니며 local variable을 고려하십시오. 따라서 queue_runnerfile_namesQueue으로 대기열에 넣기 시작하기 전에 해당 지역 변수를 초기화해야합니다. 따라서 다음 코드는 다음과 같습니다.

filename_queue = tf.train.string_input_producer(tfrecords_filename, num_epochs=num_epoch, shuffle=False, name='queue') 
reader = tf.TFRecordReader() 

key, serialized_example = reader.read(filename_queue) 
features = tf.parse_single_example(
    serialized_example, 
    # Defaults are not specified since both keys are required. 
    features={ 
     'height': tf.FixedLenFeature([], tf.int64), 
     'width': tf.FixedLenFeature([], tf.int64), 
     'image_raw': tf.FixedLenFeature([], tf.string), 
     'annotation_raw': tf.FixedLenFeature([], tf.string) 
    }) 
... 
init_op = tf.group(tf.local_variables_initializer(), 
       tf.global_variables_initializer()) 
with tf.Session() as sess: 
    sess.run(init_op) 

    coord = tf.train.Coordinator() 
    threads = tf.train.start_queue_runners(coord=coord) 

이제는 작동해야합니다.

이제 이미지를 네트워크에 보내기 전에 이미지 모음을 수집하려면 tf.train.shuffle_batch 또는 tf.train.batch을 사용할 수 있습니다. 두 작품. 그리고 그 차이는 간단합니다. 하나는 이미지를 섞고 다른 하나는 섞지 않습니다. 그러나 스레드 수를 정의하고 tf.train.batch을 사용하면 대기열에 포함 된 스레드간에 참여하는 경쟁으로 인해 데이터 샘플이 섞일 수 있습니다 (file_names). 어쨌든, 다음 코드는 다음과 같이 Queue을 초기화 한 후 직접 삽입해야합니다 여기에 tensors의 모양이 다를 수

min_after_dequeue = 100 
num_threads = 1 
capacity = min_after_dequeue + num_threads * batch_size 
label_batch, images_batch = tf.train.batch([annotation, image], 
             shapes=[[], [112, 112, 3]], 
             batch_size=batch_size, 
             capacity=capacity, 
             num_threads=num_threads) 

참고.독자가 크기 [112, 112, 3]의 컬러 이미지를 디코딩하는 중이었습니다. 특수 효과는 []입니다 (특별한 이유가없는 이유는 없습니다).

마지막으로 tf.string 데이터 유형을 문자열로 처리 할 수 ​​있습니다. 사실, 주석 텐서를 평가 한 후에, 텐서가 binary string으로 처리된다는 것을 알 수 있습니다 (이것은 텐서 플로우에서 실제로 처리되는 방법입니다). 따라서 필자의 경우 문자열은 특정 이미지와 관련된 일련의 기능 일뿐입니다. 따라서 구체적인 기능을 추출하려면 다음 예를 참조하십시오.

# The output of string_split is not a tensor, instead, it is a SparseTensorValue. Therefore, it has a property value that stores the actual values. as a tensor. 
label_batch_splitted = tf.string_split(label_batch, delimiter=', ') 
label_batch_values = tf.reshape(label_batch_splitted.values, [batch_size, -1]) 
# string_to_number will convert the feature's numbers into float32 as I need them. 
label_batch_numbers = tf.string_to_number(label_batch_values, out_type=tf.float32) 
# the tf.slice would extract the necessary feature which I am looking. 
confidences = tf.slice(label_batch_numbers, begin=[0, 3], size=[-1, 1]) 

희망 답변입니다.