TensorFlow学习笔记(三)书写体数字数据集的生成

上篇

TensorFlow学习笔记(二)手写体数字的识别——环境安装

关于代码运行平台

博主示范使用的平台是 PyCharm Community 2019.3 x64 ,仅仅出于个人习惯。
读者也可以在 JupterNotebook 等其他平台上使用。

所用库的引入

import random
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np

random 和 os 是 python 内置的库,不需要引入。
PIL 是一个生成和处理图片的库。
numpy 将图片转化为张量,方便神经网络进行数据分析。

1. 依次打开 :File --> Settings --> Project: practice -->Project Interpreter
2. 按下 右侧的小齿轮,点击 Add…
在这里插入图片描述
3. 在 Location 右侧点击📂选择环境安装位置
4. 在Base interpreter 右侧点击浏览(···)选择 Anaconda 安装路径\envs\tensorflow\python3.exe 如图二所示,图一不正确。
可以勾选下面的两个小方框方便以后寻找环境。
在这里插入图片描述

在这里插入图片描述

5. 点击 OK 完成配置,等待一会,可以看到 PyCharm 列出了所有已经安装的库。
如果没有,点击右侧小眼睛图标显示即可
在这里插入图片描述

6. 点击右侧➕,以添加库。
在这里插入图片描述

7. 等待一会,出现如下界面,在搜索栏输入你想要的库的名称。
在这里插入图片描述

8.选中你需要的库,按 Install Package 下载,等待下载完成。
在这里插入图片描述
9. 如果没能下载成功,尝试打开 Terminal,即命令提示符窗口进行手动下载。
注:必须打开正确的环境,即 (tensorflow) C:\Users\用户名\pythonwork>

在这里插入图片描述

输入如下代码:
注:如果使用 Anaconda 环境,可以不安装 numpy ,因为我们之前安装 tensorflow 环境时已经默认安装好了相应的 numpy 包,如果没有,就输
入代码手动安装。

pip install PIL
pip install numpy # 选做

10. 使用JupyterNotebook 的朋友们按照第9步的做法在 tensorflow 环境中安装好了需要的库后就可以愉快的在 JupyterNotebook 里运行代码啦!

生成用来存放数字的文件夹

random.seed(3)
path_data ="data_and_distribution" #文件夹路径

# 在目录下生成用来存放数字的文件夹
def mkdir_for_imgs():
    if not os.path.exists(path_data):
        print(path_data)
        os.makedirs(path_data)

删除路径下的图片

在生成新的数据前必须要先删除之前的数据。

# 删除路径下的图片
def del_imgs():
    dir_nums = os.listdir(path_data)
    for file in dir_nums:
        print("delete: ", path_data + "/" + file)
        os.remove(path_data + "/" + file)
    print("Delete finish", "\n")

生成单张扭曲的数字图像

每行代码的解释都写在了代码注释里。

# 生成单张扭曲的数字图像
def generate_single():
    # 先绘制一个50*50的空图像
    im_50_blank = Image.new('RGB', (50, 50), (255, 255, 255))

    # 创建画笔
    draw = ImageDraw.Draw(im_50_blank)

    # 生成随机数1-9
    num = random.randint(0, 9)

    # 设置字体,这里选取字体大小25
    font = ImageFont.truetype('simsun.ttc', 20)

    # xy是左上角开始的位置坐标
    draw.text(xy=(18, 11), font=font, text=str(num), fill=(0, 0, 0))

    # 随机旋转-10-10角度
    random_angle = random.randint(-10, 10)
    im_50_rotated = im_50_blank.rotate(random_angle)

    # 图形扭曲参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500]

    # 创建扭曲
    im_50_transformed = im_50_rotated.transform((50, 50), Image.PERSPECTIVE, params)

    # 生成新的28*28图像
    im_28 = im_50_transformed.crop([11, 11, 39, 39])

    return im_28, num

生成手写体数字和标签存入指定文件夹

