Decoding tfrecord with tfslim - tensorflow

I use Python 2.7.13 and Tensorflow 1.3.0 on CPU.
I want to use DensNet( https://github.com/pudae/tensorflow-densenet ) for regression problem. My data contains 60000 jpeg images with 37 float labels for each image.
I saved my data into tfrecords files by:
def Read_Labels(label_path):
labels_csv = pd.read_csv(label_path)
labels = np.array(labels_csv)
return labels[:,1:]
`
def load_image(addr):
# read an image and resize to (224, 224)
img = cv2.imread(addr)
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32)
return img
def Shuffle_images_with_labels(shuffle_data, photo_filenames, labels):
if shuffle_data:
c = list(zip(photo_filenames, labels))
shuffle(c)
addrs, labels = zip(*c)
return addrs, labels
def image_to_tfexample_mine(image_data, image_format, height, width, label):
return tf.train.Example(features=tf.train.Features(feature={
'image/encoded': bytes_feature(image_data),
'image/format': bytes_feature(image_format),
'image/class/label': _float_feature(label),
'image/height': int64_feature(height),
'image/width': int64_feature(width),
}))
def _convert_dataset(split_name, filenames, labels, dataset_dir):
assert split_name in ['train', 'validation']
num_per_shard = int(math.ceil(len(filenames) / float(_NUM_SHARDS)))
with tf.Graph().as_default():
for shard_id in range(_NUM_SHARDS):
output_filename = _get_dataset_filename(dataset_path, split_name, shard_id)
with tf.python_io.TFRecordWriter(output_filename) as tfrecord_writer:
start_ndx = shard_id * num_per_shard
end_ndx = min((shard_id+1) * num_per_shard, len(filenames))
for i in range(start_ndx, end_ndx):
sys.stdout.write('\r>> Converting image %d/%d shard %d' % (
i+1, len(filenames), shard_id))
sys.stdout.flush()
img = load_image(filenames[i])
image_data = tf.compat.as_bytes(img.tostring())
label = labels[i]
example = image_to_tfexample_mine(image_data, image_format, height, width, label)
# Serialize to string and write on the file
tfrecord_writer.write(example.SerializeToString())
sys.stdout.write('\n')
sys.stdout.flush()
def run(dataset_dir):
labels = Read_Labels(dataset_dir + '/training_labels.csv')
photo_filenames = _get_filenames_and_classes(dataset_dir + '/images_training')
shuffle_data = True
photo_filenames, labels = Shuffle_images_with_labels(
shuffle_data,photo_filenames, labels)
training_filenames = photo_filenames[_NUM_VALIDATION:]
training_labels = labels[_NUM_VALIDATION:]
validation_filenames = photo_filenames[:_NUM_VALIDATION]
validation_labels = labels[:_NUM_VALIDATION]
_convert_dataset('train',
training_filenames, training_labels, dataset_path)
_convert_dataset('validation',
validation_filenames, validation_labels, dataset_path)
print('\nFinished converting the Flowers dataset!')
And I decode it by:
with tf.Session() as sess:
feature = {
'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
'image/format': tf.FixedLenFeature((), tf.string, default_value='jpeg'),
'image/class/label': tf.FixedLenFeature(
[37,], tf.float32, default_value=tf.zeros([37,], dtype=tf.float32)),
}
filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example, features=feature)
image = tf.decode_raw(features['image/encoded'], tf.float32)
print(image.get_shape())
label = tf.cast(features['image/class/label'], tf.float32)
image = tf.reshape(image, [224, 224, 3])
images, labels = tf.train.shuffle_batch([image, label], batch_size=10, capacity=30, num_threads=1, min_after_dequeue=10)
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for batch_index in range(6):
img, lbl = sess.run([images, labels])
img = img.astype(np.uint8)
print(img.shape)
for j in range(6):
plt.subplot(2, 3, j+1)
plt.imshow(img[j, ...])
plt.show()
coord.request_stop()
coord.join(threads)
It's all fine up to this point. But when I use the bellow commands for decoding TFRecord files:
reader = tf.TFRecordReader
keys_to_features = {
'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
'image/format': tf.FixedLenFeature((), tf.string, default_value='raw'),
'image/class/label': tf.FixedLenFeature(
[37,], tf.float32, default_value=tf.zeros([37,], dtype=tf.float32)),
}
items_to_handlers = {
'image': slim.tfexample_decoder.Image('image/encoded'),
'label': slim.tfexample_decoder.Tensor('image/class/label'),
}
decoder = slim.tfexample_decoder.TFExampleDecoder(
keys_to_features, items_to_handlers)
I get the following error.
INFO:tensorflow:Error reported to Coordinator: , assertion failed: [Unable to decode bytes as JPEG, PNG, GIF, or BMP]
[[Node: case/If_0/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert = Assert[T=[DT_STRING], summarize=3, _device="/job:localhost/replica:0/task:0/cpu:0"](case/If_0/decode_image/cond_jpeg/cond_png/cond_gif/is_bmp, case/If_0/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert/data_0)]]
INFO:tensorflow:Caught OutOfRangeError. Stopping Training.
INFO:sensorflow:Finished training! Saving model to disk.
To use Densenet for my problem, I should fix this error first.
Could anybody please help me out of this problem. This code works perfectly for the datasets like flowers, MNIST and CIFAR10 available at https://github.com/pudae/tensorflow-densenet/tree/master/datasets but does not work for my data.

Thanks to pudae, the problem is solved. I was needed to use:
image_data = tf.gfile.FastGFile(filenames[i], 'rb').read()
Instead of this for loading data. That works perfectly now.
img = load_image(filenames[i])
image_data = tf.compat.as_bytes(img.tostring())

According to the error, I think the problem is that you use an image decoder for array data (decoded data) because you saved decoded data when creating TFRecords. Maybe you have noticed, when you are not using slim, you use tf.decode_raw to decode the data. But when you use slim, the 'image/format': tf.FixedLenFeature((), tf.string, default_value='raw') is not used and by default, slim will use image decoder.
I believe you use the code in slim/data,
where format_key = 'image/format' is you need. So, like this:
keys_to_features = {
'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
'image/format': tf.FixedLenFeature((), tf.string, default_value='raw'),
'image/class/label': tf.FixedLenFeature(
[1], tf.int64, default_value=tf.zeros([1], dtype=tf.int64)),
}
items_to_handlers = {
'image': tfexample_decoder.Image(
image_key = 'image/encoded',
format_key = 'image/format',
'label': tfexample_decoder.Tensor('image/class/label'),
}
decoder = tfexample_decoder.TFExampleDecoder(
keys_to_features, items_to_handlers)
But I am not sure this can solve your problem perfectly because I can't reproduce your work in my machine.

Maybe there is a problem with your image itself as follows:

Related

How to freeze TensorFlow ckpt with queuerunner?

I used tf.train.shuffle_batch while training, and do not use any placeholder, when I freezed the ckpt to pb file, I did not get any input tensor, though I can feed thing to shuffle_batch tensor, but it need the feed has the same size with the shuffle_batch data. How to fix it? I know I can rewrite a net and restore params, then freeze, but it is not wise?
The train
import tensorflow as tf
import tensorlayer as tl
from tensorlayer.layers import *
import os
trainsize=35680
testsize=889
batch_size=32
inputW=224
inputH=480
TRAIN_TFRECORD='./train.tfrecords'
TEST_TFRECORD='./test.tfrecords'
BATCH_CAPACITY=512
MIN_AFTER_DEQU=256
MAX_Cycle=100000
TRAIN_CYCLE=int(trainsize/batch_size)
TEST_CYCLE=int(testsize/batch_size)
learning_rt = 0.001
savepath='./ckpt/'
logpath='./logs/'
def network(inputs,is_train,reuse):
BITW =8
BITA=8
Decay=0.99
Epsi=1e-5
with tf.variable_scope('Model',reuse=reuse):
net=InputLayer(inputs,name='input') #224*480
net=QuanConv2dWithBN(net,32,(3,3),(1,1),'SAME',tf.nn.relu, decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv1_1')
net=QuanConv2dWithBN(net,64,(3,3),(2,2),'SAME',tf.nn.relu, decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv1_2') #112*240
net=QuanConv2dWithBN(net,64,(3,3),(1,1),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv2_1')
net=QuanConv2dWithBN(net,128,(3,3),(2,2),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv2_2') #56*120
net=QuanConv2dWithBN(net,128,(3,3),(1,1),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv3_1')
net=QuanConv2dWithBN(net,64,(1,1),(1,1),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv3_2')
net=QuanConv2dWithBN(net,128,(3,3),(2,2),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv3_3') #28*60
net=QuanConv2dWithBN(net,64,(3,3),(1,1),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv4_1')
net=QuanConv2dWithBN(net,96,(3,3),(2,2),'VALID',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv4_2') #14*30
print(net.outputs)
net=QuanConv2dWithBN(net,128,(3,3),(2,2),'SAME',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv5_1') #7*30
net=QuanConv2dWithBN(net,128,(3,3),(1,2),'VALID',tf.nn.relu,decay=Decay, epsilon=Epsi, is_train=is_train, bitW=BITW,bitA=BITA,name='Conv5_2') #3*30
net=QuanConv2d(net,128,(3,3),(1,2),'VALID',tf.nn.leaky_relu,bitW=BITW,bitA=BITA,name='Conv5_3') #1*30
print(net.outputs)
net=FlattenLayer(net,name='flat1')
net=QuanDenseLayer(net,128,act=tf.nn.leaky_relu,bitW=BITW,bitA=BITA,name='dense1')
net=DropoutLayer(net,0.5,is_fix=True,is_train=is_train,name='drop1')
net=DenseLayer(net,1,name='dense2')
outnet=net
volcume=net.outputs
print(volcume)
return outnet,net.outputs,volcume
def inference(inputs,is_train,reuse):
return network(inputs,is_train,reuse)
def read_and_decode(filename):
filename_queue = tf.train.string_input_producer([filename])
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example,
features={
'img': tf.FixedLenFeature([], tf.string),
'num' : tf.FixedLenFeature([], tf.float32),
})
img = tf.decode_raw(features['img'], tf.uint8)
img = tf.reshape(img, [480, 240, 3])
img=tf.random_crop(img,[480,224,3])
img = tf.image.random_brightness(img, max_delta=0.3)
img = tf.image.random_contrast(img, lower=0.1, upper=0.5)
# img = tf.image.random_hue(img, max_delta=0.1)
# img = tf.image.random_saturation(img, lower=0, upper=2.5)
img = tf.image.per_image_standardization(img)
label = tf.reshape( tf.cast(features['num'], tf.float32)*(1./230.)-0.5,[1])
return img, label
def read_and_decode_test(filename):
filename_queue = tf.train.string_input_producer([filename])
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example,
features={
'img': tf.FixedLenFeature([], tf.string),
'num' : tf.FixedLenFeature([], tf.float32),
})
img = tf.decode_raw(features['img'], tf.uint8)
img = tf.reshape(img, [480, 240, 3])
img=img[:,8:232,:]
img = tf.image.per_image_standardization(img)
label = tf.reshape( tf.cast(features['num'], tf.float32)*(1./230.)-0.5,[1])
return img, label
def smooth_L1(x):
return tf.where(tf.less_equal(tf.abs(x), 1.0), tf.multiply(0.5, tf.pow(x, 2.0)), tf.subtract(tf.abs(x), 0.5))
def cal_loss(logits,labels):
# return tf.clip_by_value(tf.reduce_mean(tf.losses.mean_squared_error(labels,logits)) ,0.000001,10000000.)
return tf.reduce_mean(tf.where(tf.less_equal(tf.abs(logits-labels), 0.02),0.00001*tf.ones_like(logits-labels), tf.multiply(1., tf.pow(logits-labels, 2.0))))
# return tf.clip_by_value(tf.reduce_sum(smooth_L1(labels-logits)),0.0000001,100.)
def cal_acc(logits,labels):
return tf.reduce_mean( tf.cast( tf.less_equal(tf.abs(labels-logits),tf.ones_like(labels)*.1),tf.float32))
if __name__ == '__main__':
img_train,num_train = read_and_decode(TRAIN_TFRECORD)
img_test,num_test = read_and_decode(TEST_TFRECORD)
img_train_batch, num_train_batch = tf.train.shuffle_batch(
[img_train, num_train], batch_size=batch_size, capacity=BATCH_CAPACITY,
min_after_dequeue=MIN_AFTER_DEQU)
img_test_batch, num_test_batch = tf.train.batch(
[img_test,num_test], batch_size=batch_size)
net,_,logits_train=inference(img_train_batch,True,None)
_,_,logits_test=inference(img_test_batch,False,True)
loss_train=cal_loss(logits_train,num_train_batch)
loss_test=cal_loss(logits_test,num_test_batch)
acc_test=cal_acc(logits_test,num_test_batch)
acc_train=cal_acc(logits_train,num_train_batch)
global_step=tf.train.create_global_step()
#tf.train.get_global_step()
learning_rate=tf.train.exponential_decay(learning_rt, global_step,
5000, 0.9, staircase=True)
train = tf.train.MomentumOptimizer(learning_rate,momentum=0.9).minimize(loss_train,global_step=global_step)
# train = tf.train.AdamOptimizer(learning_rt).minimize(loss_train)
tf.summary.scalar('loss_train', loss_train)
tf.summary.scalar('acc_train', acc_train)
merged = tf.summary.merge_all()
with tf.Session(config=tf.ConfigProto()) as sess:
trainwrite = tf.summary.FileWriter(logpath, sess.graph)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
run_cycle=0
if os.path.exists(savepath+'313.ckpt.index') :
print('\nStart Restore')
saver.restore(sess, savepath+'33.ckpt')
print('\nEnd Restore')
print('\nStart Training')
try:
while not coord.should_stop():
while run_cycle < MAX_Cycle:
run_cycle+=1
# if run_cycle%10==0:
# learning_rt*=0.6
# if run_cycle%200==0:
# learning_rt*=2.
l_tall=0
a_tall=0
l_teall=0
a_teall=0
for train_c in range(TRAIN_CYCLE):
_,l_train,a_train=sess.run([train,loss_train,acc_train])
l_tall+=l_train
a_tall+=a_train
if (train_c+1)%100==0:
print('train_loss:%f'%(l_tall/100.))
print('train_acc:%f'%(a_tall/100.))
l_tall = 0
a_tall = 0
if (train_c+1)%500==0:
print('Global Step:',sess.run(global_step))
result_merged=sess.run(merged)
trainwrite.add_summary(result_merged, run_cycle*TRAIN_CYCLE+train_c)
for test_c in range(TEST_CYCLE):
l_test,a_test=sess.run([loss_test,acc_test])
l_teall+=l_test
a_teall+=a_test
if (test_c+1)%TEST_CYCLE==0:
print('------------------')
print('test_loss:%f'%(l_teall/TEST_CYCLE))
print('test_acc:%f'%(a_teall/TEST_CYCLE))
print('------------------')
l_teall = 0
l_teall = 0
saver.save(sess, savepath+ str(run_cycle) + '.ckpt')
except tf.errors.OutOfRangeError:
print('Done training!!!')
finally:
# When done, ask the threads to stop.
coord.request_stop()
coord.join(threads)
sess.close()
Freeze code
import os, argparse
import tensorflow as tf
from tensorflow.python.framework import graph_util
dir = os.path.dirname(os.path.realpath(__file__))
def freeze_graph(model_folder, output_nodes='y_hat',
output_filename='frozen-graph.pb',
rename_outputs=None):
# Load checkpoint
checkpoint = tf.train.get_checkpoint_state(model_folder)
input_checkpoint = checkpoint.model_checkpoint_path
output_graph = output_filename
# Devices should be cleared to allow Tensorflow to control placement of
# graph when loading on different machines
saver = tf.train.import_meta_graph(input_checkpoint + '.meta',
clear_devices=True)
graph = tf.get_default_graph()
onames = output_nodes.split(',')
# https://stackoverflow.com/a/34399966/4190475
if rename_outputs is not None:
nnames = rename_outputs.split(',')
with graph.as_default():
for o, n in zip(onames, nnames):
_out = tf.identity(graph.get_tensor_by_name(o + ':0'), name=n)
onames = nnames
input_graph_def = graph.as_graph_def()
# fix batch norm nodes
for node in input_graph_def.node:
if node.op == 'RefSwitch':
node.op = 'Switch'
for index in range(len(node.input)):
if 'moving_' in node.input[index]:
node.input[index] = node.input[index] + '/read'
elif node.op == 'AssignSub':
node.op = 'Sub'
if 'use_locking' in node.attr: del node.attr['use_locking']
with tf.Session(graph=graph) as sess:
saver.restore(sess, input_checkpoint)
# In production, graph weights no longer need to be updated
# graph_util provides utility to change all variables to constants
output_graph_def = graph_util.convert_variables_to_constants(
sess, input_graph_def,
onames # unrelated nodes will be discarded
)
# Serialize and write to file
with tf.gfile.GFile(output_graph, "wb") as f:
f.write(output_graph_def.SerializeToString())
print("%d ops in the final graph." % len(output_graph_def.node))
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Prune and freeze weights from checkpoints into production models')
parser.add_argument("--checkpoint_path",
default='./regressionDir/',
type=str, help="Path to checkpoint files")
parser.add_argument("--output_nodes",
default='Model/dense2/bias_add',
type=str, help="Names of output node, comma seperated")
parser.add_argument("--output_graph",
default='reg.pb',
type=str, help="Output graph filename")
parser.add_argument("--rename_outputs",
default='out_vol',
type=str, help="Rename output nodes for better \
readability in production graph, to be specified in \
the same order as output_nodes")
args = parser.parse_args()
freeze_graph(args.checkpoint_path, args.output_nodes, args.output_graph, args.rename_outputs)
Test inference code
import tensorflow as tf
import numpy as np
from PIL import Image
import time
gf = tf.GraphDef()
gf.ParseFromString(open('reg.pb', 'rb').read())
print([n.name + '=>' + n.op for n in gf.node])
output_graph_path = './reg.pb'
with tf.Session() as sess:
tf.global_variables_initializer().run()
output_graph_def = tf.GraphDef()
with open(output_graph_path, "rb") as f:
output_graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(output_graph_def, name="")
input_img = sess.graph.get_tensor_by_name("shuffle_batch:0")
print(input_img)
out_vol = sess.graph.get_tensor_by_name("out_vol:0")
out_voln = sess.graph.get_tensor_by_name("shuffle_batch:0")
a = np.random.random([48, 480, 224, 3])
for x in range(100):
ntime1 = time.time()
vol = sess.run(out_vol, {input_img: a})
ntime2 = time.time()
print(ntime2 - ntime1)

tf.data API read the TFRecord files

I am trying to use the tf.data API read the TFRecord file.
import tensorflow as tf
from PIL import Image
import numpy as np
import os
def train_input_fn():
filenames = ["mytrain.tfrecords"]
dataset = tf.data.TFRecordDataset(filenames)
def parser(record):
keys_to_features = {
"image_data": tf.FixedLenFeature((), tf.string, default_value=""),
"date_time": tf.FixedLenFeature((), tf.int64, default_value=""),
"label": tf.FixedLenFeature((), tf.int64,
default_value=tf.zeros([], dtype=tf.int64)),
}
parsed = tf.parse_single_example(record, keys_to_features)
image = tf.decode_jpeg(parsed["image_data"])
image = tf.reshape(image, [128, 128, 3])
label = tf.cast(parsed["label"], tf.int32)
return {"image_data": image, "date_time": parsed["date_time"]}, label
dataset = dataset.map(parser)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
dataset = dataset.repeat(1)
iterator = dataset.make_one_shot_iterator()
features, labels = iterator.get_next()
return features, labels
output = train_input_fn()
init_op = 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)
for i in range(230):
image, label = sess.run(output)
img = Image.fromarray(image, 'RGB')
img.save(cwd+str(i) + '_''Label_'+str(l)+'.jpg')
print(image, label)
coord.request_stop()
coord.join(threads)
Traceback (most recent call last):
File "E:/Tensorflow/Wenshan_Cai_Nanoletters/tf_data.py", line 34, in
output = train_input_fn()
File "E:/Tensorflow/Wenshan_Cai_Nanoletters/tf_data.py", line 25, in train_input_fn
TypeError: Expected int64, got '' of type 'str' instead.
Note TypeError: Expected int64, got '' of type 'str' instead from your error log. You have a bug in your code.
The bug
In the following line:
"date_time": tf.FixedLenFeature((), tf.int64, default_value=""),
The default value for a tf.int64 type variable is specified as a string "".
A fix
So say your expected default is 0, then you should change line to:
"date_time": tf.FixedLenFeature((), tf.int64, default_value=0),
Hope that helps.

tf.contrib.data.TFRecordDataset not able to read from *.tfrecord

In the context of creating and loading a .tfrecord file i encountered the following Problem:
Generating the dataset.tfrecord file
The Folder /Batch_manager/assets contains some *.tif Images that are used to generate a dataset.tfrecord file:
def _save_as_tfrecord(self, path, name):
self.__filename = os.path.join(path, name + '.tfrecord')
writer = tf.python_io.TFRecordWriter(self.__filename)
print('Writing', self.__filename)
for index, img in enumerate(self.load(get_iterator=True, n_images=1)):
img = img[0]
image_raw = img.tostring()
rows = img.shape[0]
cols = img.shape[1]
try:
depth = img.shape[2]
except IndexError:
depth = 1
example = tf.train.Example(features=tf.train.Features(feature={
'height': self._int64_feature(rows),
'width': self._int64_feature(cols),
'depth': self._int64_feature(depth),
'label': self._int64_feature(int(self.target[index])),
'image_raw': self._bytes_feature(image_raw)
}))
writer.write(example.SerializeToString())
writer.close()
Reading from the dataset.tfrecord file
Next i try to read from this file using where path directs towards the dataset.tfrecord file:
def dataset_input_fn(self, path):
dataset = tf.contrib.data.TFRecordDataset(path)
def parser(record):
keys_to_features = {
"height": tf.FixedLenFeature((), tf.int64, default_value=""),
"width": tf.FixedLenFeature((), tf.int64, default_value=""),
"depth": tf.FixedLenFeature((), tf.int64, default_value=""),
"label": tf.FixedLenFeature((), tf.int64, default_value=""),
"image_raw": tf.FixedLenFeature((), tf.string, default_value=""),
}
print(record)
features = tf.parse_single_example(record, features=keys_to_features)
print(features)
label = features['label']
height = features['height']
width = features['width']
depth = features['depth']
image = tf.decode_raw(features['image_raw'], tf.float32)
image = tf.reshape(image, [height, width, -1])
label = tf.cast(features["label"], tf.int32)
return {"image_raw": image, "height": height, "width": width, "depth":depth, "label":label}
dataset = dataset.map(parser)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
iterator = dataset.make_one_shot_iterator()
# `features` is a dictionary in which each value is a batch of values for
# that feature; `labels` is a batch of labels.
features = iterator.get_next()
return Features
Error message:
TypeError: Expected int64, got '' of type 'str' instead.
What is wrong with this Piece of code? I successfully validated that the dataset.tfrecord actually contains the correct Images and meta data!
The error happens because i copy and pasted this example which sets the values for all key-value pairs to an empty string, caused by default_value="". Removing that from all tf.FixedLenFeature fixed the issue.

Tensorflow, read tfrecord without a graph

I tried to write a good structured Neural network model with Tensorflow. But I met a problem about feed the data from tfrecord into the graph. The code is as below, it hangs on at the following function, how can I make it work?
images, labels = network.load_tfrecord_data(1)
this function can not get the features (images) and labels from my datafile, .tfrecords?
Any idea will be appreciated?
from __future__ import division
from __future__ import print_function
import datetime
import numpy as np
import tensorflow as tf
layers = tf.contrib.layers
losses = tf.contrib.losses
metrics = tf.contrib.metrics
LABELS = 10
WIDTH = 28
HEIGHT = 28
HIDDEN = 100
def read_and_decode_single_example(filename):
filename_queue = tf.train.string_input_producer([filename], num_epochs=None)
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(
serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'image': tf.FixedLenFeature([50176], tf.int64)
})
label = features['label']
image = features['image']
image = tf.reshape(image, [-1, 224, 224, 1])
label = tf.one_hot(label - 1, 11, dtype=tf.int64)
return label, image
class Network:
def __init__(self, logdir, experiment, threads):
# Construct the graph
with tf.name_scope("inputs"):
self.images = tf.placeholder(tf.float32, [None, WIDTH, HEIGHT, 1], name="images")
self.labels = tf.placeholder(tf.int64, [None], name="labels")
# self.keep_prob = keep_prob
self.keep_prob = tf.placeholder(tf.float32, name="keep_prob")
flattened_images = layers.flatten(self.images)
hidden_layer = layers.fully_connected(flattened_images, num_outputs=HIDDEN, activation_fn=tf.nn.relu, scope="hidden_layer")
output_layer = layers.fully_connected(hidden_layer, num_outputs=LABELS, activation_fn=None, scope="output_layer")
loss = losses.sparse_softmax_cross_entropy(labels=self.labels, logits=output_layer, scope="loss")
self.training = layers.optimize_loss(loss, None, None, tf.train.AdamOptimizer(), summaries=['loss', 'gradients', 'gradient_norm'], name='training')
with tf.name_scope("accuracy"):
predictions = tf.argmax(output_layer, 1, name="predictions")
accuracy = metrics.accuracy(predictions, self.labels)
tf.summary.scalar("training/accuracy", accuracy)
self.accuracy = metrics.accuracy(predictions, self.labels)
with tf.name_scope("confusion_matrix"):
confusion_matrix = metrics.confusion_matrix(predictions, self.labels, weights=tf.not_equal(predictions, self.labels), dtype=tf.float32)
confusion_image = tf.reshape(confusion_matrix, [1, LABELS, LABELS, 1])
# Summaries
self.summaries = {'training': tf.summary.merge_all() }
for dataset in ["dev", "test"]:
self.summaries[dataset] = tf.summary.scalar(dataset + "/loss", loss)
self.summaries[dataset] = tf.summary.scalar(dataset + "/accuracy", accuracy)
self.summaries[dataset] = tf.summary.image(dataset + "/confusion_matrix", confusion_image)
# Create the session
self.session = tf.Session(config=tf.ConfigProto(inter_op_parallelism_threads=threads,
intra_op_parallelism_threads=threads))
self.session.run(tf.global_variables_initializer())
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S")
self.summary_writer = tf.summary.FileWriter("{}/{}-{}".format(logdir, timestamp, experiment), graph=self.session.graph, flush_secs=10)
self.steps = 0
def train(self, images, labels, keep_prob):
self.steps += 1
feed_dict = {self.images: self.session.run(images), self.labels: self.session.run(labels), self.keep_prob: keep_prob}
if self.steps == 1:
metadata = tf.RunMetadata()
self.session.run(self.training, feed_dict, options=tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE), run_metadata=metadata)
self.summary_writer.add_run_metadata(metadata, 'step1')
elif self.steps % 100 == 0:
_, summary = self.session.run([self.training, self.summaries['training']], feed_dict)
self.summary_writer.add_summary(summary, self.steps)
else:
self.session.run(self.training, feed_dict)
def evaluate(self, dataset, images, labels):
feed_dict ={self.images: images, self.labels: labels, self.keep_prob: 1}
summary = self.summaries[dataset].eval({self.images: images, self.labels: labels, self.keep_prob: 1}, self.session)
self.summary_writer.add_summary(summary, self.steps)
def load_tfrecord_data(self, training):
training = training
if training:
label, image = read_and_decode_single_example("mhad_Op_train.tfrecords")
# print(self.session.run(image))
else:
label, image = read_and_decode_single_example("mhad_Op_test.tfrecords")
# image = tf.cast(image, tf.float32) / 255.
images_batch, labels_batch = tf.train.shuffle_batch(
[image, label], batch_size=50, num_threads=2,
capacity=80,
min_after_dequeue=30)
return images_batch, labels_batch
if __name__ == '__main__':
# Fix random seed
np.random.seed(42)
tf.set_random_seed(42)
# Parse arguments
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=256, type=int, help='Batch size.')
parser.add_argument('--epochs', default=50, type=int, help='Number of epochs.')
parser.add_argument('--logdir', default="logs", type=str, help='Logdir name.')
parser.add_argument('--exp', default="mnist-final-confusion_matrix_customized_loss", type=str, help='Experiment name.')
parser.add_argument('--threads', default=1, type=int, help='Maximum number of threads to use.')
args = parser.parse_args()
# Load the data
keep_prob = 1
# Construct the network
network = Network(logdir=args.logdir, experiment=args.exp, threads=args.threads)
# Train
for i in range(args.epochs):
images, labels = network.load_tfrecord_data(1)
network.train(images, labels, keep_prob)
print('current epoch', i)
You need to start the queue before using images, labels in your model.
with tf.Session() as sess:
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
images, labels = network.load_tfrecord_data(1)
...
coord.request_stop()
coord.join(threads)
Check this tutorial for a full example

How to get misclassified files in TF-Slim's eval_image_classifier.py?

I'm using a script that comes with TF-Slim to validate my trained model. It works fine but I'd like to get a list of the misclassified files.
The script makes use of https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/slim/python/slim/evaluation.py but even there I cannot find any options for printing the misclassified files.
How can I achieve that?
At a high level, you need to do 3 things:
1) Get your filename from the data loader. If you are using a tf-slim dataset from tfrecords, it is likely that the filenames are not stored in the tfrecord so you may be out of luck there. However if you are consuming image files directly from the filesystem with tf.WholeFileReader, then you can get the tensor of filenames where you form your batch:
def load_data():
train_image_names = ... # list of filenames
filename_queue = tf.train.string_input_producer(train_image_names)
reader = tf.WholeFileReader()
image_filename, image_file = reader.read(filename_queue)
image = tf.image.decode_jpeg(image_file, channels=3)
.... # load your labels from somewhere
return image_filename, image, label
# in your eval code
image_fn, image, label = load_data()
filenames, images, labels = tf.train.batch(
[image_fn, image, label],
batch_size=32,
num_threads=2,
capacity=100,
allow_smaller_final_batch=True)
2) Mask your filename tensor with your result after doing inference:
logits = my_network(images)
preds = tf.argmax(logits, 1)
mislabeled = tf.not_equal(preds, labels)
mislabeled_filenames = tf.boolean_mask(filenames, mislabeled)
3) Put all this into your eval_op:
eval_op = tf.Print(eval_op, [mislabeled_filenames])
slim.evaluation.evaluate_once(
.... # other options
eval_op=eval_op,
.... # other options)
I don't have a setup to test this, unfortunately. Let me know if it works!
shadow chris pointed me in the right direction so I share my solution to make it work with a TF-records dataset.
For better unstanding I relate my code to the flower example of TF-Slim.
1) Modify your dataset script to store a filename feature in the TF-records.
keys_to_features = {
'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
'image/format': tf.FixedLenFeature((), tf.string, default_value='png'),
'image/class/label': tf.FixedLenFeature(
[], tf.int64, default_value=tf.zeros([], dtype=tf.int64)),
'image/filename': tf.FixedLenFeature((), tf.string, default_value=''),
}
items_to_handlers = {
'image': slim.tfexample_decoder.Image(),
'label': slim.tfexample_decoder.Tensor('image/class/label'),
'filename': slim.tfexample_decoder.Tensor('image/filename'),
}
2) Add filename parameter to data util's image_to_tfexample function
It should then look like:
def image_to_tfexample(image_data, image_format, height, width, class_id, filename):
return tf.train.Example(features=tf.train.Features(feature={
'image/encoded': bytes_feature(image_data),
'image/format': bytes_feature(image_format),
'image/class/label': int64_feature(class_id),
'image/height': int64_feature(height),
'image/width': int64_feature(width),
'image/filename': bytes_feature(filename)
}))
3) Modify download and convert script to save filenames
Feed your TF record with the filename.
example = dataset_utils.image_to_tfexample(
image_data, 'jpg', height, width, class_id, filenames[i])
4) In your evaluation map misclassified imgs to filename
I'm refering to eval_image_classifier.py.
Retrieve filenames with tf.train.batch:
images, labels, filenames = tf.train.batch(
[image, label, filename],
batch_size=FLAGS.batch_size,
num_threads=FLAGS.num_preprocessing_threads,
capacity=5 * FLAGS.batch_size)
Get misclassified imgs and map them to filenames:
predictions = tf.argmax(logits, 1)
labels = tf.squeeze(labels)
mislabeled = tf.not_equal(predictions, labels)
mislabeled_filenames = tf.boolean_mask(filenames, mislabeled)
Print:
eval_op = tf.Print(eval_op, [mislabeled_filenames])
slim.evaluation.evaluate_once(
.... # other options
eval_op=eval_op,
.... # other options)