Python-猫狗数据集两阶段分类原始数据直接训练;数据增强后训练
本博客运⾏环境为Jupyter Notebook-Python3.7。
由于我使⽤的是Anaconda3配置的jupyter环境,我也将直接在anaconda下搭建keras环境。
博客⽬录
由于我电脑性能不是很好,⼜是AMD显卡的,本博客是烧cpu版本的,运⾏过程会⽐较慢。
下载tensorflow、keras
直接找到Anaconda Powershell右键管理员⾝份运⾏。
输⼊下列两条命令
conda install tensorflow
conda install keras
安装好后,可以进⼊jupyter来试⼀试了。
可以查看keras版本。
import keras
keras.__version__
输出如下:
Using TensorFlow backend.
'2.3.1'
下载数据集并重新划分
代码如下:
D://jupyterwork//AI//data//kaggle_original_data是存放原始数据集的位置,kaggle_original_data是原始数据集的名字。D://jupyterwork//AI//data//cats_and_dogs_small是创建的新数据集的位置,cats_and_dogs_small是新数据集的名字。
import os, shutil
# 原始数据集路径
original_datat_dir ='D://jupyterwork//AI//data//kaggle_original_data'
# 新的数据集
ba_dir ='D://jupyterwork//AI//data//cats_and_dogs_small' os.mkdir(ba_dir)
# 训练图像、验证图像、测试图像的⽬录
train_dir = os.path.join(ba_dir,'train')
os.mkdir(train_dir)
validation_dir = os.path.join(ba_dir,'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(ba_dir,'test')
os.mkdir(test_dir)
# 训练集-猫的图⽚
train_cats_dir = os.path.join(train_dir,'cats')
os.mkdir(train_cats_dir)
#训练集-狗的图⽚
train_dogs_dir = os.path.join(train_dir,'dogs')
os.mkdir(train_dogs_dir)
# 验证集-猫的图⽚
validation_cats_dir = os.path.join(validation_dir,'cats') os.mkdir(validation_cats_dir)
# Directory with our validation dog pictures
validation_dogs_dir = os.path.join(validation_dir,'dogs') os.mkdir(validation_dogs_dir)学会英语
# 测试集-猫的图⽚
test_cats_dir = os.path.join(test_dir,'cats')
os.mkdir(test_cats_dir)
# Directory with our validation dog pictures
test_dogs_dir = os.path.join(test_dir,'dogs')
os.mkdir(test_dogs_dir)
# 复制1000张猫的图⽚到train_cats_dir
fnames =['cat.{}.jpg'.format(i)for i in range(1000)]
for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(train_cats_dir, fname)
#复制接着的500张猫的图⽚到validation_cats_dir
fnames =['cat.{}.jpg'.format(i)for i in range(1000,1500)] for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(validation_cats_dir, fname)
# Copy next 500 cat images to test_cats_dir
元旦晚会策划fnames =['cat.{}.jpg'.format(i)for i in range(1500,2000)] for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(test_cats_dir, fname)
# Copy first 1000 dog images to train_dogs_dir
fnames =['dog.{}.jpg'.format(i)for i in range(1000)]
注电考试for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(train_dogs_dir, fname)
# Copy next 500 dog images to validation_dogs_dir fnames =['dog.{}.jpg'.format(i)for i in range(1000,1500)]
for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(validation_dogs_dir, fname)
# Copy next 500 dog images to test_dogs_dir
好吃的早餐fnames =['dog.{}.jpg'.format(i)for i in range(1500,2000)]
for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(test_dogs_dir, fname)
编译成功后,我们可以看到对应位置⽣成了新的数据集。
我们可以验证⼀下刚刚的训练分割的数据集中有多少图⽚(训练/验证/测试)
print('total training cat images:',len(os.listdir(train_cats_dir)))
total training cat images: 1000
print('total training dog images:',len(os.listdir(train_dogs_dir)))
total training dog images: 1000
print('total validation cat images:',len(os.listdir(validation_cats_dir)))苏联怎么解体的
total validation cat images: 500
print('total validation dog images:',len(os.listdir(validation_dogs_dir)))
total validation dog images: 500
print('total test cat images:',len(os.listdir(test_cats_dir)))
total test cat images: 500
print('total test dog images:',len(os.listdir(test_dogs_dir)))
total test dog images: 500
我们训练集中确实有2000个图像,验证集中有1000个验证图像,测试集中1000个图像。
卷积⽹络(ConvNet)将是⼀组交替的Conv2D(具有relu激活)和MaxPooling2D层。从⼤⼩150x150的输⼊开始,最终得到尺⼨为7x7的Flatten层之前的特征图。
注意特征图的深度在⽹络中逐渐增加(从32到128),⽽特征图的⼤⼩正在减少(从148x148到7x7)。这是⼀个⼏乎在所有的卷积⽹络(ConvNet)结构中会看到的模式。
由于我们正在处理⼆元分类问题,所以我们⽤⼀个神经元(⼀个⼤⼩为1的密集层(Den))和⼀个sigmoid激活函数来结束⽹络。该神经元将会被⽤来查看图像归属于那⼀类或另⼀类的概率。
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32,(3,3), activation='relu',
input_shape=(150,150,3)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3), activation='relu'))塑造品牌
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Den(512, activation='relu'))
model.add(layers.Den(1, activation='sigmoid'))
输出模型各层参数状况:
model.summary()
运⾏结果如下:
Model: “quential_1”
_________________________________________________________________
Layer (type) Output Shape Param #
================================================================= conv2d_1 (Conv2D) (None, 148, 148, 32) 896
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 72, 72, 64) 18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 64) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 34, 34, 128) 73856
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 128) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 15, 15, 128) 147584
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 7, 7, 128) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 6272) 0
_________________________________________________________________
den_1 (Den) (None, 512) 3211776
_________________________________________________________________
den_2 (Den) (None, 1) 513
================================================================= Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________
使⽤“RMSprop”优化器:
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
数据预处理
1、读⼊图⽚⽂件。
2、将JPEG内容解码为RBG像素⽹格。
3、把它们转换成浮点张量。
4、将像素值(介于0和255之间)重新缩放到[0,1]间隔。
Keras有⼀个带有图像处理辅助⼯具的模块,位于keras.preprocessing.image⽂件。它包含ImageData
Generator类,该类可以快速设置Python⽣成器,该⽣成器可以⾃动将磁盘上的图像⽂件转换成批预处理的张量。
代码如下:
from keras.preprocessing.image import ImageDataGenerator
# 所有的图像将重新进⾏归⼀化处理 Rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# 直接从⽬录读取图像数据
train_generator = train_datagen.flow_from_directory(
# This is the target directory
train_dir,
# 所有图像⼤⼩会被转换成150x150
target_size=(150,150),
batch_size=20,
# 由于这是⼀个⼆元分类问题,y的label值也会被转换成⼆元的标签
class_mode='binary')
# 直接从⽬录读取图像数据
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150,150),
batch_size=20,
class_mode='binary')
运⾏结果如下:
Found 2000 images belonging to 2 class.
Found 1000 images belonging to 2 class.
可以看⼀下其中⼀个⽣成器的输出:它⽣成150x150的RGB图像(shape(20,150,150,3))和⼆进制标签
(shape(20,))。
20是每批样品的数量(批量⼤⼩)。ps:⽣成器⽆限期地⽣成这些批:它只是在⽬标⽂件夹中的图像上⽆休⽌地循环。因此,我们需要在某个点上中断迭代循环。
for data_batch, labels_batch in train_generator:
print('data batch shape:', data_batch.shape)
优雅走过下雨天
print('labels batch shape:', labels_batch.shape)
break
运⾏结果如下:
data batch shape: (20, 150, 150, 3)费尔巴哈
labels batch shape: (20,)
训练