Tensorflow构建自己的图片数据集TFrecords




通过python来完成,更加的简单

#encoding=utf-8
import os
import tensorflow as tf
from PIL import Image

cwd = os.getcwd()
#图片文件夹目录,可有多层
classes = {'tensor'}
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((224, 224))
            img_raw = img.tobytes() #将图片转化为原生bytes
            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()
'''

这样会在当前目录下生成一个traintfrecords二进制文件

------------------------------------------------------------------------------------------------------------------

下面一篇是我转的一篇通过C++来操作的

文章链接: http://blog.csdn.net/yhl_leo/article/details/50801226 

说明一下,这是一篇在window下操作的,换到ubuntu下请各位自行解决,博客质量是不错的,自己制作很不错。

前一篇博客:C/C++ 图像二进制存储与读取中,已经讲解了如何利用C/C++的方法存储与读取二进制图像文件,本文继续讲述如何根据CIFAR-10的格式制作自己的数据集。

所述博文与代码均已同步至GitHub:yhlleo/imageBinaryDataset

主要代码文件有三个:

  • BinaryDataset.h
  • BinaryDataset.cpp
  • main.cpp

main.cpp给出的一个小demo为例,首先指定一个原数据图片所在的文件夹:

std::string filefolder = "C:\\Samples\\train";
 
 
  • 1
  • 1

然后,自动获得该文件下的所有图片文件名:

std::vector<std::string> fileLists = binData.getFileLists(filefolder); // load file name
 
 
  • 1
  • 1

这里有一点需要说明一下,getFileLists()是按照文件名升序顺序读取(大家都知道,文件名为字符串,comparable),文件命名最好不要以1, 2, ..., 11, ...这种方式存储,因为这么存,你就会发现1之后的文件可能不是你想的2, 3, 4, ...,而是11, 12, 13, ...

如果你想按照顺序的某一堆数据是一种类别(我是这么做的,因为便于产生对应的labels),建议使用等宽零位补齐的方式命名,例如:00001, 0002, ..., 0011, ...,那么文件读取的顺序就会如我们所设定。

总结一下实现方法(仅供参考):

  • 采集样本的时候可以先类别存于不同的文件夹,命名就随意吧,如果是使用一些抠图软件,也不用纠结一个一个手工修改成自己想要的命名(这么做工作量很大,真的很蛋疼。。。);
  • 每一类数据整理好后,依次将每一类的数据,用程序读取并另存一份(读取使用getFileLists(),反正是一类的,也无所谓先后顺序):
    for ( int i=0; i<fileLists.size(); i++ )
    {
        char* curfile = new char[128];
        sprintf(curfile, "C:\\Samples\\class-1\\%04d.jpg", i);
        string fileName = filefolder + "\\";
        fileName += fileLists[i];
        cv::Mat image = cv::imread(fileName);
        cv::imwrite(curfile, image);
        delete[] curfile;
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 后面的其他类别也可以这样,为了按照顺序区分,依次进行其他类别的时候,只需要在改动文件夹后,将sprintf(curfile, "C:\\Samples\\class-1\\%04d.jpg", i);中的第三个参数i改为i+k,这里k是前面一类或几类的样本总数。
  • 最后,将重新命名的文件,存在一个文件夹里,记清楚类别对应的区间范围,以便生成labels

读取上述最终文件内的所有文件,接下来,生成labelslabels一般用[0, 9]组成的整数字):

std::vector<int> image_labels(size_list, 0);  // generate lables, here are all 0
 
 
  • 1
  • 1

当然,你也可以用image_labels.push_back()把所有的labels设置,但是熟悉vector的话,就会明白使用初始化长度,比那种做法更加高效(可以阅读本人的博客: C++ 容器(一):顺序容器简介)。然后就相应地修改某些索引区间内的label值:

for ( int i=0; i<count_class_k; i++ )
    image_labels[i] = 1;
 
 
  • 1
  • 2
  • 1
  • 2

都准备好后,就可以开始生成想要的二进制文件了:

    std::string binfile = "C:\\Samples\\train.bin";
    binData.images2BinaryFile( filefolder, fileLists, image_labels, binfile );
 
 
  • 1
  • 2
  • 1
  • 2

到这里,已经制作好了二进制数据集,我很懒,想直接基于tensorflow/models/image/cifar10模块的源码跑我定义的数据集,想想只要跟cifar10数据集类似,那肯定没什么问题,下面是官网上下载的cifar-10-binary.tar解压后内容:

cifar.rar

这份数据集比较大,训练样本有50000测试样本10000(我的数据集并没有这么大,但是又有什么关系呢!)。

看,这是我的数据集:

cifar2

是不是很迷你~

然后,将tensorflow/models/image/cifar10模块的拷贝中的部分参数修改成为适合自己数据集的,就OK了~

献上运行截图(训练测试集有5196张样本,所以5196*0.4 = 2078):

run

 
训练了两天,跑完后,评估精度为:0.896。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
TensorFlow 中,可以使用 `tf.keras.preprocessing.image_dataset_from_directory` 方法来加载本地图片数据集。这个方法可以从一个目录中读取图片,并将其转换成 TensorFlow 中的数据集。 以下是一个示例代码,演示如何使用 `image_dataset_from_directory` 方法加载本地图片数据集: ``` python import tensorflow as tf # 指定图片目录和 batch_size image_dir = "/path/to/image/directory/" batch_size = 32 # 使用 image_dataset_from_directory 方法加载数据集 train_dataset = tf.keras.preprocessing.image_dataset_from_directory( image_dir, validation_split=0.2, # 拆分训练集和验证集的比例 subset="training", # 使用训练集子集 seed=123, # 随机种子,用于拆分数据集 image_size=(224, 224),# 图片大小 batch_size=batch_size # 批量大小 ) val_dataset = tf.keras.preprocessing.image_dataset_from_directory( image_dir, validation_split=0.2, # 拆分训练集和验证集的比例 subset="validation", # 使用验证集子集 seed=123, # 随机种子,用于拆分数据集 image_size=(224, 224),# 图片大小 batch_size=batch_size # 批量大小 ) ``` 在这个示例中,我们指定了图片目录 `image_dir` 和批量大小 `batch_size`,然后使用 `image_dataset_from_directory` 方法加载数据集。这个方法会自动将图片转换成 TensorFlow 中的数据集,并且可以将数据集拆分成训练集和验证集两个子集。 如果需要对图片进行数据增强,可以使用 `tf.keras.preprocessing.image.ImageDataGenerator` 类来设置数据增强参数,并将其传递给 `image_dataset_from_directory` 方法。例如: ``` python import tensorflow as tf # 设置数据增强参数 data_augmentation = tf.keras.Sequential([ tf.keras.layers.experimental.preprocessing.RandomFlip('horizontal'), tf.keras.layers.experimental.preprocessing.RandomRotation(0.2), ]) # 使用 image_dataset_from_directory 方法加载数据集 train_dataset = tf.keras.preprocessing.image_dataset_from_directory( image_dir, validation_split=0.2, # 拆分训练集和验证集的比例 subset="training", # 使用训练集子集 seed=123, # 随机种子,用于拆分数据集 image_size=(224, 224), # 图片大小 batch_size=batch_size, # 批量大小 label_mode='categorical', # 标签类型 preprocessing_function=data_augmentation, # 数据增强 ) ``` 在这个示例中,我们使用 `Sequential` 类创建了一个数据增强模型,并将其传递给 `image_dataset_from_directory` 方法的 `preprocessing_function` 参数。这样,在加载数据集时,会自动对图片进行数据增强。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值