使用Tensorflow Dataset API时预处理输入数据时出错

时间:2018-10-08 08:26:27

标签: python numpy tensorflow floating-accuracy tfrecord

我在[.npy]文件中存储了[64,512,5]张图像,然后将其转换为* .tfrecords文件。

我已验证所述记录的读取与* .npy文件中存在的内容正确对应。但是,当我在解析器上执行某些操作时,例如将1加到图像的每个像素上,结果不是预期的。结果应为65 * 512 * 5 = 163840,但应为163839.99980013957(并非始终相同)
我尝试执行tf.subtract之类的不同操作,但结果是相同的。

有人可以告诉我怎么了吗?

import re
import ast
import sys, select
import random as rn
from glob import glob
from tqdm import tqdm
from datetime import datetime
from configparser import SafeConfigParser

import numpy as np
import numpy.ma as ma
import scipy.misc

import os.path
from os import mkdir, stat
from os.path import exists, dirname, abspath
from os.path import join as dir_join
import tensorflow as tf

''' File hierarchy
'''
_code_dir             = dirname(abspath(__file__))
_python_dir           = dirname(_code_dir)
_model_dir            = dirname(_python_dir)
_project_dir          = dirname(_model_dir)
_ml_dir               = dirname(_project_dir)
_srv_dir              = dirname(_ml_dir)
_root_datasets_dir    = dir_join(_srv_dir,'machine_learning','data_sets/ssd_prepared')
_config_dir           = dir_join(_python_dir, 'config')

'''Data sets directories
'''
THIS_DATA_SET_DIR     = 'Sph_50m' #WARNING: Global variable also used in helper.py
_data_dir             = dir_join(_root_datasets_dir, THIS_DATA_SET_DIR)
_data_set_dir         = dir_join(_data_dir,'ImageSet')
_data_npy_dir         = dir_join(_data_dir,'data')
_data_tfRecord_dir    = dir_join(_data_dir,'tfRecord')

''' Configuration parser
'''
cfg_parser = SafeConfigParser()
cfg_parser.read(dir_join(_config_dir,'cfg_model.ini'))

''' Private variables
'''
_batch_size        = cfg_parser.getint(section='train', option='batch_size')
_max_epoch         = cfg_parser.getint(section='train', option='max_epoch')
_standarize        = cfg_parser.getboolean(section='train', option='standarize_input')

_input_shape       = ast.literal_eval(cfg_parser.get(section='data_shape', option='input_shape'))
_label_channel     = cfg_parser.getint(section='data_shape', option='label_channel')
_track_channel     = cfg_parser.getint(section='data_shape', option='track_channel')
_mask_channel      = cfg_parser.getint(section='data_shape', option='mask_channel')

_data_train        = cfg_parser.get(section='data_set', option='data_train')
_data_val          = cfg_parser.get(section='data_set', option='data_val')
_data_test         = cfg_parser.get(section='data_set', option='data_test')

def _int64_feature(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value.reshape(-1)))

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

def _floats_feature(value):
    return tf.train.Feature(float_list=tf.train.FloatList(value=value.reshape(-1)))

def numpy_to_TFRecord():
    if not exists(_data_tfRecord_dir): mkdir(_data_tfRecord_dir)

    for dataset in [_data_train, _data_val, _data_test]:
        tfRecord_folder = dir_join(_data_tfRecord_dir, dataset)
        if not exists(tfRecord_folder): mkdir(tfRecord_folder)

        #Retrieve list of files
        projections_dir=[]
        file_ = open(dir_join(_data_set_dir, dataset+'.txt'), 'r')
        for x in file_.readlines():
            file_nat = x.strip()+'.npy'
            filename = dir_join(_data_npy_dir, file_nat)
            assert exists(filename), "{} doesn't exist".format(filename)
            projections_dir.append(filename)
        file_.close()

        totaltfRecordSize = 0
        numFile = 0

        for projection_dir in tqdm(projections_dir, ncols= 100, desc = 'TFRecord {}'.format(dataset)):
            scanName = projection_dir.split('/')[-1].split('.')[0]
            if totaltfRecordSize > 100*(10**6) or totaltfRecordSize == 0:
                # address to save the TFRecords file
                train_filename = dir_join(tfRecord_folder, \
                                        str(numFile) + '_' + dataset +'.tfrecords')
                # open the TFRecords file                
                writer = tf.python_io.TFRecordWriter(train_filename)

                numFile += 1
                totaltfRecordSize = 0

            # Load the image
            projection = np.load(projection_dir)
            image = projection[:,:,:_label_channel]
            label = projection[:,:,_label_channel].astype(int)
            mask  = projection[:,:,_mask_channel].astype(int)
            track = projection[:,:,_track_channel].astype(int)

            # Create a feature
            feature = {'image': _floats_feature(image),
                       'label': _int64_feature(label),
                       'mask' : _int64_feature(mask),
                       'track': _int64_feature(track),
                       'scanName': _bytes_feature(tf.compat.as_bytes(scanName))}

            # Create an example protocol buffer
            example = tf.train.Example(features=tf.train.Features(feature=feature))

            # Serialize to string and write on the file
            writer.write(example.SerializeToString())

            fileSize = stat(train_filename).st_size
            totaltfRecordSize += fileSize

        writer.close()
        sys.stdout.flush()

