Tensorflow入门——自制数据集:将未经处理的图片制成npy格式的数据集

2023-11-15

一些吐槽和文章简介

博主是那种“拿来就用,不会再查”的人。而几乎所有教程都秉持着“这应该是python课教的”的理念,从而使得没学过python的人颇为头疼。博主虽接触过python,但还没系统学过,阅读一篇代码,最耗时的部分不是探索算法原理,而是查阅python函数用法……

嗯?你说什么?学python?在我眼中,专门学一门语言是最低效的事情之一(大学学C语言除外,毕竟是基础)。python是不会学的,这辈子也不可能学的。但也不能永远被语言问题所困扰,于是博主决定,总结一个“数据处理‘万能’模板”,将来需要用时,直接稍加改动,复制粘贴。

本文代码来源《Tensorflow实战Google深度学习框架(第2版)》第六章最后一节,本来是一个迁移学习的程序,但其中的数据处理模块我觉得很有帮助,特拿出来逐行精析。一不小心写了很多注释,干脆放在博客上,希望能帮有需要的人节省语言学习时间。


一、程序功能和数据集

http://download.tensorflow.org/example_images/flower_photos.tgz ,在这个网址下载数据,解压缩如下图:

代码文件要和这两个文件夹放在一个文件夹下
左边文件夹是解压得到,右边文件夹是新建的。flower_photos文件夹中有五个子文件夹,每个文件夹中都是同种类的花朵图片,这就是我们要面对的数据。
平均每一种花有734张图片,每张图都是RGB彩色,大小不同。

本文程序的input就是这些图片,output就是一个以.npy格式存储的数据文件(文末会说明如何读取这种文件)。


二、代码精析

# -*- coding: utf-8 -*-

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

INPUT_DATA = 'flower_photos'     # 原始输入数据的目录,其有五个子目录,每个目录下保存属于该类别的所有图片
OUTPUT_DATA = 'processed_flower_data/flower_processed_data.npy'     # 将整理后的图片数据通过numpy的格式保存

# 测试数据和验证数据的比例
VALIDATION_PERCENTAGE = 10
TEST_PERCENTAGE = 10

