Tensorflow实现人马图片的分类器 [使用ImageDataGenerator 无需人为标注数据]

本文主要是介绍Tensorflow实现人马图片的分类器 [使用ImageDataGenerator 无需人为标注数据],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实验环境: goolge colab (改为本地使用也非常的简单,只需将测试部分稍作修改即可)

初始环境:
tmp文件下为空
content文件下只有sample_data文件
在这里插入图片描述
步骤
(1):下载人马数据集的训练集压缩包和验证集压缩包,放在
/tmp/horse-or-human.zip
/tmp/validation-horse-or-human.zip

!wget --no-check-certificate \https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip \-O /tmp/horse-or-human.zip
!wget --no-check-certificate \https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip \-O /tmp/validation-horse-or-human.zip

在这里插入图片描述
(2)解压压缩包
训练数据放在/tmp/horse-or-human
验证数据放在/tmp/validation-horse-or-human

import os
import zipfilelocal_zip = '/tmp/horse-or-human.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/horse-or-human')
local_zip = '/tmp/validation-horse-or-human.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp/validation-horse-or-human')
zip_ref.close()

在这里插入图片描述
(3) 定义训练数据和验证数据中人马图片的路径

# Directory with our training horse pictures
train_horse_dir = os.path.join('/tmp/horse-or-human/horses')# Directory with our training human pictures
train_human_dir = os.path.join('/tmp/horse-or-human/humans')# Directory with our training horse pictures
validation_horse_dir = os.path.join('/tmp/validation-horse-or-human/horses')# Directory with our training human pictures
validation_human_dir = os.path.join('/tmp/validation-horse-or-human/humans')

(4)输出各种路径中的前10个文件名

train_horse_names = os.listdir(train_horse_dir)
print(train_horse_names[:10])train_human_names = os.listdir(train_human_dir)
print(train_human_names[:10])validation_horse_hames = os.listdir(validation_horse_dir)
print(validation_horse_hames[:10])validation_human_names = os.listdir(validation_human_dir)
print(validation_human_names[:10])

在这里插入图片描述
(5)输出各个路径下图片的数目。训练数据一共1027张图片,验证数据一共256张图片。

print('total training horse images:', len(os.listdir(train_horse_dir)))
print('total training human images:', len(os.listdir(train_human_dir)))
print('total validation horse images:', len(os.listdir(validation_horse_dir)))
print('total validation human images:', len(os.listdir(validation_human_dir)))

在这里插入图片描述
(6)显示出8张马和人的图片

%matplotlib inlineimport matplotlib.pyplot as plt
import matplotlib.image as mpimg# Parameters for our graph; we'll output images in a 4x4 configuration
nrows = 4
ncols = 4# Index for iterating over images
pic_index = 0# Set up matplotlib fig, and size it to fit 4x4 pics
fig = plt.gcf()
fig.set_size_inches(ncols * 4, nrows * 4)pic_index += 8
next_horse_pix = [os.path.join(train_horse_dir, fname) for fname in train_horse_names[pic_index-8:pic_index]]
next_human_pix = [os.path.join(train_human_dir, fname) for fname in train_human_names[pic_index-8:pic_index]]for i, img_path in enumerate(next_horse_pix+next_human_pix):# Set up subplot; subplot indices start at 1sp = plt.subplot(nrows, ncols, i + 1)sp.axis('Off') # Don't show axes (or gridlines)img = mpimg.imread(img_path)plt.imshow(img)plt.show()

在这里插入图片描述
(7)定义网络模型,我们使用5个卷积层+平铺层+全连接层+输出层
其中,我们设置输入的格式为input_shape=(300,300,3),即输入是大小为300x300的彩色图片

import tensorflow as tfmodel = tf.keras.models.Sequential([# Note the input shape is the desired size of the image 300x300 with 3 bytes color# This is the first convolutiontf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(300, 300, 3)),tf.keras.layers.MaxPooling2D(2, 2),# The second convolutiontf.keras.layers.Conv2D(32, (3,3), activation='relu'),tf.keras.layers.MaxPooling2D(2,2),# The third convolutiontf.keras.layers.Conv2D(64, (3,3), activation='relu'),tf.keras.layers.MaxPooling2D(2,2),# The fourth convolutiontf.keras.layers.Conv2D(64, (3,3), activation='relu'),tf.keras.layers.MaxPooling2D(2,2),# The fifth convolutiontf.keras.layers.Conv2D(64, (3,3), activation='relu'),tf.keras.layers.MaxPooling2D(2,2),# Flatten the results to feed into a DNNtf.keras.layers.Flatten(),# 512 neuron hidden layertf.keras.layers.Dense(512, activation='relu'),# Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('horses') and 1 for the other ('humans')tf.keras.layers.Dense(1, activation='sigmoid')
])

