Deep Learning with Python猫狗大战cats-vs-dogs学习笔记(1)

最近我通过这本书Deep Learning with Python在学习,其中第一个例子是采用了kaggle上面的cats-vs-dogs 猫狗大战,根据书上的代码,第一次发生了过拟合现象,根据第二次通过数据增强之后,发现一直在提示run out of data,因此记录这一部分的学习过程。

第二部分为了解决过拟合采用数据增强的代码

首先分为两部分,第一部分是对数据进行分类,第二部分是对数据进行处理。在对数据进行分类的时候,我们需要从dataset里面取出数据构造新的数据集,其中我们需要取出一部分数据作为train文件,另一部分作为validation文件,最后一部分作为test文件,在train文件中我们需要有cat train和dog train,同样我们需要cat validation和dog validation,还有cat test和dog test。

之后是数据处理,我们在第一次的小型神经网络的密集链接分类器之前添加一个Dropout层即可。

import os , shutil
#导入这几个库
original_dataset_dir = '/home/weijia/Desktop/deeplearning-practice/dogs-vs-cats/train'
#这段话的意思是 原数据集在这个文件夹里
base_dir = '/home/weijia/Desktop/deeplearning-practice/dogs-vs-cats/base_dir'
os.mkdir(base_dir)
#这段话的意思是在/home/weijia/Desktop/deeplearning-parctice/dogs-vs-cats路径里新建一个base_dir来储存要创建的文件
train_dir = os.path.join(base_dir , 'train')
os.mkdir(train_dir)
#os.path.join的意思是在和上面相同的路径上,base_dir就是在要生成的文件里,‘train’可以理解为文件类型,os.mkdir就是在那个陆经理创建,括号里的train_dir就是要创建的内容
validation_dir = os.path.join(base_dir , 'validation')
os.mkdir(validation_dir)
#这一部分同理了,意思是在相同路径的base_dir里面创建一个validation_dir文件,这个文件类型是‘validation’,注意这个文件类型不是真正的文件类型的意思
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_dir文件里创建train_cats_dir文件,意思是train_dir中的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)
#上面几行代码不难理解,到此为止我们在base_dir文件中创建了train_dir , validation_dir , test_dir ,其中train_dir 中又包含了train_cats_dir,train_dogs_dir,
#validation_dir中又包含了validation_dogs_dir,validation_dogs_dir,同理test_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)
#这段代码的意思是我们取数据来把它们分到这个文件夹里,因为从网上下载下来的训练集的文件名格式都是cat.number.jpg,所以我们在这里写cat.{}.jpg意思就是名字是这个的文件统一做这个操作,
#range(1000)就是0到1000,src表示源,可以理解为从哪来的数据,dst表示要放到哪,最后shutil.copyfile(src , dst)表示‘整合’的意思
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)

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)

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)

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)

fname = ['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(len(os.listdir(train_cats_dir)))
print(len(os.listdir(train_dogs_dir)))
print(len(os.listdir(validation_cats_dir)))
print(len(os.listdir(validation_dogs_dir)))
print(len(os.listdir(test_cats_dir)))
print(len(os.listdir(test_dogs_dir)))'''
'''这一部分查看自己整理的数据中都有多少张照片'''
from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32 , (3 , 3) , activation = 'relu', input_shape = (150 , 150  , 3)))
#第一个Conv2D层,激活函数为relu,输入形状为(150 , 150 , 3)
model.add(layers.MaxPool2D((2 , 2)))
#第一个池化层
model.add(layers.Conv2D(64 , (3 , 3) , activation = 'relu'))
model.add(layers.MaxPool2D((2 , 2)))
model.add(layers.Conv2D(128 , (3 , 3) , activation = 'relu'))
model.add(layers.MaxPool2D((2 , 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512 , activation = 'relu'))
model.add(layers.Dense(1 , activation = 'sigmoid'))
#构建神经网络

from tensorflow.keras import optimizers

model.compile(loss = 'binary_crossentropy' , optimizer = optimizers.RMSprop(lr= 1e-4) , metrics = ['acc'])
#构建optimizer优化器
from keras.preprocessing.image import ImageDataGenerator
#数据增强 注意只对训练集进行增强,因为测试集是测试用途,所以不需要增强。
train_datagen = ImageDataGenerator(
    rescale = 1./255 ,#除以255,让这个东西小于1
    rotation_range = 40 ,
    width_shift_range = 0.2 ,
    height_shift_range = 0.2 ,
    shear_range = 0.2 ,
    zoom_range = 0.2 ,
    horizontal_flip = True ,
)

test_datagen = ImageDataGenerator(rescale = 1./255)

train_generator = train_datagen.flow_from_directory(
    train_dir ,#数据来自于哪里
    target_size = (150 , 150) ,#目标大小为(150 , 150),统一大小
    batch_size = 32 ,#每一批有多少数据
    class_mode = 'binary'#因为使用了binary_crossentropy损失,所以这里用二进制标签
)

validation_generator = test_datagen.flow_from_directory(
    validation_dir ,#数据来自于验证集
    target_size = (150 , 150) ,
    batch_size = 32 ,#每一批有32个数据
    class_mode = 'binary'
)

history = model.fit_generator(
    train_generator ,
    steps_per_epoch = 63 ,
    epochs = 100 ,
    validation_data = validation_generator ,
    validation_steps = 32
)
#这里需要注意,
# epoch意思是一共训练多少批,
# steps_per_epoch意思是一批训练多少个
#根据我们的训练集有猫1000只,狗1000只来看,我们共有2000张图片作为训练集,其中每一批有32个数据,那么2000/32=62.5 , 取整数一共有63批,
#简单来说就是在2000张照片中,把照片按照规律摞在一起,每一摞有32张照片,只能多不能少,那么一共需要63摞才能把这些照片摞在一起
#所以steps_per_epoch = 63 , validation_steps = 32(和第126行一样),这是书上的错误之处
model.save('cats_and_dogs_small_2.h5')
#保存模型
import matplotlib.pyplot as plt
#导入库准备绘制图像
acc = history.history['acc']#acc就是历史中的acc
val_acc = history.history['val_acc']#val_acc就是validation acc 也是历史中的
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1 , len(acc) + 1)

plt.plot(epochs , acc , 'bo' , label = 'Training acc')#横坐标是epoch,纵坐标是acc,类型为bo,标签为Training acc
plt.plot(epochs , val_acc , 'b' , label = 'Validation acc')#同理
plt.title('Training and validation accuracy')#图片名字为Training and validation accurary
plt.legend()

plt.figure()

plt.plot(epochs , loss , 'bo' , label = 'Training loss')#同理
plt.plot(epochs , val_loss , 'b' , label = 'Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()
#最终显示图像并完成

Deep Learning with Python猫狗大战cats-vs-dogs学习笔记(1) 

上一篇:Chrome浏览器加载script机制浅谈


下一篇:JavaScript