Data Preprocess

  本文试图解决一个问题,即我们自定义的数据如何训练模型?初识深度学习,我们接触手写数字识别模型,但是批次数据是mnist已经定义好的,我们现在有自己的图片如何做成批次进行训练模型。

  现在我们将准备好的原始数据放在flower_photos下的文件夹下面,里面又分类包含五种花,文件夹的名字即为类名,每种文件夹下面又有若干图片,如下图所示:

例如,daisy文件下面图片,图片的尺寸大小不一致,这在后期要处理。

数据增强

  数据增强通过对图片进行一定的处理,使得训练数据量增强,防止过拟合等,这块后期完善。。

  由于模型需要既定尺寸大小的图片,我们先对图片进行resize,以下代码将实现对图片调整尺寸后保存在新的地址中。本文只是解决了在一个文件下

def resize_image(base_dir, new_dir, wight, height):
    if not os.path.exists(new_dir):
        os.mkdir(new_dir)
    foldername = os.listdir(base_dir)
    for folder in foldername:
        if not os.path.exists(new_dir+'\'+folder):
            os.mkdir(new_dir+'\'+folder)
        imagename = os.listdir(base_dir+'\'+folder)
        for img in imagename:
            image = Image.open(base_dir +"\"+ folder+'\'+img)
            image_sized = image.resize((wight, height),Image.ANTIALIAS)
            image_sized.save(new_dir +"\"+ folder+'\'+img)        
    print('--------------Data_resized DONE-------------------')

write_tfrecord

  这里需要一个将类标对应成0,1,2。。的数字,建立一个label.txt,文件夹为类名,对应相应的数字。

  

  本节理论后期完善,下面代码将会生成xx.tfrecord

def convert2example(img_dir, label):
    image=Image.open(img_dir)
    width, height = image.size
    if image.mode != 'RGB':
        image=image.convert('RGB')
    image_data=image.tobytes()
    #img_name1 = bytes(img_name, 'utf-8')
    example = tf.train.Example(features=tf.train.Features(feature={
        'image/encoded': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_data])),
        'image/height': tf.train.Feature(int64_list=tf.train.Int64List(value=[height])),
        'image/width': tf.train.Feature(int64_list=tf.train.Int64List(value=[width])),
        'image/label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
    }))
    return example

def writer_tfrecord(data_dir, label_txt_dir, output_dir, dataset):
    if not tf.gfile.Exists(output_dir):
        tf.gfile.MakeDirs(output_dir)
    out_file=os.path.join(output_dir, dataset+'.tfrecord')
    num_samples=0
    with tf.python_io.TFRecordWriter(out_file) as tfWriter:
        label_dict = {}
        with open(label_txt_dir,'r') as f:
            for line in f.readlines():
                folder = line.strip().split(':')[0]
                label = line.strip().split(':')[1]
                label_dict[folder] = label
        image_list, label_list = [], []
        for folder in os.listdir(data_dir):
            dir_path = os.path.join(data_dir,folder,'*.jpg')
            for image in glob.glob(dir_path):
                image_list.append(image)
                label_list.append(int(label_dict[folder]))
                label = int(label_dict[folder])
                example=convert2example(image, label)
                tfWriter.write(example.SerializeToString())
                num_samples+=1
    print("Number of samples: {}".format(num_samples))

Get_batch

  首先read_tfrecord读取上文生成的tfrecord文件,之后shuffle生成batch,test文件是测试的,

def read_tfrecord(filename_queue):
    feature = {'image/encoded': tf.FixedLenFeature([], tf.string),
               'image/height': tf.FixedLenFeature([], tf.int64),
               'image/width': tf.FixedLenFeature([], tf.int64),
               'image/label': tf.FixedLenFeature([], tf.int64)}

    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.uint8)
    image  = tf.cast(image, tf.float32)
    height = tf.cast(features['image/height'],tf.int32)
    width  = tf.cast(features['image/width'], tf.int32)
    label  = tf.cast(features['image/label'], tf.int32)
    img = tf.reshape(image, [height, width, 3])

    # preprocess
    # subtract mean valu
    rgb_mean=np.array([123.68, 116.779, 103.939])
    img = tf.subtract(img, rgb_mean)
    # red, green, blue = tf.split(3, 3, img)
    # img = tf.concat(3, [
    #     tf.subtract(red , bgr_mean[2]),
    #     tf.subtract(green , bgr_mean[1]),
    #     tf.subtract(blue , bgr_mean[0]),
    # ])
    # center_crop
    img = tf.image.resize_images(img, [256, 256])
    j = int(round((256 - 224) / 2.))
    i = int(round((256 - 224) / 2.))
    img = img[j:j+224, i:i+224, :]

    # scale to 1
    img = tf.cast(img, tf.float32) * 0.017

    return img, label

def get_batch(infile, batch_size, num_threads=4, shuffle=False, min_after_dequeue=None):
    # 使用batch,img的shape必须是静态常量
    image, label = read_tfrecord(infile)

    if min_after_dequeue is None:
        min_after_dequeue = batch_size * 10
    capacity = min_after_dequeue + 3 * batch_size

    if shuffle:
        img_batch, label_batch = tf.train.shuffle_batch([image, label], batch_size=batch_size,
                                                    capacity=capacity,num_threads=num_threads,
                                                    min_after_dequeue=min_after_dequeue)
    else:
        img_batch, label_batch = tf.train.batch([image, label], batch_size,
                                                capacity=capacity, num_threads=num_threads,
                                                allow_smaller_final_batch=True)

    return img_batch, label_batch
def test_tfrecord(dataset_dir,batch_size):
    glob_pattern = os.path.join(dataset_dir, '*.tfrecord')
    tfrecords_list = glob.glob(glob_pattern)
    filename_queue = tf.train.string_input_producer(tfrecords_list, num_epochs=None)
    img_batch, label_batch = get_batch(filename_queue, batch_size)
    print('-----img_batch:------',type(img_batch))
    print('-----label_batch:------',type(label_batch))

main 测试

  通过下面的代码我们测试下数据。

  生成的batch为tensor,这为后期placeholder占位符送入的数据非tensor,需要转换成列表或者其他都可以,有两种方式:

 with tf.Session() as sess:
        print('-----img_batch:------',type(img_batch))
        print('-----label_batch:------',type(label_batch))
     #第一种 tensor在run后变成array
#img_batch, label_batch = sess.run([img_batch, label_batch])
     # 第二种,eval()方法可以将tensor变为array
     # 同里,将array变为tensor可以用convert_to_tensor()
img_batch = img_batch.eval() label_batch = label_batch.eval() print('-----img_batch:------',type(img_batch)) print('-----label_batch:------',type(label_batch))
def main():
    
    label_txt_dir = 'label.txt'
    data_dir = './resized_flower_photos'
    base_dir = './flower_photos' 
    new_dir = './resized_flower_photos'
    resize_wight = 224
    resize_height = 224
    
    output_dir = './tfrecord'
    dataset = 'mobilenetv2_data'
    
    #resize_image(base_dir,new_dir,resize_wight,resize_height)
    #image_list, label_list = read_file(label_txt_dir,data_dir)
    #writer_tfrecord(data_dir, label_txt_dir, output_dir, dataset)
    img_batch, label_batch = test_tfrecord(output_dir,64)
    with tf.Session() as sess:
        print('-----img_batch:------',type(img_batch))
        print('-----label_batch:------',type(label_batch))
        img_batch, label_batch = sess.run([img_batch, label_batch])
        print('-----img_batch:------',type(img_batch))
        print('-----label_batch:------',type(label_batch))
if __name__ == '__main__':
    main()

 创建txt文件

  我们需要将图片和类标对应起来作为一个txt文件存在,下面的代码实现了将文件中的内容做成txt文件,这个可以在caffe中的imagedata中使用,需要的数据label_txt_dir如下图:

import tensorflow as tf
import os
import glob

def creat_txt(label_txt_dir, data_dir,txt_name):
    #将label_txt中的内容放在字典中
    label_dict = {}
    with open(label_txt_dir,'r') as f:
        for line in f.readlines():
            folder = line.strip().split(':')[0]
            label = line.strip().split(':')[1]
            label_dict[folder] = label
    #将文件中的数据放在列表中
    image_list, label_list = [], []
    for folder in os.listdir(data_dir):
        dir_path = os.path.join(data_dir,folder,'*.jpg')
        for image in glob.glob(dir_path):
            image_list.append(image)
            label_list.append(label_dict[folder])
    #将列表中内容写在文件中
    with open(txt_name,'w') as file:
        for i in range(len(image_list)):
            file.write(image_list[i])
            file.write(' ')
            file.write(label_list[i])
            file.write('
')
        file.close()
    print("There are %d data" % (len(image_list)))
    print('-------creat_%s   Done--------'% txt_name)
    
#------------执行main函数-------------------#
def main():
    print('----------main-------------')
    data_dir = './resized_image'
    label_txt_dir = 'label.txt'
    txt_name = 'train.txt'
    creat_txt(label_txt_dir, data_dir,txt_name)
    
    
    

if __name__ == '__main__':
    main()

 生成的train.txt文件如下图所示:

原文地址:https://www.cnblogs.com/missidiot/p/10219471.html