Tensorflow 学习之猫狗分类案例

Tensorflow 学习之猫狗分类案例

本人一直在Cousera上学习Ng Andrew老师的Tensorflow课程,在本次猫狗分类案例当中,我对课程做了相应的记录,呈现在此,一方面加深学习的印象,另一方面记录自己学习的心得。如有错误还望各位大佬指正。

注:我使用的是Spyder进行的代码编写与运行。

文章目录

    • Tensorflow 学习之猫狗分类案例
  • 前言
  • 一、cats_and_dogs数据集
    • 1.cats_and_dogs_filtered.zip下载地址
    • 2.数据集概况
    • 3.部分图片可视化
  • 二、模型构建
    • 1.定义模型
    • 2.输出摘要
    • 3.编译
    • 4.训练过程
  • 三、预测陌生图像
  • 四、绘图
  • 总结


前言

在课程前面部分我们学习了如何处理Fashion MNIST数据集分类模型,它的特点是图片尺寸规整,聚焦于主体特征;后面又接连处理了人与马的分类模型,这里使用了ImageGenerator,使我们通过自己的操作生成训练集以及验证集。具体操作的问题在我前面写的博客里也已经详细介绍过,这里不再做细致的讨论。

我们学习的这些是处理Kaggle等地方的一些常见数据科学问题一个良好的开始,我们今天将讨论如何处理猫狗分类的问题。当然利用我们已经掌握的知识,恰好能够解决这个问题。


以下是本篇文章正文内容

一、cats_and_dogs数据集

1.cats_and_dogs_filtered.zip下载地址

第一件事我们就是要获得数据集,这里附上数据集下载地址:
cats_and_dogs_filtered.zip下载链接

2.数据集概况

数据集文件的储存为zip文件,里面包含3000张图片,2000张用于培训,1000张用于验证。
我们可以直接在其所在文件夹中进行解压。
解压之后得到cats_and_dogs_filtered文件夹,里面有train与validation两个文件夹,每个文件夹之中又都包含cats文件夹和dogs文件夹。
Tensorflow 学习之猫狗分类案例_第1张图片
在这里插入图片描述
目录作为变量,所以我们可以将生成器指向它们。

base_dir = 'cats_and_dogs_filtered'

train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')

# 猫/狗训练图片目录
train_cats_dir = os.path.join(train_dir, 'cats')
train_dogs_dir = os.path.join(train_dir, 'dogs')

# 猫/狗测试图片目录
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')

同样的,我们将目录传递给os.list,从这些目录中提取图片,并将它们放到python列表中,我们就可以查看部分图片文件名称。

train_cat_fnames = os.listdir( train_cats_dir )
train_dog_fnames = os.listdir( train_dogs_dir )

print(train_cat_fnames[:10])
print(train_dog_fnames[:10])
['cat.829.jpg', 'cat.189.jpg', 'cat.432.jpg', 'cat.647.jpg', 'cat.295.jpg', 'cat.496.jpg', 'cat.974.jpg', 'cat.301.jpg', 'cat.608.jpg', 'cat.946.jpg']
['dog.160.jpg', 'dog.216.jpg', 'dog.848.jpg', 'dog.99.jpg', 'dog.936.jpg', 'dog.67.jpg', 'dog.995.jpg', 'dog.634.jpg', 'dog.461.jpg', 'dog.791.jpg']

用下列代码,我们可以确定一下我们图片数量是否正确。

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)))

如结果所示,我们有1000张猫图和1000张狗图用于训练,500张猫图和500张狗图用于验证,总共3000张图片。

total training cat images : 1000
total training dog images : 1000
total validation cat images : 500
total validation dog images : 500

3.部分图片可视化

下面,我们可以可视化一些数据,因此我们能看到图片的多样性。

import matplotlib.image as mpimg
import matplotlib.pyplot as plt

# Parameters for our graph; we'll output images in a 4x4 configuration
nrows = 4
ncols = 4

pic_index = 0 # Index for iterating over images
 
# Set up matplotlib fig, and size it to fit 4x4 pics
fig = plt.gcf()
fig.set_size_inches(ncols*4, nrows*4)

pic_index+=8

next_cat_pix = [os.path.join(train_cats_dir, fname) 
                for fname in train_cat_fnames[ pic_index-8:pic_index] 
               ]

next_dog_pix = [os.path.join(train_dogs_dir, fname) 
                for fname in train_dog_fnames[ pic_index-8:pic_index]
               ]