(8)输出网络结构的摘要信息

model.summary()

在这里插入图片描述
(9)设置网络的编译环境,损失函数,优化器,计算指标。。。

from tensorflow.keras.optimizers import RMSpropmodel.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])

(10)预处理数据集
注意:
1:第一个目录参数值为训练集或验证集的根目录,其中包括不同类型数据的子目录
2:batch_size设置的值要记住,后面会用到

from tensorflow.keras.preprocessing.image import ImageDataGenerator# 将图片像素值归一化,[0,255]->[0,1]
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)# 训练集生成器
train_generator = train_datagen.flow_from_directory('/tmp/horse-or-human/',  #训练数据的根目录,其中包括两个子目录,因为人和马都是训练数据target_size=(300, 300),  # 调整图片的大小为300x300batch_size=128,#训练更新时,每一批次的图片数目为128# 因为只有两类,所以我们使用0,1标签标记数据。生成去会将每一个子目录下的图片标记为同一种标签,第一个子目录下标记为0,第二个标记为1class_mode='binary')#验证集生成器,同理
# Flow training images in batches of 128 using train_datagen generator
validation_generator = validation_datagen.flow_from_directory('/tmp/validation-horse-or-human/',  # This is the source directory for training imagestarget_size=(300, 300),  # All images will be resized to 150x150batch_size=32,# Since we use binary_crossentropy loss, we need binary labelsclass_mode='binary')

在这里插入图片描述
(11)训练模型
不在使用model.fit() 而是使用 model.fit_generator()

history = model.fit_generator(train_generator,#训练集生成器steps_per_epoch=8,  #训练集每次完全迭代需要多少批次 1027/128=8epochs=15, #迭代次数verbose=1, #每次迭代后都进行验证validation_data = validation_generator,#验证集生成器validation_steps=8 #验证集每次完全迭代需要多少批次 256/32=8
)

在这里插入图片描述
(12)测试
上传一些图片到 /content目录下,进行测试,每次可以处理10张图片

import numpy as np
from google.colab import files
from keras.preprocessing import imageuploaded = files.upload()for fn in uploaded.keys():# predicting imagespath = '/content/' + fnimg = image.load_img(path, target_size=(300, 300))x = image.img_to_array(img)x = np.expand_dims(x, axis=0)images = np.vstack([x])classes = model.predict(images, batch_size=10)print(classes[0])if classes[0]>0.5:print(fn + " is a human")else:print(fn + " is a horse")

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,模型 错误 的将马的图片分为了人

我们再看看之前的训练信息可知,模型在后几轮的训练准确率都是100%,模型很可能陷入了过拟合的状态
在这里插入图片描述
(13)优化
我们可以使用 callbacks机制,使得当训练准确率大于 99.9%时停止训练

我们只需在 训练模型 步骤之前,定义和实例化 callbacks对象,并在fit_generator()中加入callbacks参数

class myCallback(tf.keras.callbacks.Callback):def on_epoch_end(self, epoch, logs={}):if(logs.get('acc')>0.999):print("\nReached 99.9% accuracy so cancelling training!")self.model.stop_training = Truecallbacks = myCallback()history = model.fit_generator(train_generator,steps_per_epoch=8,  epochs=15,verbose=1,validation_data = validation_generator,validation_steps=8,callbacks=[callbacks]
)

再次训练
在这里插入图片描述
测试:这次就全分类正确了
在这里插入图片描述

这篇关于Tensorflow实现人马图片的分类器 [使用ImageDataGenerator 无需人为标注数据]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/679446

相关文章

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

MySQL8.0设置redo缓存大小的实现

《MySQL8.0设置redo缓存大小的实现》本文主要在MySQL8.0.30及之后版本中使用innodb_redo_log_capacity参数在线更改redo缓存文件大小,下面就来介绍一下,具有一... mysql 8.0.30及之后版本可以使用innodb_redo_log_capacity参数来更改

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个