圖像分類數據組織方式

一.npy輸入數據格式python

數據文件夾組織形式git

——————————flower
————————rose
——————圖片
————————菊花
——————圖片

圖像數據編碼
data_encoder.py
import glob
import os.path
import numpy as np
import tensorflow as tf
from tensorflow.python.platform import gfile

# 原始輸入數據的目錄,這個目錄下有5個子目錄,每一個子目錄底下保存這屬於該
# 類別的全部圖片。
INPUT_DATA = r'E:\X18301096\flower_photos'
# 輸出文件地址。咱們將整理後的圖片數據經過numpy的格式保存。
OUTPUT_FILE = r'E:\X18301096\flower_photos/flower_processed_data.npy'

# 測試數據和驗證數據比例。
VALIDATION_PERCENTAGE = 10
TEST_PERCENTAGE = 10


# 讀取數據並將數據分割成訓練數據、驗證數據和測試數據。
def create_image_lists(sess, testing_percentage, validation_percentage):
    sub_dirs = [x[0] for x in os.walk(INPUT_DATA)]
    is_root_dir = True

    # 初始化各個數據集。
    training_images = []
    training_labels = []
    testing_images = []
    testing_labels = []
    validation_images = []
    validation_labels = []
    current_label = 0

    # 讀取全部的子目錄。
    for sub_dir in sub_dirs:
        if is_root_dir:
            is_root_dir = False
            continue

        # 獲取一個子目錄中全部的圖片文件。
        extensions = ['jpg', 'jpeg', 'JPG', 'JPEG']
        file_list = []
        dir_name = os.path.basename(sub_dir)
        for extension in extensions:
            file_glob = os.path.join(INPUT_DATA, dir_name, '*.' + extension)
            file_list.extend(glob.glob(file_glob))
        if not file_list: continue
        print("processing:", dir_name)

        i = 0
        # 處理圖片數據。
        for file_name in file_list:
            i += 1
            # 讀取並解析圖片,將圖片轉化爲299*299以方便inception-v3模型來處理。
            image_raw_data = gfile.FastGFile(file_name, 'rb').read()
            image = tf.image.decode_jpeg(image_raw_data)
            if image.dtype != tf.float32:
                image = tf.image.convert_image_dtype(image, dtype=tf.float32)
            image = tf.image.resize_images(image, [299, 299])
            image_value = sess.run(image)

            # 隨機劃分數據聚。
            chance = np.random.randint(100)
            if chance < validation_percentage:
                validation_images.append(image_value)
                validation_labels.append(current_label)
            elif chance < (testing_percentage + validation_percentage):
                testing_images.append(image_value)
                testing_labels.append(current_label)
            else:
                training_images.append(image_value)
                training_labels.append(current_label)
            if i % 200 == 0:
                print(i, "images processed.")
        current_label += 1

    # 將訓練數據隨機打亂以得到更好的訓練效果。
    state = np.random.get_state()
    np.random.shuffle(training_images)
    np.random.set_state(state)
    np.random.shuffle(training_labels)

    return np.asarray([training_images, training_labels,
                       validation_images, validation_labels,
                       testing_images, testing_labels])

#數據處理主函數
def main():
    with tf.Session() as sess:
        processed_data = create_image_lists(sess, TEST_PERCENTAGE, VALIDATION_PERCENTAGE)
        # 經過numpy格式保存處理後的數據。
        np.save(OUTPUT_FILE, processed_data)

if __name__ == '__main__':
    main()

圖像數據解碼數組

data_load.py網絡

import glob
import os.path
import numpy as np
import tensorflow as tf
from tensorflow.python.platform import gfile

INPUT_DATA = ''

def main():
    processed_data = np.load(INPUT_DATA)
    training_images = processed_data[0]
    training_labels = processed_data[1]
    validation_images = processed_data[2]
    validation_labels = processed_data[3]
    testing_images = processed_data[4]
    testing_labels = processed_data[5]

    print(len(training_images),len(validation_images),len(testing_images))
    print(len(training_images[0]),len(training_images[0][0]))
    print(training_labels)
    print(validation_labels)
    print(testing_labels)

if __name__ =="__main__":
    main()

二.TFRecord輸入數據格式數據結構

將數據寫成TFRecord格式多線程

TFRecord_write.pyapp

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np