# 读取数据并将数据分割成训练数据、验证数据和测试数据
def create_image_lists(sess, testing_percentage, validation_percentage):
    # sub_dirs用于存储INPUT_DATA下的全部子文件夹目录
    sub_dirs = [x[0] for x in os.walk(INPUT_DATA)]  # os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下
    is_root_dir = True

    # 初始化各个数据集
    training_images = []
    training_labels = []
    testing_images = []
    testing_labels = []
    validation_images = []
    validation_labels = []
    current_label = 0   # 在接下来的for循环中,第一次循环时值为0,每次循环结束时加一
    count = 1   # 循环计数器

    # 对每个在sub_dirs中的子文件夹进行操作
    for sub_dir in sub_dirs:
        # 直观上感觉这个条件结构是多此一举,暂时不分析为什么要加上这个语句
        if is_root_dir:
            is_root_dir = False
            continue    # 继续下一轮循环,下一轮就无法进入条件分支而是直接执行下列语句

        print("开始读取第%d类图片:" % count)
        count += 1

        # 获取一个子目录中所有的图片文件
        extensions = ['jpg', 'jpeg', 'JPG', 'JPEG']     # 列出所有扩展名
        file_list = []
        # os.path.basename()返回path最后的文件名。若path以/或\结尾,那么就会返回空值
        dir_name = os.path.basename(sub_dir)    # 返回子文件夹的名称(sub_dir是包含文件夹地址的串,去掉其地址,只保留文件夹名称)
        # 针对不同的扩展名,将其文件名加入文件列表
        for extension in extensions:
            # INPUT_DATA是数据集的根文件夹,其下有五个子文件夹,每个文件夹下是一种花的照片;
            # dir_name是这次循环中存放所要处理的某种花的图片的文件夹的名称
            # file_glob形如"INPUT_DATA/dir_name/*.extension"
            file_glob = os.path.join(INPUT_DATA, dir_name, '*.' + extension)
            # extend()的作用是将glob.glob(file_glob)加入file_list
            # glob.glob()返回所有匹配的文件路径列表,此处返回的是所有在INPUT_DATA/dir_name文件夹中,且扩展名是extension的文件
            file_list.extend(glob.glob(file_glob))
        # 猜想这句话的意思是,如果file_list是空list,则不继续运行下面的数据处理部分,而是直接进行下一轮循环,
        # 即换一个子文件夹继续操作
        if not file_list: continue

        print "文件名列表制作完毕,开始读取图片文件"

        # 将file_list中的图片文件一条一条进行数据处理
        # 注意此时file_list已经变成了一个基本单位为字符串的list,list中的每个字符串存储的是一个图片的完整文件名(含路径),
        # 这些图片所属的文件夹就是这一轮循环的sub_dir
        for file_name in file_list:
            # 以下两行是读文件常用语句
            image_raw_data = gfile.FastGFile(file_name, 'rb').read()
            image = tf.image.decode_jpeg(image_raw_data)
            # 如果图片数据的类型不是float32,则转换之
            if image.dtype != tf.float32:
                image = tf.image.convert_image_dtype(image, dtype=tf.float32)
            # 调整图片的尺寸,将其化为299*299,以便inception-v3模型来处理
            image = tf.image.resize_images(image, [299, 299])
            image_value = sess.run(image)   # 提示:sess.run(image)返回image的计算结果;
            # 至此, image_value类型是299*299的float32型矩阵,代表当前循环所处理的图片文件

            # 随机划分数据集,通过生成一个0-99的随机数chance来决定当前循环中的图片文件划入验证集、测试集还是训练集
            # np.random.randint(100)作用是随机生成在0-99间的一个数(此函数还可以指定返回的尺寸,比如可以指定返回一个x*y的矩阵,未指定尺寸则返回一个数)
            chance = np.random.randint(100)
            if chance < validation_percentage:
                validation_images.append(image_value)   # 由于一共有3670张图片,这样最终的validation_images的尺寸大致是(3670*validation_percentage%)*229*229*3
                validation_labels.append(current_label)     # 由于一共有3670张图片,这样最终的validation_labels的尺寸大致是(3670*validation_percentage%)*1
            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)
        current_label += 1  # 注意这一行在上一个for外面,在最外层for里面;作用是在进入最外层for的下一轮循环之前,将"当前标签"加一,以表示下一个图片文件夹
        print "本类图片读取完毕"

    print "开始打乱训练数据集"

    # 将训练数据随机打乱以获得更好的训练效果
    # 注意这里已经跳出了for循环,此时的training_image尺寸大致是(3670*(100-validition_percentage-testing_percentage)%)*299*299*3
    # training_labels尺寸大致是(734*(100-validition_percentage-testing_percentage)%)*1
    state = np.random.get_state()   # 获取随机生成器np.random的状态
    np.random.shuffle(training_images)      # 进行打乱操作,如果对象是多维矩阵,只对第一维进行打乱操作
    np.random.set_state(state)      # 将之前随机生成器的状态设置为现在随机生成器的状态,目的是让下面一行对标签的打乱和上一行图片的打乱一致
    np.random.shuffle(training_labels)

    print "数据集处理完毕!"

    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)
        np.save(OUTPUT_DATA, processed_data)

if __name__ == '__main__':
    main()

三、代码运行

如果你的目录结构和文件夹的名称和我在一中所述一样,那么上述代码能不加改动直接在你的pycharm上运行。毕竟要对付3670张彩图,我运行了约33分钟,成功后大概是这样:

# 开始读取第1类图片:
# 文件名列表制作完毕,开始读取图片文件
# 本类图片读取完毕
# 开始读取第2类图片:
# 文件名列表制作完毕,开始读取图片文件
# 本类图片读取完毕
# 开始读取第3类图片:
# 文件名列表制作完毕,开始读取图片文件
# 本类图片读取完毕
# 开始读取第4类图片:
# 文件名列表制作完毕,开始读取图片文件
# 本类图片读取完毕
# 开始读取第5类图片:
# 文件名列表制作完毕,开始读取图片文件
# 本类图片读取完毕
# 开始打乱训练数据集
# 数据集处理完毕!

然后在processed_flower_data下发现有一个新文件flower_processed_data.npy
在这里插入图片描述


四、.npy文件的简单使用

import numpy as np
data = np.load(xxx.npy)

然后data就是如下格式:

[training_images, training_labels,
validation_images, validation_labels,
testing_images, testing_labels]

比如data[0]就是training_images的list,用如下代码查看其尺寸(应该有比这更简单的方法):

array=np.array(data[0])
array.shape

结果:

(2915, 299, 299, 3)

这是我的训练集的尺寸,共2915张图片,由于是用随机数分配的图片,可能每个人的图片张数不一样。

以上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tensorflow入门——自制数据集:将未经处理的图片制成npy格式的数据集 的相关文章