for i, img_path in enumerate(next_cat_pix+next_dog_pix):
  # Set up subplot; subplot indices start at 1
  sp = plt.subplot(nrows, ncols, i + 1)
  sp.axis('Off') # Don't show axes (or gridlines)

  img = mpimg.imread(img_path)
  plt.imshow(img)

plt.show()

这段代码将随机选择8猫8狗,把它们绘制在网格中,然后看下图我们可以看出它们有非常大的多样性,动物颜色不一,姿态各异,主体位置不尽相同,图片的尺寸大小也有所不同,有的图片甚至有多个项目。
Tensorflow 学习之猫狗分类案例_第2张图片
当然,我们也可以直接从文件夹中打开图片进行观察。

二、模型构建

1.定义模型

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

2.输出摘要

print(model.summary())

这里,将看到输出形状,图像如何穿过图层的信息并逐渐减少,通过卷积和合并来确定大小。

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 148, 148, 32)      896       
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 74, 74, 32)        0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 72, 72, 64)        18496     
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 36, 36, 64)        0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 34, 34, 128)       73856     
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 17, 17, 128)       0         
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 15, 15, 128)       147584    
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 7, 7, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 6272)              0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               3211776   
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 513       
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________
None

3.编译

这里,我们编译出模型,定义损失函数和优化器。

model.compile(loss='binary_crossentropy',
              optimizer=RMSprop(lr=1e-4),
              metrics=['acc'])

该处使用的url网络请求的数据。


## 4.建立图片生成器 这里,我们建立了两个生成器,将它们指向训练和验证子目录,
# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
        train_dir,  # This is the source directory for training images
        target_size=(150, 150),  # All images will be resized to 150x150
        batch_size=20,
        # Since we use binary_crossentropy loss, we need binary labels
        class_mode='binary')

# Flow validation images in batches of 20 using test_datagen generator
validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')

history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,  # 2000 images = batch_size * steps
      epochs=100,
      validation_data=validation_generator,
      validation_steps=50,  # 1000 images = batch_size * steps
      verbose=2)

运行代码,得到下列结果,训练图片生成器在两个类别中找到2000张图片,验证图片生成器在两个类别中找到1000张图片

Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.

4.训练过程

训练不使用model.fit(),我们将使用model.fit_generator(),因为我们的数据源是生成器

history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,  # 2000 images = batch_size * steps
      epochs=100,
      validation_data=validation_generator,
      validation_steps=50,  # 1000 images = batch_size * steps
      verbose=2)

训练耗时较长,观察最后的accuracy,我们发现这个模型不算太好,但还不错。

Epoch 1/100
100/100 - 50s - loss: 0.6911 - acc: 0.5360 - val_loss: 0.6726 - val_acc: 0.6360
Epoch 2/100
100/100 - 49s - loss: 0.6575 - acc: 0.6060 - val_loss: 0.6619 - val_acc: 0.5480
Epoch 3/100
100/100 - 55s - loss: 0.6029 - acc: 0.6760 - val_loss: 0.5956 - val_acc: 0.6770
Epoch 4/100
100/100 - 52s - loss: 0.5646 - acc: 0.7130 - val_loss: 0.5774 - val_acc: 0.6980
Epoch 5/100
100/100 - 56s - loss: 0.5383 - acc: 0.7230 - val_loss: 0.5949 - val_acc: 0.6770
......
Epoch 96/100
100/100 - 51s - loss: 0.0032 - acc: 0.9990 - val_loss: 2.3710 - val_acc: 0.7390
Epoch 97/100
100/100 - 52s - loss: 0.0108 - acc: 0.9980 - val_loss: 2.3308 - val_acc: 0.7370
Epoch 98/100
100/100 - 52s - loss: 5.4245e-04 - acc: 1.0000 - val_loss: 2.3215 - val_acc: 0.7430
Epoch 99/100
100/100 - 51s - loss: 0.0082 - acc: 0.9980 - val_loss: 2.3366 - val_acc: 0.7390
Epoch 100/100
100/100 - 48s - loss: 0.0025 - acc: 0.9995 - val_loss: 2.3298 - val_acc: 0.7370

三、预测陌生图像

四、绘图

我们可以看一下该对象的训练精度和损耗值,验证准确性与验证损失值

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

你可能感兴趣的:(Tensorflow2.0学习,python,tensorflow,深度学习)