Tensorflow之構建自己的圖片資料集
阿新 • • 發佈:2019-02-08
用了這麼久的tensorflow,例子跑了N多便,基本流程是清楚了。但是自己獨立做一個小例子各種問題都來了。如自己圖片資料集怎麼做?說句老實話,tensorflow真是煩,管方文件教程上老拿MNIST和cifar_10這種做好的資料集說事,對於我們這些初學者,完全不知道圖片該如何輸入。今天給大家分享我的Tensorflow製作資料集的學習歷程。
流程是:製作資料集—讀取資料集—-加入佇列
先貼完整的程式碼:
#encoding=utf-8
import os
import tensorflow as tf
from PIL import Image
cwd = os.getcwd()
classes = {'test' ,'test1','test2'}
#製作二進位制資料
def create_record():
writer = tf.python_io.TFRecordWriter("train.tfrecords")
for index, name in enumerate(classes):
class_path = cwd +"/"+ name+"/"
for img_name in os.listdir(class_path):
img_path = class_path + img_name
img = Image.open(img_path)
img = img.resize((64 , 64))
img_raw = img.tobytes() #將圖片轉化為原生bytes
print index,img_raw
example = tf.train.Example(
features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw' : tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}))
writer.write(example.SerializeToString())
writer.close()
data = create_record()
#讀取二進位制資料
def read_and_decode(filename):
# 建立檔案佇列,不限讀取的數量
filename_queue = tf.train.string_input_producer([filename])
# create a reader from file queue
reader = tf.TFRecordReader()
# reader從檔案佇列中讀入一個序列化的樣本
_, serialized_example = reader.read(filename_queue)
# get feature from serialized example
# 解析符號化的樣本
features = tf.parse_single_example(
serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'img_raw': tf.FixedLenFeature([], tf.string)
}
)
label = features['label']
img = features['img_raw']
img = tf.decode_raw(img, tf.uint8)
img = tf.reshape(img, [64, 64, 3])
img = tf.cast(img, tf.float32) * (1. / 255) - 0.5
label = tf.cast(label, tf.int32)
return img, label
if __name__ == '__main__':
if 0:
data = create_record("train.tfrecords")
else:
img, label = read_and_decode("train.tfrecords")
print "tengxing",img,label
#使用shuffle_batch可以隨機打亂輸入 next_batch挨著往下取
# shuffle_batch才能實現[img,label]的同步,也即特徵和label的同步,不然可能輸入的特徵和label不匹配
# 比如只有這樣使用,才能使img和label一一對應,每次提取一個image和對應的label
# shuffle_batch返回的值就是RandomShuffleQueue.dequeue_many()的結果
# Shuffle_batch構建了一個RandomShuffleQueue,並不斷地把單個的[img,label],送入佇列中
img_batch, label_batch = tf.train.shuffle_batch([img, label],
batch_size=4, capacity=2000,
min_after_dequeue=1000)
# 初始化所有的op
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
# 啟動佇列
threads = tf.train.start_queue_runners(sess=sess)
for i in range(5):
print img_batch.shape,label_batch
val, l = sess.run([img_batch, label_batch])
# l = to_categorical(l, 12)
print(val.shape, l)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
製作資料集
#製作二進位制資料
def create_record():
cwd = os.getcwd()
classes = {'1','2','3'}
writer = tf.python_io.TFRecordWriter("train.tfrecords")
for index, name in enumerate(classes):
class_path = cwd +"/"+ name+"/"
for img_name in os.listdir(class_path):
img_path = class_path + img_name
img = Image.open(img_path)
img = img.resize((28, 28))
img_raw = img.tobytes() #將圖片轉化為原生bytes
#print index,img_raw
example = tf.train.Example(
features=tf.train.Features(
feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}
)
)
writer.write(example.SerializeToString())
writer.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
TFRecords檔案包含了tf.train.Example 協議記憶體塊(protocol buffer)(協議記憶體塊包含了欄位 Features)。我們可以寫一段程式碼獲取你的資料, 將資料填入到Example協議記憶體塊(protocol buffer),將協議記憶體塊序列化為一個字串, 並且通過tf.python_io.TFRecordWriter 寫入到TFRecords檔案。
讀取資料集
#讀取二進位制資料
def read_and_decode(filename):
# 建立檔案佇列,不限讀取的數量
filename_queue = tf.train.string_input_producer([filename])
# create a reader from file queue
reader = tf.TFRecordReader()
# reader從檔案佇列中讀入一個序列化的樣本
_, serialized_example = reader.read(filename_queue)
# get feature from serialized example
# 解析符號化的樣本
features = tf.parse_single_example(
serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'img_raw': tf.FixedLenFeature([], tf.string)
}
)
label = features['label']
img = features['img_raw']
img = tf.decode_raw(img, tf.uint8)
img = tf.reshape(img, [64, 64, 3])
img = tf.cast(img, tf.float32) * (1. / 255) - 0.5
label = tf.cast(label, tf.int32)
return img, label
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
一個Example中包含Features,Features裡包含Feature(這裡沒s)的字典。最後,Feature裡包含有一個 FloatList, 或者ByteList,或者Int64List
加入佇列
with tf.Session() as sess:
sess.run(init)
# 啟動佇列
threads = tf.train.start_queue_runners(sess=sess)
for i in range(5):
print img_batch.shape,label_batch
val, l = sess.run([img_batch, label_batch])
# l = to_categorical(l, 12)
print(val.shape, l)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
這樣就可以的到和tensorflow官方的二進位制資料集了,
注意:
- 啟動佇列那條code不要忘記,不然卡死
- 使用的時候記得使用val和l,不然會報型別錯誤:TypeError: The value of a feed cannot be a tf.Tensor object. Acceptable feed values include Python scalars, strings, lists, or numpy ndarrays.
- 算交叉熵時候:cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits,labels)算交叉熵
最後評估的時候用tf.nn.in_top_k(logits,labels,1)選logits最大的數的索引和label比較 - cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))算交叉熵,所以label必須轉成one-hot向量