随机推荐

  • java学习笔记——众筹项目练习——前台系统的实名认证功能、ajax发送跨域请求、后台manager系统的实名认证人工审核

    实名认证功能 前面的文章中我们实现了后台manager系统中的流程管理功能 并且将实名认证的流程上传到了服务器并完成部署 不过 仅仅是长传和部署当然不是我们的目的啦 我们上传这个实名认证流程时为了可以让前台的广大用户可以使用这个流程 怎么才
  • C++ Primer 第五章 Statements

    C Primer 第五章 Statements 5 3 Conditional Statements 5 3 2 The switch Statement 5 4 Iterative Statements 5 4 3 Range for S
  • VScode 运行java出现exited with code=1 in 0.695 seconds的问题解决

    在运行vs中Java代码时 配置过程中可能会出现一些问题 导致运行结果为上述所示 在vs中运行Java代码时 首先要确保Java环境配置无误 出现下面的则证明配置成功 之后需要安装几个插件 最后就可以在vs中编写Java代码了
  • 使用C++调用C#的DLL

    SwfDotNet是C 编写的 作者的C 水平 真是令我佩服 这是个特别好的读写Swf文件的库 但是 我要用在C 项目中 怎么让C 调用C 的DLL呢 今天一上午都在琢磨这个问题 耽误了很多时间 原因是编译是出现 warning C4819
  • LeetCode题目笔记——389. 找不同/Python/C++

    文章目录 题目描述 题目难度 简单 方法一 使用哈希表计数出现次数 代码 Python 方法二 利用字母的ASCII码 代码 C Python 方法三 位运算 总结 题目描述 给定两个字符串 s 和 t 它们只包含小写字母 字符串 t 由字
  • thttpd嵌入式www服务工具的使用

    thttpd是一个非常小巧的轻量级web server 它非常简单 仅仅提供了HTTP 1 1和简单的CGI支持 在其官方网站上有一个与其他web server 如Apache Zeus等 的对比图 Benchmark 可以参考 此外 th
  • 空间频率 MTF和 SFR

    什么叫空间频率 我们日常中一般的频率是指时间频率 其单位是Hz 其定义是单位时间内 s 运动次数 官方定义 1 单位时间内完成振动或振荡的次数或周数 2 某一时间内某事物发生的次数或完成某过程的次数 这里的被除数是单位所以是时间频率 但是如
  • [现代控制理论]11_现代控制理论串讲_完结_pdf获取

    DR CAN的现代控制理论的笔记就结束了 加上这篇一共11篇 现代控制理论 11 现代控制理论串讲 完结 pdf获取 现代控制理论 10 可观测性与分离原理 观测器与控制器 现代控制理论 9 状态观测器设计 龙伯格观测器 现代控制理论 8
  • 数据结构(五):前序遍历、中序遍历、后序遍历

    我们先看下二叉树的前序 后序和中序遍历 遍历下面这个二叉树 分别以前中后三种遍历方式 写出结点的顺序 前序遍历 顺序 根左右 或 中左右 遍历根节点 遍历根结点的左子结点 如果左结点不是叶节点 则以当前结点开始 重新从第一步开始循环 遍历根
  • keil错误 *** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED 解决方法

    keil错误 FATAL ERROR L250 CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED 解决方法 出现这个是你的keli没有破解 步骤如下 1 以管理员的身份运行你的keli 2 以管理
  • 【Java+MySQL】使用JDBC连接MySQL 8.0数据库

    一 Java MySQL 8 0连接驱动包 下载链接 https pan baidu com s 1YFOImz0dCHtzIajSFq9xgg pwd boul 提取码 boul IDEA 导入方式 1 在 External Librar
  • Mysql 学习

    文章目录 下载 安装 修改 修改登录密码 授权 下载 Mysql 数据库的下载链接 注意 CenterOS 请选择 Red Hat 那一项 安装 这里介绍的是 5 7 版本 安装包是 rpm bundle tar 结尾的 创建 mysql
  • ZC-CLS381RGB颜色识别——配置寄存器组(上)

    文章目录 前言 一 ZC CLS381RGB简介 二 配置寄存器组 1 主控寄存器 2 检测速率寄存器 2 增益寄存器 2 颜色数据寄存器 三 状态转移图和信号波形图绘制 总结 前言 在现代工业生产中 颜色识别技术已经成为了一个非常重要的技
  • 使用JsonConvert.DeserializeObject注意事项

    在使用JsonConvert DeserializeObject反序列化自定义对象的时候 我遇到了一个问题 定义了一个对象QueryModel QueryModel拥有两个构造方法 私有无参构造方法 private QueryModel 跟
  • android直接方法和虚方法,Android NDK入门:C++ 基础知识

    为什么写这篇文章 本文算作是 Android 音视频开发打怪升级 系列文章的 番外 篇 原本打算将本文的内容写在 Android FFmpeg视频解码播放 这篇文章中 因为要想学习 FFmpeg 相关知识 C 的基础知识是必不可少的 但是写
  • java集合框架Map之HashMap底层原理解析

    感兴趣的话大家可以关注一下公众号 猿人刘先生 欢迎大家一起学习 一起进步 一起来交流吧 哈希表 hash table 哈希表也称为散列表 散列表 Hash table 也叫哈希表 是根据关键码值 Key value 而直接进行访问的数据结构
  • STM32——HAL版——定时器ms和us延时函数

    定时器做ms和us延时函数 本文用的是STM32L431RCT6芯片 定时器TIM2和TIM6挂载在APB1总线上 1 配置TIM2为ms延时定时器 TIM2为通用定时器在APB1总线上 主频为80MHz 设置TIM2参数 时钟源选择为内部
  • Android应用请求获取Root权限

    要让Android应用获得Root权限 首先Android设备必须已经获得Root权限 应用获取Root权限的原理 让应用的代码执行目录获取最高权限 在Linux中通过chmod 777 代码执行目录 代码如下 应用程序运行命令获取 Roo
  • 企业实践

    欢迎关注 全栈工程师修炼指南 公众号 点击 下方卡片 即可关注我哟 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 花开堪折直须折 莫待无花空折枝 文章目录 0x00 前言简述 1 背景了解 2 发展历程 3 产品版本 4 官
  • Tensorflow入门——自制数据集:将未经处理的图片制成npy格式的数据集

    一些吐槽和文章简介 博主是那种 拿来就用 不会再查 的人 而几乎所有教程都秉持着 这应该是python课教的 的理念 从而使得没学过python的人颇为头疼 博主虽接触过python 但还没系统学过 阅读一篇代码 最耗时的部分不是探索算法原