猫狗识别与分类
文章目录
一、前言
在实现猫狗识别的时候,我看到csdn上检索的猫狗识别有一些博客比较繁杂,可是作为正式进入AL世界的Hello world,这是不合理的,代码本来就不复杂。
繁杂的操作和图片有点让人生畏,所以我决定有必要重写一下程序、记录一下过程。
下面是一些国内的pip源,有需要可自取
阿里云 http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) http://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
二、环境配置
软件:ANACONDA3+Pycharm2019
keras>=2.7;
tensorflow>=2.7
注:一定关掉科学上网
三、源码以及数据集
链接:https://pan.baidu.com/s/1gvFfpK64Z16rkW81jWVZdw
提取码:f1ff
四、基础猫狗识别程序如下
1、train.py
基于卷积池化构架的猫狗识别训练程序
train.py程序结构:
- 第一步:导入包
- 第二步:指定一些超参数
- 第三步:准备训练集和验证集
- 第四步:建立神经网络模型
- 第五步:训练模型
- *第六步:根据训练过程中的信息绘制图表
import numpy as np
import os,random,shutil
np.random.seed(7)
FOLDER=".\\dataset_default"
train_data_dir=os.path.join(FOLDER,'train')
val_data_dir=os.path.join(FOLDER,'validate')
train_samples_num=4916
val_samples_num=1439
IMG_W,IMG_H,IMG_CH=150,150,3
batch_size=32
epochs=20
class_num=2
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
rescale=1. / 255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
color_mode='rgb',
class_mode='categorical')
val_datagen = ImageDataGenerator(rescale=1. / 255)
val_generator = val_datagen.flow_from_directory(
val_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
color_mode='rgb',
class_mode='categorical')
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
def build_model(input_shape):
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Dense(class_num))
model.add(Activation("softmax"))
from tensorflow import optimizers
model.compile(
loss="categorical_crossentropy",
optimizer='adam',
metrics=["accuracy"],
)
return model
model=build_model(input_shape=(IMG_W,IMG_H,IMG_CH))
history_ft = model.fit(train_generator,
steps_per_epoch=train_samples_num // batch_size,
epochs=epochs,
validation_data=val_generator,
validation_steps=val_samples_num // batch_size
)
model.save("./model.h5")
print(history_ft.history.keys())
import matplotlib.pyplot as plt
acc = history_ft.history['accuracy']
val_acc = history_ft.history['val_accuracy']
loss = history_ft.history['loss']
val_loss = history_ft.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='validate acc')
plt.title('Training and validation acc')
plt.legend()
plt.show()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='validate Loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
2、detect.py
detect.py程序结构:
- 第一步:导入库以及定义一些参数
- 第二步:定义一个函数,从测试文件夹内读取任意一张图片
- 第三步:定义一个预测函数
- *第四步:载入模型并预测
import os, random
from matplotlib.pyplot import imshow
import numpy as np
import matplotlib.pyplot as plt
IMG_W,IMG_H,IMG_CH=150,150,3
def read_random_image():
folder=r"./Imgs/"
file_path = folder + random.choice(os.listdir(folder))
pil_im = Image.open(file_path, 'r')
return pil_im
from PIL import Image
from keras.preprocessing import image
def predict(model, img, target_size):
name = ["猫", "狗"]
if img.size != target_size:
img = img.resize(target_size)
x = image.img_to_array(img)
x *= 1. / 255
x = np.expand_dims(x, axis=0)
preds = model.predict(x)
imshow(np.asarray(img))
print(preds)
for i in range(2):
if preds[0][i]>0.5:
print(name[i])
break
from keras.models import load_model
model_path = './model.h5'
model = load_model(model_path)
print("下面将抽五张图并预测如下:")
for i in range(5):
print("该图片的猫狗概率如下:")
predict(model,read_random_image(),(IMG_W,IMG_H))
plt.show()
'''
test_datagen = ImageDataGenerator(rescale=1. / 255) # 只需要和trainset同样的scale即可,不需增强
test_data_dir="./data_oppo/train"
val_generator = test_datagen.flow_from_directory(
test_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=32,
color_mode='rgb',
class_mode='categorical')
test_loss,test_acc=model.evaluate(val_generator)
print("test_acc={} test_loss={}".format(test_acc,test_loss))
'''
以下是跑通这个程序的过程。如果清楚这些步骤的过程可以略过下面
五、配置环境过程
1、打开Anaconda Prompt
a、创建一个叫MNIST4的环境
conda create -n MNIST4 python=3.8
注:记得python=3.8,大了就下载不了tensorflow包了
注:名字不重要,你之后想起什么名字都可以
b、创建成功后激活环境并下载keras包:
conda activate MNIST4
为了提高下载速度,在国内清华源中下载keras包
pip install keras -i https://pypi.tuna.tsinghua.edu.cn/simple/
c、下载matplotlib包
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple/
d、下载tensorflow包
pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple/
e、下载SciPy包
pip install SciPy -i https://pypi.tuna.tsinghua.edu.cn/simple/
2、打开Pycharm配置
配置代码运行环境
注:这里刷新出来的时候比较长,需要等等
之后一路点击确认下去
; 六、运行基础程序
这个程序是最基础的程序,有训练模型,部署模型的能力,数据集6000简单训练20轮,验证集精度大概有0.7的精度,
当然这只是用来玩的基础版本,一定要理解, 之后的VGG–>Res–>DenseNet–>EffectionNet
也都只是时间问题了。
1、运行train程序
a、将开头的程序copy进pycharm的程序中
; b、运行结果:
这样就训练成功了。
训练数据画图如下:
1、运行detect程序
a、将开头的detect程序进pycharm的程序中
; b、运行结果
七、基于DenseNet神经网络构架的猫狗识别训练程序
DenseNet神经网络架构是2017年比较活的架构
到2020年虽然干不过谷歌的EffectionNet不过在很多方面已经很优秀了
所以特意举这个例子
数据集:6000
验证集精度大概在0.97左右。
1、在之前的基础上导入sklearn包
pip install sklearn -i https://pypi.tuna.tsinghua.edu.cn/simple/
2、将程序copy到pycharm
train.py程序结构
- 第一步:导入相应的库和指定超参数
- 第二步:学习率修改函数
- 第三步:准备训练集
- 第四步:建立Keras模型:模型的建立主要包括模型的搭建,模型的编译
- 第五步:回调函数
- 第六步:模型的训练
- 第七步:绘制训练过程图像
from idlelib import history
from tensorflow.keras.callbacks import ReduceLROnPlateau,ModelCheckpoint
import tensorflow as tf
import os
FOLDER=".\\dataset_default"
train_data_dir=os.path.join(FOLDER,'train')
val_data_dir=os.path.join(FOLDER,'validate')
train_samples_num=4916
val_samples_num=1439
IMG_W,IMG_H,IMG_CH=150,150,3
batch_size=32
epochs=10
class_num=2
if not os.path.exists("save_weights"):
os.makedirs("save_weights")
def lr_schedule(epoch):
"""Learning Rate Schedule
Learning rate is scheduled to be reduced after 80, 120, 160, 180 epochs.
Called automatically every epoch as part of callbacks during training.
# Arguments
epoch (int): The number of epochs
# Returns
lr (float32): learning rate
"""
lr = 1e-4
if epoch > 40:
lr *= 0.5e-3
elif epoch > 30:
lr *= 0.5
elif epoch > 20:
lr *= 0.5
elif epoch > 10:
lr *= 0.5
print('Learning rate: ', lr)
return lr
from keras.preprocessing.image import ImageDataGenerator
'''
在深度学习中,一般要求样本的数量要充足,样本数量越多,训练出来的模型效果越好,模型的泛化能力越强。但是实际中,样本数量不足或者样本质量不够好,这就要对样本做数据增强,来提高样本质量。
关于数据增强的作用总结如下:
1,增加训练的数据量,提高模型的泛化能力
2,增加噪声数据,提升模型的鲁棒性
讲解数据增强的文章:#https://zhuanlan.zhihu.com/p/41679153
'''
train_datagen = ImageDataGenerator(rescale=1.0 / 255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
'''
ImageDataGenerator类的简单介绍
(1)图片生成器,负责生成一个批次一个批次的图片,以生成器的形式给模型训练;
(2)对每一个批次的训练图片,适时地进行数据增强处理(data augmentation);
'''
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
shuffle=True,
color_mode='rgb',
class_mode='categorical')
val_datagen = ImageDataGenerator(rescale=1.0 / 255)
val_generator = val_datagen.flow_from_directory(
val_data_dir,
target_size=(IMG_W, IMG_H),
batch_size=batch_size,
shuffle=False,
color_mode='rgb',
class_mode='categorical')
from keras.models import Sequential
from keras.initializers import TruncatedNormal
def build_model(input_shape):
covn_base = tf.keras.applications.DenseNet121(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
covn_base.trainable = True
for layers in covn_base.layers[:-5]:
layers.trainable = False
model = tf.keras.Sequential()
model.add(covn_base)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=0.5))
model.add(tf.keras.layers.Dense(2, activation='softmax'))
model.summary()
model.compile(optimizer=tf.optimizers.RMSprop(lr_schedule(0)),
loss='binary_crossentropy',
metrics=["accuracy"])
return model
model=build_model(input_shape=(IMG_W,IMG_H,IMG_CH))
reduce_lr = ReduceLROnPlateau(
monitor='val_loss',
factor=0.1,
patience=2,
mode='auto',
verbose=1
)
checkpoint = ModelCheckpoint(
filepath='./save_weights/myDenseNet121.h5',
monitor='val_accuracy',
save_weights_only=False,
save_best_only=True,
mode='auto',
period=1
)
history_ft = model.fit(train_generator,
steps_per_epoch=train_samples_num // batch_size,
epochs=epochs,
validation_data=val_generator,
validation_steps=val_samples_num // batch_size,
callbacks=[checkpoint, reduce_lr]
)
model.save("./model2.h5")
print(history_ft.history.keys())
import matplotlib.pyplot as plt
acc = history_ft.history['accuracy']
val_acc = history_ft.history['val_accuracy']
loss = history_ft.history['loss']
val_loss = history_ft.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='validate acc')
plt.title('Training and validation acc')
plt.legend()
plt.show()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='validate Loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
3、运行结果
可以看到算比较理想,验证集精度0.97。毕竟数据集那么小,才6000张图片。
kaggle正式比赛时候训练的模型数据集可是25000张图片
至于为什么验证集精度比训练集精度高可以看这篇博客:https://blog.csdn.net/qq_51116518/article/details/122227731
Original: https://blog.csdn.net/qq_51116518/article/details/122225124
Author: 风吹落叶花飘荡
Title: 猫狗识别与分类
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/663072/
转载文章受原作者版权保护。转载请注明原作者出处!