卷积神经网络图像分类
- 1 理解卷积神经网络
- 1.1 搭建环境
- 1.2 猫狗分析实例
- 2 卷积神经网络
- 2.1 网络模型搭建
- 2.2 使用图像生成器读取图片
本次实验将完成以下任务:
- 按照 python笔记本深度学习,利用TensorFlow和Keras,自己搭建卷积神经网络完成狗猫数据集的分类实验;将关键步骤用汉语注释出来。解释什么是overfit(过拟合)?什么是数据增强?如果单独只做数据增强,精确率提高了多少?然后再添加的dropout层,是什么实际效果?
- 用Vgg19网络模型完成狗猫分类,写出实验结果;
1 理解卷积神经网络
1.1 搭建环境
首先,检查一下anaconda的版本号,随后创建名为tensorflow的conda环境
conda --version //检查Anaconda版本号(安装失败则会提示)
conda create -n tensorflow pip python=3.6 //创建名为tensorflow的conda环境
创建好后,输入activate tensorflow
激活环境,如果出现前缀则激活成功
在进入环境的条件下下载Tensorflow的纯CPU版
pip install --ignore-installed --upgrade tensorflow
退出后查看环境,能够看到tensorflow就算成功
安装keras
pip install keras
将环境改为刚才创建的tensorflow,再安装一个jupyter(需要一点时间)
PS:可以在刚才的控制台中添加如下库,添加jupyter_contrib_nbextensions插件
功能:自动补全代码功能+pep8+字体大小+代码行号+拼写检查+目录索引
等功能
pip install jupyter_contrib_nbextensions -i https://pypi.douban.com/simple/
jupyter contrib nbextension install --user --skip-running-check
勾了一个hinterland,代码自动补全
1.2 猫狗分析实例
回归题目,新建一个Python3后,引入keras包,查看版本(主要看是否下载成功)
添加如下代码(注意自己训练图片的地址和创建文件夹的地址)
import os, shutil #复制文件
# 原始目录所在的路径
# 数据集未压缩
original_dataset_dir = 'D:\\QQ\\kaggle_Dog&Cat\\train'# The directory where we will
# store our smaller dataset
base_dir = 'D:\QQ\kaggle_Dog&Cat\\find_cats_and_dogs'
os.mkdir(base_dir)# # 训练、验证、测试数据集的目录
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_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)# 狗验证数据集所在目录
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)# 狗测试数据集所在目录
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_dataset_dir, fname)dst = os.path.join(train_cats_dir, fname)shutil.copyfile(src, dst)# 将下500张猫图像复制到validation_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:src = os.path.join(original_dataset_dir, fname)dst = os.path.join(validation_cats_dir, fname)shutil.copyfile(src, dst)# 将下500张猫图像复制到test_cats_dir
fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:src = os.path.join(original_dataset_dir, fname)dst = os.path.join(test_cats_dir, fname)shutil.copyfile(src, dst)# 将前1000张狗图像复制到train_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:src = os.path.join(original_dataset_dir, fname)dst = os.path.join(train_dogs_dir, fname)shutil.copyfile(src, dst)# 将下500张狗图像复制到validation_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:src = os.path.join(original_dataset_dir, fname)dst = os.path.join(validation_dogs_dir, fname)shutil.copyfile(src, dst)# 将下500张狗图像复制到test_dogs_dir
fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:src = os.path.join(original_dataset_dir, fname)dst = os.path.join(test_dogs_dir, fname)shutil.copyfile(src, dst)
点开文件夹看了一下,数据集已经被创建好了
以防万一还是检查一下图片数量
print('total training cat images:', len(os.listdir(train_cats_dir)))
print('total training dog images:', len(os.listdir(train_dogs_dir)))
print('total validation cat images:', len(os.listdir(validation_cats_dir)))
print('total validation dog images:', len(os.listdir(validation_dogs_dir)))
print('total test cat images:', len(os.listdir(test_cats_dir)))
print('total test dog images:', len(os.listdir(test_dogs_dir)))
可以看到,验证图片,测试图片,训练图片都已经准备好了。
2 卷积神经网络
接来下将要使用深度学习最经典的算法卷积神经网络CNN
2.1 网络模型搭建
首先使用model.summary()
输出模型各层的参数状况
from keras import layers
from keras import modelsmodel = 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.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
2.2 使用图像生成器读取图片
- model.compile()优化器(loss:计算损失,这里用的是交叉熵损失,metrics: 列表,包含评估模型在训练和测试时的性能的指标)
- 将所有图片的尺寸设置为150150统一*
- ImageDataGenerator就像一个把文件中图像转换成所需格式的转接头,通常先定制一个转接头train_datagen,它可以根据需要对图像进行各种变换,然后再把放入相应位置中,规定数据的格式(图像的大小、每次的数量、样本标签的格式等)。其中train_generator是个(X,y)元组,X的shape为(20,150,150,3),y的shape为(20,)
from keras import optimizersmodel.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=1e-4),metrics=['acc'])
from keras.preprocessing.image import ImageDataGenerator# 所有图像将按1/255重新缩放
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_directory(# 这是目标目录train_dir,# 所有图像将调整为150x150target_size=(150, 150),batch_size=20,# 因为我们使用二元交叉熵损失,我们需要二元标签class_mode='binary')validation_generator = test_datagen.flow_from_directory(validation_dir,target_size=(150, 150),batch_size=20,class_mode='binary')