#生成整數型的屬性
def _int64_feature(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

#生成字符串型的屬性
def _bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
# 將數據轉化爲tf.train.Example格式。
def make_example(image,label,pixels):
    # 將圖像轉化成一個字符串
    image_raw = image.tostring()
    # 將一個樣例轉化爲Example protocol Buffer,並將全部信息寫入這個數據結構
    example = tf.train.Example(features=tf.train.Feature(feature={
        'pixels': _int64_feature(pixels),
        'label': _int64_feature(np.argmax(labels[index])),
        'image_raw': _bytes_feature(image_raw)
    }))
    return example


#讀取mnist訓練數據
mnist = input_data.read_data_sets(
    r"E:\MNIST_data\MNIST_data",dtype=tf.uint8,one_hot=True
)
images = mnist.train.images
#訓練數據所對應的正確答案,能夠做爲一個屬性保存在TFRECORD中
labels = mnist.train.labels
#訓練數據的圖像分辨率,這能夠做爲Example中的一個屬性
pixels = images.shape[1]
num_examples = mnist.train.num_examples

#輸出TFRecord文件的地址
filename = r"E:\X18301096\data_processing\TFRecord\output.tfrecords"
#建立一個writer 來寫TFRecord文件
with tf.python_io.TFRecordWriter(filename) as writer:
    for index in range(num_examples):
        example = make_example(images[index],labels[index],pixels)
        #將一個Example寫入TFRecord文件
        writer.write(example.SerializeToString())
print("TFRecord訓練數據已保存。")

#讀取mnist測試數據
images_test = mnist.test.images
labels_test = mnist.test.labels
pixels_test = images_test.shape[1]
num_examples_test = mnist.test.num_examples
#輸出包含測試數據的TFRecord文件
with tf.python_io.TFRecordWriter("output_test.tfrecords") as writer:
    for index in range(num_examples_test):
        example = make_example(images_test[index],labels[index],pixels_test)
        writer.write(example.SerializeToString())
print("TFRecord測試數據已保存!")

讀取TFRecord數據格式框架

import tensorflow as tf
#讀取文件。
reader= tf.TFRecordReader()
#建立一個隊列來維護輸入文件列表 filename_queue
= tf.train.string_input_producer(["output.tfrecords"])
#從文件中讀出一個樣例 _,serialized_example
= reader.read(filename_queue) #解析讀取的樣例 features = tf.parse_single_example( serialized_example, features={ 'image_raw':tf.FixedLenFeature([],tf.string), 'pixels':tf.FixedLenFeature([],tf.int64), 'label':tf.FixedLenFeature([],tf.int64) }) #tf.decode_raw能夠將字符串解析成圖像對應的像素數組 images = tf.decode_raw(features['image_raw'],tf.uint8) labels = tf.cast(features['label'],tf.int32) pixels = tf.cast(features['pixels'],tf.int32) with tf.Session() as sess: #啓動多線程處理輸入數據 coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess,coord=coord) for i in range(10): image,label,pixel = sess.run([images,labels,pixels])

三.tf.datasetdom

在數據集框架中,每一個數據集表明一個數據來源;數據可能來自一個張量,一個TFRecord文件,一個文本文件。函數

 數據集的基本使用方法

基本步驟:

1.定義數據集的構造方法

2.定義遍歷器

one_shot_iterator

initializable_iterator

3.使用get_next()方法從遍歷器中讀取數據張量,做爲計算圖其它部分的輸入

import tensorflow as tf
import tempfile

#從數組建立數據集
input_data = [1,2,3,4,5,8]

dataset = tf.data.Dataset.from_tensor_slices(input_data)

#定義迭代器,用於遍歷數據集
iterator = dataset.make_one_shot_iterator()

#get_next()返回表明一個輸入數據的張量
x = iterator.get_next()
y = x * x

with tf.Session() as sess:
    for i in range(len(input_data)):
        print(y.eval())


#讀取文本文件裏的數據
#建立文本文件做爲本例的輸入
with open("./test1.txt","w") as file:
    file.write("File1,line1.\n")
    file.write("File1,line2.\n")

with open("./test2.txt","w") as file:
    file.write("File2,line1.\n")
    file.write("File2,line2.\n")
#從文本文件建立數據集。可提供多個文件
input_files= ["./test1.txt","./test2.txt"]
dataset = tf.data.TextLineDataset(input_files)

#定義迭代器
iterator = dataset.make_one_shot_iterator()

#get_next()返回一個字符串類型的張量,表明文件中的一行
x = iterator.get_next()
with tf.Session() as sess:
    for i in range(4):
        print(x.eval())

# 解析TFRecord文件裏的數據
def parser(record):
    features = tf.parse_single_example(
        record,
        features={
            'image_raw':tf.FixedLenFeature([],tf.string),
            'pixels':tf.FixedLenFeature([],tf.int64),
            'label':tf.FixedLenFeature([],tf.int64)
        }
    )
    decode_images = tf.decode_raw(features['image_raw'],tf.uint8)
    retyped_images = tf.cast(decode_images,tf.float32)
    images = tf.reshape(retyped_images,[784])
    labels = tf.cast(features['label'],tf.int32)
    return images,labels
#從TFRecord文件建立數據集。這裏能夠提供多個文件
input_files = ["../output.tfrecords"]
dataset = tf.data.TFRecordDataset(input_files)

#map()函數表示對數據集中的每一條數據進行調用解析方法
dataset = dataset.map(parser)
#定義遍歷數據集的迭代器
iterator = dataset.make_one_shot_iterator()

#讀取數據,可用於進一步計算
image,label = iterator.get_next()

with tf.Session() as sess:
    for i in range(10):
        x,y = sess.run([image,label])
        print(y)

#使用initializable_iterator來動態初始化數據集
# 從TFRecord文件建立數據集,具體文件路徑是一個placeholder,稍後再提供具體路徑。
input_files = tf.placeholder(tf.string)
dataset = tf.data.TFRecordDataset(input_files)
dataset = dataset.map(parser)

# 定義遍歷dataset的initializable_iterator。
iterator = dataset.make_initializable_iterator()
image, label = iterator.get_next()

with tf.Session() as sess:
    # 首先初始化iterator,並給出input_files的值。
    sess.run(iterator.initializer,
             feed_dict={input_files: ["../output.tfrecords"]})
    # 遍歷全部數據一個epoch。當遍歷結束時,程序會拋出OutOfRangeError。
    while True:
        try:
            x, y = sess.run([image, label])
        except tf.errors.OutOfRangeError:
            break

數據集的高層操做

import tensorflow as tf

#列舉輸入文件
# 輸入數據使用本章第一節(1. TFRecord樣例程序.ipynb)生成的訓練和測試數據。
train_files = tf.train.match_filenames_once("../output.tfrecords")
test_files = tf.train.match_filenames_once("../output_test.tfrecords")

#定義解析TFRecord文件的parser方法
# 解析一個TFRecord的方法。
def parser(record):
    features = tf.parse_single_example(
        record,
        features={
            'image_raw':tf.FixedLenFeature([],tf.string),
            'pixels':tf.FixedLenFeature([],tf.int64),
            'label':tf.FixedLenFeature([],tf.int64)
        })
    decoded_images = tf.decode_raw(features['image_raw'],tf.uint8)
    retyped_images = tf.cast(decoded_images, tf.float32)
    images = tf.reshape(retyped_images, [784])
    labels = tf.cast(features['label'],tf.int32)
    #pixels = tf.cast(features['pixels'],tf.int32)
    return images, labels

#定義訓練數據集
image_size = 299          # 定義神經網絡輸入層圖片的大小。
batch_size = 100          # 定義組合數據batch的大小。
shuffle_buffer = 10000   # 定義隨機打亂數據時buffer的大小。

# 定義讀取訓練數據的數據集。
dataset = tf.data.TFRecordDataset(train_files)
dataset = dataset.map(parser)

# 對數據進行shuffle和batching操做。這裏省略了對圖像作隨機調整的預處理步驟。隨機打亂順序,將數據組合成batch
dataset = dataset.shuffle(shuffle_buffer).batch(batch_size)

# 重複NUM_EPOCHS個epoch。
NUM_EPOCHS = 10
#將數據集重複N份 dataset = dataset.repeat(NUM_EPOCHS) # 定義數據集迭代器。 iterator = dataset.make_initializable_iterator() image_batch, label_batch = iterator.get_next() # 定義神經網絡結構和優化過程 # 定義神經網絡的結構以及優化過程。這裏與7.3. 4小節相同。 def inference(input_tensor, weights1, biases1, weights2, biases2): layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1) return tf.matmul(layer1, weights2) + biases2 INPUT_NODE = 784 OUTPUT_NODE = 10 LAYER1_NODE = 500 REGULARAZTION_RATE = 0.0001 TRAINING_STEPS = 5000 weights1 = tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1)) biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE])) weights2 = tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1)) biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE])) y = inference(image_batch, weights1, biases1, weights2, biases2) # 計算交叉熵及其平均值 cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=label_batch) cross_entropy_mean = tf.reduce_mean(cross_entropy) # 損失函數的計算 regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE) regularaztion = regularizer(weights1) + regularizer(weights2) loss = cross_entropy_mean + regularaztion # 優化損失函數 train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss) #定義測試用數據集 # 定義測試用的Dataset。 test_dataset = tf.data.TFRecordDataset(test_files) test_dataset = test_dataset.map(parser) test_dataset = test_dataset.batch(batch_size) # 定義測試數據上的迭代器。 test_iterator = test_dataset.make_initializable_iterator() test_image_batch, test_label_batch = test_iterator.get_next() # 定義測試數據上的預測結果。 test_logit = inference(test_image_batch, weights1, biases1, weights2, biases2) predictions = tf.argmax(test_logit, axis=-1, output_type=tf.int32) # 聲明會話並運行神經網絡的優化過程。 with tf.Session() as sess: # 初始化變量。 sess.run((tf.global_variables_initializer(), tf.local_variables_initializer())) # 初始化訓練數據的迭代器。 sess.run(iterator.initializer) # 循環進行訓練,直到數據集完成輸入、拋出OutOfRangeError錯誤。 while True: try: sess.run(train_step) except tf.errors.OutOfRangeError: break test_results = [] test_labels = [] # 初始化測試數據的迭代器。 sess.run(test_iterator.initializer) # 獲取預測結果。 while True: try: pred, label = sess.run([predictions, test_label_batch]) print(pred.shape) test_results.extend(pred) test_labels.extend(label) except tf.errors.OutOfRangeError: break # 計算準確率 correct = [float(y == y_) for (y, y_) in zip(test_results, test_labels)] accuracy = sum(correct) / len(correct) print("Test accuracy is:", accuracy)

四.多線程輸入數據處理框架

import tensorflow as tf

#建立文件列表,經過文件列表建立輸入文件隊列,讀取文件爲本章第一節建立的文件
files = tf.train.match_filenames_once("./output.tfrecords")
filename_queue = tf.train.string_input_producer(files, shuffle=False)

# 解析TFRecord文件裏的數據
# 讀取文件。

reader = tf.TFRecordReader()
_,serialized_example = reader.read(filename_queue)

# 解析讀取的樣例。
features = tf.parse_single_example(
    serialized_example,
    features={
        'image_raw':tf.FixedLenFeature([],tf.string),
        'pixels':tf.FixedLenFeature([],tf.int64),
        'label':tf.FixedLenFeature([],tf.int64)
    })
#從原始圖像數據解析出像素矩陣,並根據圖像尺寸還原圖像
decoded_images = tf.decode_raw(features['image_raw'],tf.uint8)
retyped_images = tf.cast(decoded_images, tf.float32)
labels = tf.cast(features['label'],tf.int32)
#pixels = tf.cast(features['pixels'],tf.int32)
images = tf.reshape(retyped_images, [784])

#將文件以100個爲一組打包。
min_after_dequeue = 10000
batch_size = 100
capacity = min_after_dequeue + 3 * batch_size

image_batch, label_batch = tf.train.shuffle_batch([images, labels],
                                                    batch_size=batch_size,
                                                    capacity=capacity,
                                                    min_after_dequeue=min_after_dequeue)

#訓練模型
def inference(input_tensor, weights1, biases1, weights2, biases2):
    layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1)
    return tf.matmul(layer1, weights2) + biases2


# 模型相關的參數
INPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500
REGULARAZTION_RATE = 0.0001
TRAINING_STEPS = 5000

weights1 = tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1))
biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE]))

weights2 = tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1))
biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))

y = inference(image_batch, weights1, biases1, weights2, biases2)

# 計算交叉熵及其平均值
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=label_batch)
cross_entropy_mean = tf.reduce_mean(cross_entropy)

# 損失函數的計算
regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
regularaztion = regularizer(weights1) + regularizer(weights2)
loss = cross_entropy_mean + regularaztion

# 優化損失函數
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

# 初始化會話,並開始訓練過程。
with tf.Session() as sess:
    # tf.global_variables_initializer().run()
    sess.run((tf.global_variables_initializer(),
              tf.local_variables_initializer()))
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    # 循環的訓練神經網絡。
    for i in range(TRAINING_STEPS):
        if i % 1000 == 0:
            print("After %d training step(s), loss is %g " % (i, sess.run(loss)))

        sess.run(train_step)
    coord.request_stop()
    coord.join(threads)
相關文章
相關標籤/搜索