def readTFRecord():
    # Transforms a scalar string `example_proto` into a pair of a scalar string and
    # a scalar integer, representing an image and its label, respectively.
    image_dim = _input_shape[0] * _input_shape[1] * _label_channel
    label_dim = _input_shape[0] * _input_shape[1]
    mean = np.load(dir_join(_data_dir,'mean.npy'))
    std  = np.load(dir_join(_data_dir,'std.npy'))
    mean_tf = tf.convert_to_tensor(mean, dtype=tf.float32, name='mean')
    std_tf = tf.convert_to_tensor(std,  dtype=tf.float32, name='std')

    with tf.variable_scope('TFRecord'):
        def _parse_function(example_proto):
            with tf.variable_scope('parser'):
                features = {'image': tf.FixedLenFeature([image_dim], tf.float32),
                            'label': tf.FixedLenFeature([label_dim], tf.int64),
                            'mask' : tf.FixedLenFeature([label_dim], tf.int64),
                            'track': tf.FixedLenFeature([label_dim], tf.int64),
                            'scanName': tf.FixedLenFeature([], tf.string)}

                parsed_features = tf.parse_single_example(example_proto, features)

                # Reshape image data into the original shape
                image = tf.reshape(parsed_features['image'], [_input_shape[0], _input_shape[1], _label_channel], name='image')
                label = tf.reshape(parsed_features['label'], _input_shape, name='lable_reshape')
                mask  = tf.reshape(parsed_features['mask'],  _input_shape, name='mask_reshape')
                track = tf.reshape(parsed_features['track'], _input_shape, name='track_reshape')
                scanName = parsed_features['scanName']

                image = image + tf.constant(1., dtype=tf.float32)

                return image, label, mask, track, scanName

        training_filenames = glob(dir_join(_data_tfRecord_dir, _data_train, '*.tfrecords'))
        validation_filenames = glob(dir_join(_data_tfRecord_dir, _data_val, '*.tfrecords'))

        filenames = tf.placeholder(tf.string, shape=[None], name='filenames')
        dataset = tf.data.TFRecordDataset(filenames)

        dataset = dataset.map(_parse_function, num_parallel_calls=20)  # Parse the record into tensors.
        dataset = dataset.shuffle(buffer_size=10000)
        dataset = dataset.batch(_batch_size, drop_remainder=True)
        dataset = dataset.prefetch(buffer_size=10)
        iterator = dataset.make_initializable_iterator()

        next = iterator.get_next()
        sess = tf.Session()

        while True:
            sess.run(iterator.initializer, feed_dict={filenames: training_filenames})
            try:
                img, _, _, _, scanX = sess.run(next)
                for i, scan in enumerate(scanX):
                    print(scan.decode("utf-8"))
                    projection = np.load(dir_join(_data_npy_dir, scan.decode("utf-8") + '.npy'))
                    imagenp = projection[:,:,:_label_channel]

                    if np.abs(np.sum(img[i,...] - imagenp)) > 0.:
                        print(np.sum(img[i,...] - imagenp))

            except tf.errors.OutOfRangeError:
                break

    return training_filenames, validation_filenames, filenames, iterator

if __name__ == '__main__':
    numpy_to_TFRecord()
    readTFRecord()

我在前面的代码中所做的测试是将* .npy文件转换为* .tfrecords。然后,我将* .trecords与* .npy进行比较。如果两个图像相同,则该值应为0。

img, _, _, _, scanX = sess.run(next)
    for i, scan in enumerate(scanX):
         print(scan.decode("utf-8"))
         projection = np.load(dir_join(_data_npy_dir, scan.decode("utf-8") + '.npy'))
         imagenp = projection[:,:,:_label_channel]

         print(np.sum(img[i,...] - imagenp))

如果未对数据进行预处理,则这些图像是相同的,但是,如果我们执行某种转换,则结果将与预期的结果不符。在这种情况下,我们向图像的每个像素加1,因此总差应为64 * 512 * 5。

image = image + tf.constant(1., dtype=tf.float32)

我想解决这个错误,因为到目前为止,我还无法使用feed_dict代替Tensorflow Dataset API来获得由我的神经网络获得的结果,这是我可以观察到的唯一差异。输入数据。

0 个答案:

没有答案