TensorFlow2.0以上版本的图像分类
ztj100 2024-11-27 23:33 11 浏览 0 评论
摘要
本篇文章采用CNN实现图像的分类,图像选取了猫狗大战数据集的1万张图像(猫狗各5千)。模型采用自定义的CNN网络,版本是TensorFlow 2.0以上的版本。通过本篇文章,你可以学到图像分类常用的手段,包括:
1、图像增强
2、训练集和验证集切分
3、使用ModelCheckpoint保存最优模型
4、使用ReduceLROnPlateau调整学习率。
5、打印loss结果生成jpg图片。
网络详解
训练部分
1、导入依赖
import os
import numpy as np
from tensorflow import keras
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout,BatchNormalization,Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D,GlobalAveragePooling2D
import cv2
from tensorflow.keras.preprocessing.image import img_to_array
from sklearn.model_selection import train_test_split
from tensorflow.python.keras import Input
from tensorflow.python.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
from tensorflow.python.keras.layers import PReLU, Activation
from tensorflow.python.keras.models import Model
2、设置全局参数
norm_size=100#输入到网络的图像尺寸,单位是像素。
datapath='train'#图片的根目录
EPOCHS =100#训练的epoch个数
INIT_LR = 1e-3#初始学习率
labelList=[]#标签
dicClass={'cat':0,'dog':1}#类别
labelnum=2#类别个数
batch_size = 4
3、加载数据
def loadImageData():
imageList = []
listImage=os.listdir(datapath)#获取所有的图像
for img in listImage:#遍历图像
labelName=dicClass[img.split('.')[0]]#获取label对应的数字
print(labelName)
labelList.append(labelName)
dataImgPath=os.path.join(datapath,img)
print(dataImgPath)
image = cv2.imdecode(np.fromfile(dataImgPath, dtype=np.uint8), -1)
# load the image, pre-process it, and store it in the data list
image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)
image = img_to_array(image)
imageList.append(image)
imageList = np.array(imageList, dtype="int") / 255.0#归一化图像
return imageList
print("开始加载数据")
imageArr=loadImageData()
labelList = np.array(labelList)
print("加载数据完成")
print(labelList)
4、定义模型
def bn_prelu(x):
x = BatchNormalization(epsilon=1e-5)(x)
x = PReLU()(x)
return x
def build_model(out_dims, input_shape=(norm_size, norm_size, 3)):
inputs_dim = Input(input_shape)
x = Conv2D(32, (3, 3), strides=(2, 2), padding='same')(inputs_dim)
x = bn_prelu(x)
x = Conv2D(32, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = GlobalAveragePooling2D()(x)
dp_1 = Dropout(0.5)(x)
fc2 = Dense(out_dims)(dp_1)
fc2 = Activation('softmax')(fc2) #此处注意,为sigmoid函数
model = Model(inputs=inputs_dim, outputs=fc2)
return model
model=build_model(labelnum)#生成模型
optimizer = Adam(lr=INIT_LR)#加入优化器,设置优化器的学习率。
model.compile(optimizer =optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
5、切割训练集和验证集
trainX,valX,trainY,valY = train_test_split(imageArr,labelList, test_size=0.3, random_state=42)
6、数据增强
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)
val_datagen = ImageDataGenerator() #验证集不做图片增强
train_generator = train_datagen.flow(trainX,trainY,batch_size=batch_size,shuffle=True)
val_generator = val_datagen.flow(valX,valY,batch_size=batch_size,shuffle=True)
7、设置callback函数
checkpointer = ModelCheckpoint(filepath='weights_best_simple_model.hdf5',
monitor='val_accuracy',verbose=1, save_best_only=True, mode='max')
reduce = ReduceLROnPlateau(monitor='val_accuracy',patience=10,
verbose=1,
factor=0.5,
min_lr=1e-6)
8、训练并保存模型
history = model.fit_generator(train_generator,
steps_per_epoch=trainX.shape[0]/batch_size,
validation_data = val_generator,
epochs=EPOCHS,
validation_steps=valX.shape[0]/batch_size,
callbacks=[checkpointer,reduce],
verbose=1,shuffle=True)
model.save('my_model_.h5')
9、保存训练历史数据
import os
loss_trend_graph_path = r"WW_loss.jpg"
acc_trend_graph_path = r"WW_acc.jpg"
import matplotlib.pyplot as plt
print("Now,we start drawing the loss and acc trends graph...")
# summarize history for accuracy
fig = plt.figure(1)
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("Model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(acc_trend_graph_path)
plt.close(1)
# summarize history for loss
fig = plt.figure(2)
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("Model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(loss_trend_graph_path)
plt.close(2)
print("We are done, everything seems OK...")
# #windows系统设置10关机
os.system("shutdown -s -t 10")
img
img
完整代码: import os
import numpy as np
from tensorflow import keras
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout,BatchNormalization,Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D,GlobalAveragePooling2D
import cv2
from tensorflow.keras.preprocessing.image import img_to_array
from sklearn.model_selection import train_test_split
from tensorflow.python.keras import Input
from tensorflow.python.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
from tensorflow.python.keras.layers import PReLU, Activation
from tensorflow.python.keras.models import Model
norm_size=100
datapath='train'
EPOCHS =100
INIT_LR = 1e-3
labelList=[]
dicClass={'cat':0,'dog':1}
labelnum=2
batch_size = 4
def loadImageData():
imageList = []
listImage=os.listdir(datapath)
for img in listImage:
labelName=dicClass[img.split('.')[0]]
print(labelName)
labelList.append(labelName)
dataImgPath=os.path.join(datapath,img)
print(dataImgPath)
image = cv2.imdecode(np.fromfile(dataImgPath, dtype=np.uint8), -1)
# load the image, pre-process it, and store it in the data list
image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)
image = img_to_array(image)
imageList.append(image)
imageList = np.array(imageList, dtype="int") / 255.0
return imageList
print("开始加载数据")
imageArr=loadImageData()
labelList = np.array(labelList)
print("加载数据完成")
print(labelList)
def bn_prelu(x):
x = BatchNormalization(epsilon=1e-5)(x)
x = PReLU()(x)
return x
def build_model(out_dims, input_shape=(norm_size, norm_size, 3)):
inputs_dim = Input(input_shape)
x = Conv2D(32, (3, 3), strides=(2, 2), padding='same')(inputs_dim)
x = bn_prelu(x)
x = Conv2D(32, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(x)
x = bn_prelu(x)
x = GlobalAveragePooling2D()(x)
dp_1 = Dropout(0.5)(x)
fc2 = Dense(out_dims)(dp_1)
fc2 = Activation('softmax')(fc2) #此处注意,为sigmoid函数
model = Model(inputs=inputs_dim, outputs=fc2)
return model
model=build_model(labelnum)
optimizer = Adam(lr=INIT_LR)
model.compile(optimizer =optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
trainX,valX,trainY,valY = train_test_split(imageArr,labelList, test_size=0.3, random_state=42)
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)
val_datagen = ImageDataGenerator() #验证集不做图片增强
train_generator = train_datagen.flow(trainX,trainY,batch_size=batch_size,shuffle=True)
val_generator = val_datagen.flow(valX,valY,batch_size=batch_size,shuffle=True)
checkpointer = ModelCheckpoint(filepath='weights_best_simple_model.hdf5',
monitor='val_accuracy',verbose=1, save_best_only=True, mode='max')
reduce = ReduceLROnPlateau(monitor='val_accuracy',patience=10,
verbose=1,
factor=0.5,
min_lr=1e-6)
history = model.fit_generator(train_generator,
steps_per_epoch=trainX.shape[0]/batch_size,
validation_data = val_generator,
epochs=EPOCHS,
validation_steps=valX.shape[0]/batch_size,
callbacks=[checkpointer,reduce],
verbose=1,shuffle=True)
model.save('my_model_.h5')
print(history)
import os
loss_trend_graph_path = r"WW_loss.jpg"
acc_trend_graph_path = r"WW_acc.jpg"
import matplotlib.pyplot as plt
print("Now,we start drawing the loss and acc trends graph...")
# summarize history for accuracy
fig = plt.figure(1)
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("Model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(acc_trend_graph_path)
plt.close(1)
# summarize history for loss
fig = plt.figure(2)
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("Model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(loss_trend_graph_path)
plt.close(2)
print("We are done, everything seems OK...")
# #windows系统设置10关机
os.system("shutdown -s -t 10")
测试部分 1、导入依赖 import cv2
import numpy as np
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
import time
2、设置全局参数 norm_size=100
imagelist=[]
emotion_labels = {
0: 'cat',
1: 'dog'
}
3、加载模型 emotion_classifier=load_model(**"my_model_.h5"**)
t1=time.time()
4、处理图片 image = cv2.imdecode(np.fromfile(**'test/8.jpg'**, dtype=np.uint8), -1)
\# load the image, pre-process it, and store it in the data list
image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)
image = img_to_array(image)
imagelist.append(image)
imageList = np.array(imagelist, dtype=**"float"**) / 255.0
5、预测类别 pre=np.argmax(emotion_classifier.predict(imageList))
emotion = emotion_labels[pre]
t2=time.time()
print(emotion)
t3=t2-t1
print(t3)
完整代码 import cv2
import numpy as np
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
import time
norm_size=100
imagelist=[]
emotion_labels = {
0: 'cat',
1: 'dog'
}
emotion_classifier=load_model("my_model_.h5")
t1=time.time()
image = cv2.imdecode(np.fromfile('test/8.jpg', dtype=np.uint8), -1)
# load the image, pre-process it, and store it in the data list
image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)
image = img_to_array(image)
imagelist.append(image)
imageList = np.array(imagelist, dtype="float") / 255.0
pre=np.argmax(emotion_classifier.predict(imageList))
emotion = emotion_labels[pre]
t2=time.time()
print(emotion)
t3=t2-t1
print(t3)
相关推荐
- Whoosh,纯python编写轻量级搜索工具
-
引言在许多应用程序中,搜索功能是至关重要的。Whoosh是一个纯Python编写的轻量级搜索引擎库,可以帮助我们快速构建搜索功能。无论是在网站、博客还是本地应用程序中,Whoosh都能提供高效的全文搜...
- 如何用Python实现二分搜索算法(python二分法查找代码)
-
如何用Python实现二分搜索算法二分搜索(BinarySearch)是一种高效的查找算法,适用于在有序数组中快速定位目标值。其核心思想是通过不断缩小搜索范围,每次将问题规模减半,时间复杂度为(O...
- 路径扫描 -- dirsearch(路径查找器怎么使用)
-
外表干净是尊重别人,内心干净是尊重自己,干净,在今天这个时代,应该是一种极高的赞美和珍贵。。。----网易云热评一、软件介绍Dirsearch是一种命令行工具,可以强制获取web服务器中的目录和文件...
- 78行Python代码帮你复现微信撤回消息!
-
来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。...
- 从零开始学习 Python!2《进阶知识》 Python进阶之路
-
欢迎来到Python学习的进阶篇章!如果你说已经掌握了基础语法,那么这篇就是你开启高手之路的大门。我们将一起探讨面向对象编程...
- 白帽黑客如何通过dirsearch脚本工具扫描和收集网站敏感文件
-
一、背景介绍...
- Python之txt数据预定替换word预定义定位标记生成word报告(四)
-
续接Python之txt数据预定替换word预定义定位标记生成word报告(一)https://mp.toutiao.com/profile_v4/graphic/preview?pgc_id=748...
- Python——字符串和正则表达式中的反斜杠('\')问题详解
-
在本篇文章里小编给大家整理的是关于Python字符串和正则表达式中的反斜杠('\')问题以及相关知识点,有需要的朋友们可以学习下。在Python普通字符串中在Python中,我们用'\'来转义某些普通...
- Python re模块:正则表达式综合指南
-
Python...
- python之re模块(python re模块sub)
-
re模块一.re模块的介绍1.什么是正则表达式"定义:正则表达式是一种对字符和特殊字符操作的一种逻辑公式,从特定的字符中,用正则表达字符来过滤的逻辑。(也是一种文本模式;)2、正则表达式可以帮助我们...
- MySQL、PostgreSQL、SQL Server 数据库导入导出实操全解
-
在数字化时代,数据是关键资产,数据库的导入导出操作则是连接数据与应用场景的桥梁。以下是常见数据库导入导出的实用方法及代码,包含更多细节和特殊情况处理,助你应对各种实际场景。一、MySQL数据库...
- Zabbix监控系统系列之六:监控 mysql
-
zabbix监控mysql1、监控规划在创建监控项之前要尽量考虑清楚要监控什么,怎么监控,监控数据如何存储,监控数据如何展现,如何处理报警等。要进行监控的系统规划需要对Zabbix很了解,这里只是...
- mysql系列之一文详解Navicat工具的使用(二)
-
本章内容是系列内容的第二部分,主要介绍Navicat工具的使用。若查看第一部分请见:...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Whoosh,纯python编写轻量级搜索工具
- 如何用Python实现二分搜索算法(python二分法查找代码)
- 路径扫描 -- dirsearch(路径查找器怎么使用)
- 78行Python代码帮你复现微信撤回消息!
- 从零开始学习 Python!2《进阶知识》 Python进阶之路
- 白帽黑客如何通过dirsearch脚本工具扫描和收集网站敏感文件
- Python之txt数据预定替换word预定义定位标记生成word报告(四)
- 假期苦短,我用Python!这有个自动回复拜年信息的小程序
- Python——字符串和正则表达式中的反斜杠('\')问题详解
- Python re模块:正则表达式综合指南
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)