制作数据集-解析篇
1、數據集生成讀取文件(mnist_generateds.py)
tfrecords 文件
1)tfrecords:是一種二進制文件,可先將圖片和標簽制作成該格式的文件。使用 tfrecords 進行數據讀取,會提高內存利用率。?
2)tf.train.Example: 用來存儲訓練數據。訓練數據的特征用鍵值對的形式表示。如:‘ img_raw ’ :值 ‘ label ’ :值 值是 Byteslist/FloatList/Int64List?
3)SerializeToString( ):把數據序列化成字符串存儲。
首先生成 tfrecords 文件 :
1)將數據集的相關路徑定義好
2)讀訓練集和測試集;
讀文件解析
a:先讀入文件名,路徑
b:新建一個writer,計數次數
c:?在open函數中默認為只讀形式打開label_path,readlines()?方法用于讀取所有行(直到結束符 EOF)并返回列表,該列表可以由 Python 的 for... in ... 結構進行處理。如果碰到結束符 EOF 則返回空字符串。
d:for 循環遍歷每張圖和標簽
f:
example = tf.train.Example(features=tf.train.Features(feature={'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),'label': tf.train.Feature(int64_list=tf.train.Int64List(value=labels))}))這段代碼將在tf.train.examle函數中講解
e: writer.write(example.SerializeToString())? ?# 把 example 進行序列化? image_train_path='./data/mnist_data_jpg/mnist_train_jpg_60000/' label_train_path='./data/mnist_data_jpg/mnist_train_jpg_60000.txt' tfRecord_train='./data/mnist_train.tfrecords' image_test_path='./data/mnist_data_jpg/mnist_test_jpg_10000/' label_test_path='./data/mnist_data_jpg/mnist_test_jpg_10000.txt' tfRecord_test='./data/mnist_test.tfrecords' data_path='./data' resize_height = 28 resize_width = 28#生成tfrecords文件 def write_tfRecord(tfRecordName, image_path, label_path):#新建一個writerwriter = tf.python_io.TFRecordWriter(tfRecordName) num_pic = 0 f = open(label_path, 'r')contents = f.readlines()f.close()#循環遍歷每張圖和標簽 for content in contents:value = content.split()img_path = image_path + value[0] img = Image.open(img_path)img_raw = img.tobytes() labels = [0] * 10 labels[int(value[1])] = 1 #把每張圖片和標簽封裝到example中 example = tf.train.Example(features=tf.train.Features(feature={'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])),'label': tf.train.Feature(int64_list=tf.train.Int64List(value=labels))})) #把example進行序列化 writer.write(example.SerializeToString())num_pic += 1 print ("the number of picture:", num_pic)#關閉writer writer.close()print("write tfrecord successful")def generate_tfRecord():isExists = os.path.exists(data_path) if not isExists: os.makedirs(data_path)print 'The directory was created successfully'else:print 'directory already exists' write_tfRecord(tfRecord_train, image_train_path, label_train_path)write_tfRecord(tfRecord_test, image_test_path, label_test_path)
解析tfrecords文件:
先看一下對應的路徑文件名:
image_train_path='./data/mnist_data_jpg/mnist_train_jpg_60000/' label_train_path='./data/mnist_data_jpg/mnist_train_jpg_60000.txt' tfRecord_train='./data/mnist_train.tfrecords' image_test_path='./data/mnist_data_jpg/mnist_test_jpg_10000/' label_test_path='./data/mnist_data_jpg/mnist_test_jpg_10000.txt' tfRecord_test='./data/mnist_test.tfrecords' data_path='./data' def main(): generate_tfRecord() (1)def generate_tfRecord(): (2) isExists = os.path.exists(data_path) if not isExists: os.makedirs(data_path)print 'The directory was created successfully'else:print 'directory already exists' def get_tfrecord(num, isTrain=True): (1)
if isTrain:
tfRecord_path = tfRecord_train
else:
tfRecord_path = tfRecord_test
img, label = read_tfRecord(tfRecord_path) (2) def read_tfRecord(tfRecord_path): (3) filename_queue = tf.train.string_input_producer([tfRecord_path], shuffle=True)#新建一個readerreader = tf.TFRecordReader()
上面用顏色標記了一些參數的傳遞情況;
下面從主函數談起:
main函數調用了generate_tfRecord()函數,在該函數中使用write_tfRecord()寫入相關數據集到tfRecord中; get_tfrecord函數獲取被寫入的數據集的tfRecord的地址tfRecord_path = tfRecord_train (tfRecord_path = tfRecord_test ),使用read_tfRecord()函數讀取信息。
在read_tfRecord()函數中;
? ? ? ? ? 1)filename_queue = tf.train.string_input_producer([tfRecord_path])
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?tf.train.string_input_producer( string_tensor,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?num_epochs=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?shuffle=True,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?seed=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capacity=32,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shared_name=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cancel_op=None)
? ? ? ?該函數會生成一個先入先出的隊列,文件閱讀器會使用它來讀取數據。
? ? ? ?參數說明:string_tensor: 存儲圖像和標簽信息的 TFRecord 文件名列表
? ? ? ? ? ? ? ? ? ? ? ? ?num_epochs: 循環讀取的輪數(可選)
? ? ? ? ? ? ? ? ? ? ? ? ?shuffle:布爾值(可選),如果為 True,則在每輪隨機打亂讀取順序
? ? ? ? ? ? ? ? ? ? ? ? ?seed:隨機讀取時設置的種子(可選)
? ? ? ? ? ? ? ? ? ? ? ? ?capacity:設置隊列容量
? ? ? ? ? ? ? ? ? ? ? ? ?shared_name:(可選) 如果設置,該隊列將在多個會話中以給定名稱共享。所有具有此隊列的設備都可以通過 shared_name 訪問它。在分布式設置中使用這種方法意味著每
個名稱只能被訪問此操作的其中一個會話看到。?
? ? ? ? ? ? ? ? ? ? ? ? name:操作的名稱(可選)
? ? ? ? ? ? ? ? ? ? ? ? cancel_op:取消隊列(None)
? ? ? 2)reader = tf.TFRecordReader() #新建一個 reader
? ? ? 3)_, serialized_example = reader.read(filename_queue)
? ? ? ? ? features = tf.parse_single_example(serialized_example,features={
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'img_raw': tf.FixedLenFeature([ ], tf.string) ,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'label': tf.FixedLenFeature([10], tf.int64)})
? ? ? ? ? ? ? ? ? ? ? ? ? #把讀出的每個樣本保存在 serialized_example 中進行解序列化,標簽和圖片的鍵名應該和制作 tfrecords 的鍵名相同,其中標簽給出幾分類。?
? ? ? ? ?tf.parse_single_example(serialized,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?features,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?name=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?example_names=None)
? ? ? ? ? ?該函數可以將 tf.train.Example 協議內存塊(protocol buffer)解析為張量。
? ? ? ? ? ? ? ? ? 參數說明:serialized: 一個標量字符串張量
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? features: 一個字典映射功能鍵 FixedLenFeature 或 VarLenFeature值,也就是在協議內存塊中儲存的?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name:操作的名稱(可選)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? example_names: 標量字符串聯的名稱(可選)
? ? ? ? 4)img = tf.decode_raw(features['img_raw'], tf.uint8)
? ? ? ? ? ? ? ? ? ? ? ? ?#將 img_raw 字符串轉換為 8 位無符號整型
? ? ? ?5)img.set_shape([784]) #將形狀變為一行 784 列
? ? ? ?6)img = tf.cast(img, tf.float32) * (1. / 255) #變成 0 到 1 之間的浮點數
? ? ? ?7)label = tf.cast(features['label'], tf.float32)#把標簽列表變為浮點數
? ? ? ?8)return image,label #返回圖片和標簽(跳回到 get_tfrecord)
? ? ? ?9) tf.train.shuffle_batch( tensors,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? batch_size,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capacity,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? min_after_dequeue,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? num_threads=1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? seed=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enqueue_many=False,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shapes=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allow_smaller_final_batch=False,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shared_name=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?name=None)
? ? 這個函數隨機讀取一個 batch 的數據。
? ? ? ? ? ? ? ? ?參數說明:tensors: 待亂序處理的列表中的樣本(圖像和標簽)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? batch_size: 從隊列中提取的新批量大小
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?capacity:隊列中元素的最大數量
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?min_after_dequeue: 出隊后隊列中的最小數量元素,用于確保元素的混合級別
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?num_threads: 排列 tensors 的線程數
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?seed:用于隊列內的隨機洗牌
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enqueue_many: tensor 中的每個張量是否是一個例子
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shapes: 每個示例的形狀
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allow_smaller_final_batch: (可選)布爾值。 如果為 True,則在隊列中剩余數量不足時允許最終批次更小。?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shared_name:(可選)如果設置,該隊列將在多個會話中以給定名稱共享。?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name:操作的名稱(可選)
? ? ? ? ? 10)return img_batch,label_batch? ? ? ? ? ? ?#返回的圖片和標簽為隨機抽取的 batch_size 組
2.反向傳播文件修改圖片標簽獲取的接口(mnist_backward.py)?
關鍵操作:利用多線程提高圖片和標簽的批獲取效率? ? ? ?方法:將批獲取的操作放到線程協調器開啟和關閉之間?
開啟線程協調器:
? ? ?coord = tf.train.Coordinator( )
? ? ?threads = tf.train.start_queue_runners(sess=sess, coord=coord)
關閉線程協調器:
? ? ?coord.request_stop( )
? ? ?coord.join(threads)
注解:
? ? ?tf.train.start_queue_runners( sess=None,
? ? ?coord=None,
? ? daemon=True,
? ? start=True,
? ? collection=tf.GraphKeys.QUEUE_RUNNERS)
這個函數將會啟動輸入隊列的線程,填充訓練樣本到隊列中,以便出隊操作可以從隊列中拿到樣本。這種情況下最好配合使用一個 tf.train.Coordinator ,這
樣可以在發生錯誤的情況下正確地關閉這些線程。
參數說明:sess:用于運行隊列操作的會話。 默認為默認會話。
? ? ? ? ? ? ? ? ? coord:可選協調器,用于協調啟動的線程。
? ? ? ? ? ? ? ? ? ?daemon: 守護進程,線程是否應該標記為守護進程,這意味著它們不會阻止程序退出。?
? ? ? ? ? ? ? ? ? ?start:設置為 False 只創建線程,不啟動它們。
? ? ? ? ? ? ? ? ? collection:指定圖集合以獲取啟動隊列的 GraphKey。默認為GraphKeys.QUEUE_RUNNERS。
1)TEST_NUM=10000
之前:用 mnist.test.num_examples 表示總樣本數;
現在:要手動給出測試的總樣本數,這個數是 1 萬。
2)image_batch, label_batch=mnist_generateds.get_tfrecord(TEST_NUM, isTrain=False)?
之前:用 mnist.test.next_batch 函數讀出圖片和標簽喂給網絡;
現在:用函數 get_tfrecord 替換讀取所有測試集 1 萬張圖片。
isTrain:用來區分訓練階段和測試階段,True 表示訓練,False 表示測試。
3)xs,ys=sess.run([img_batch,label_batch])
之前:使用函數 xs,ys=mnist.test.next_batch(BATCH_SIZE)
現在:在 sess.run 中執行圖片和標簽的批獲取。
?
轉載于:https://www.cnblogs.com/fcfc940503/p/11019441.html
總結
- 上一篇: C# C/S 图片验证码功能源码
- 下一篇: freemarker list size