# 生成手写体数字和标签存入指定文件夹
def generate_0to9(n,fn=""):
    # 用cnt_num[0]-cnt_num[9]来计数数字1-9生成的个数,方便之后进行命名
    cnt_num = [0 for i in range(10)]
    #用来存储每一组image和label
    lst_img=[]
    lst_label=[]

    for m in range(n):
        # 调用生成图像文件函数
        im, num = generate_single()

        # 计数生成的数字1-9的个数,用来查看训练集内容
        cnt_num[num]+=1

        # 取灰度
        im_gray = im.convert('1')

        # 转成数组
        array = np.array(im_gray)
        lst_img.append(array)
        lst_label.append(num)


    # 存储图像张量和标签张量组成的元组
    np.savez(path_data + "/" + "data_{}".format(fn),x=np.array(lst_img),y=np.array(lst_label))
    print("图像数据的形状:",np.array(lst_img).shape,"标签数据的形状:",np.array(lst_label).shape)

    print("\n")
    # 输出显示0-9的分布
    print("生成的0-9的分布:")
    print("  "+str(n)+" in all")
    for k in range(10):
        print("Num", k, ":", cnt_num[k], "in all")

    # 存储0-9的数据分布
    np.savez(path_data + "/" + "distribution_{}".format(fn), dis=np.array(cnt_num))

主程序段执行

注:因为生成的数据集很大,需要一定的时间来运行,请耐心等待。

if __name__=="__main__":
    # 生成目录
    mkdir_for_imgs()

    # 清除已有npy文件
    del_imgs()

    # 生成60000个训练数据
    generate_0to9(60000,"train")

    # 生成10000个检验数据
    generate_0to9(10000,"test")

运行的结果

在这里插入图片描述

在这里插入图片描述

注:成功后可以在工程创建的位置找到如图所示的文件夹,里面有四个npz文件。
在这里插入图片描述

在这里插入图片描述

完整的代码

import random
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np

random.seed(3)
path_data ="data_and_distribution" #文件夹路径

# 在目录下生成用来存放数字的文件夹
def mkdir_for_imgs():
    if not os.path.exists(path_data):
        print(path_data)
        os.makedirs(path_data)


# 删除路径下的图片
def del_imgs():
    dir_nums = os.listdir(path_data)
    for file in dir_nums:
        print("delete: ", path_data + "/" + file)
        os.remove(path_data + "/" + file)
    print("Delete finish", "\n")


# 生成单张扭曲的数字图像
def generate_single():
    # 先绘制一个50*50的空图像
    im_50_blank = Image.new('RGB', (50, 50), (255, 255, 255))

    # 创建画笔
    draw = ImageDraw.Draw(im_50_blank)

    # 生成随机数1-9
    num = random.randint(0, 9)

    # 设置字体,这里选取字体大小25
    font = ImageFont.truetype('simsun.ttc', 20)

    # xy是左上角开始的位置坐标
    draw.text(xy=(18, 11), font=font, text=str(num), fill=(0, 0, 0))

    # 随机旋转-10-10角度
    random_angle = random.randint(-10, 10)
    im_50_rotated = im_50_blank.rotate(random_angle)

    # 图形扭曲参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500]

    # 创建扭曲
    im_50_transformed = im_50_rotated.transform((50, 50), Image.PERSPECTIVE, params)

    # 生成新的28*28图像
    im_28 = im_50_transformed.crop([11, 11, 39, 39])

    return im_28, num


# 生成手写体数字和标签存入指定文件夹
def generate_0to9(n,fn=""):
    # 用cnt_num[0]-cnt_num[9]来计数数字1-9生成的个数,方便之后进行命名
    cnt_num = [0 for i in range(10)]
    #用来存储每一组image和label
    lst_img=[]
    lst_label=[]

    for m in range(n):
        # 调用生成图像文件函数
        im, num = generate_single()

        # 计数生成的数字1-9的个数,用来查看训练集内容
        cnt_num[num]+=1

        # 取灰度
        im_gray = im.convert('1')

        # 转成数组
        array = np.array(im_gray)
        lst_img.append(array)
        lst_label.append(num)


    # 存储图像张量和标签张量组成的元组
    np.savez(path_data + "/" + "data_{}".format(fn),x=np.array(lst_img),y=np.array(lst_label))
    print("图像数据的形状:",np.array(lst_img).shape,"标签数据的形状:",np.array(lst_label).shape)

    print("\n")
    # 输出显示0-9的分布
    print("生成的0-9的分布:")
    print("  "+str(n)+" in all")
    for k in range(10):
        print("Num", k, ":", cnt_num[k], "in all")

    # 存储0-9的数据分布
    np.savez(path_data + "/" + "distribution_{}".format(fn), dis=np.array(cnt_num))

if __name__=="__main__":
    # 生成目录
    mkdir_for_imgs()

    # 清除已有npy文件
    del_imgs()

    # 生成60000个训练数据
    generate_0to9(60000,"train")

    # 生成10000个检验数据
    generate_0to9(10000,"test")

附录

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值