tensorflow2.3实现猫狗数据分类预训练网络(CNN)(四)

tensorflow2.3实现猫狗数据分类预训练网络(CNN)

利用Xception预训练网络对猫狗数据分类
首先需要下载相关的数据集,可从kaggle官网进行下载。
导入包

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import glob

查看tensorflow的版本

print('Tensorflow version: {}'.format(tf.__version__))
Tensorflow version: 2.3

读取数据:
获取图片数据集,把数据标签转换为0和1,通过提取图片名字拆分定义该图是猫是狗,如果是猫标签转换为1

train_image = glob.glob('./dataset/dc_2000/train/*/*.jpg')
train_image_label = [int(p.split('/')[4] == 'cat') for p in train_image]
print(train_image_label[:5])
print(train_image_label[-5:])
[0, 0, 0, 0, 0]
[1, 1, 1, 1, 1]

图片加载与预处理,并进行图像增强
自定义训练数据函数

def load_image_train(path, label):
    image = tf.io.read_file(path)   #读取图片         
    image = tf.image.decode_jpeg(image, channels=3)# 对图片进行解码
    image = tf.image.resize(image, [360, 360])# 对图片进行变形300*300像素
    image = tf.image.random_crop(image, [256, 256, 3])# 对图片进行随机裁减为256*256像素
    image = tf.image.random_flip_left_right(image)# 对图片进行左右翻转
    image = tf.image.random_flip_up_down(image)# 对图片进行上下翻转
    image = tf.image.random_brightness(image, 0.5)# 随机修改亮度 50%的范围
    image = tf.image.random_contrast(image, 0, 1) #调整图像的对比度 在[lower, upper]的范围随机调整图的对比度
    image = tf.cast(image, tf.float32) # 改变图片格式
    image = image / 255# 对图片进行归一化
    label = tf.reshape(label, [1])# 把目标值转换成2维形状  如:[1,2,3] =>[[1],[2],[3]]
    return image, label
def load_image_test(path, label):
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [256, 256])
    image = tf.cast(image, tf.float32)
    image = image / 255
    label = tf.reshape(label, [1])
    return image, label

构建dataset

train_image_dataset = tf.data.Dataset.from_tensor_slices((train_image, train_image_label))
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_image_dataset = train_image_dataset.map(load_image_train, num_parallel_calls=AUTOTUNE)
print(train_image_dataset)

AUTOTUNE 根据计算机cpu个数自动进行计算

BATCHSIZE = 64
train_count = len(train_image)
print("train_count={}".format(train_count))
train_image_dataset = train_image_dataset.repeat().shuffle(train_count).batch(BATCHSIZE)
train_image_dataset = train_image_dataset.prefetch(buffer_size=AUTOTUNE)
train_count=2000

构建测试集

test_image = glob.glob('./dataset/dc_2000/test/*/*.jpg')
test_image_label = [int(p.split('/')[4] == 'cat') for p in test_image]
test_image_dataset = tf.data.Dataset.from_tensor_slices((test_image, test_image_label))
test_image_dataset = test_image_dataset.map(load_image_test, num_parallel_calls=AUTOTUNE)
test_image_dataset = test_image_dataset.batch(BATCHSIZE)
test_image_dataset = test_image_dataset.prefetch(AUTOTUNE)

测试集数量

test_count = len(test_image)
print("test_count={}".format(test_count))
test_count=1000

加载Xception预训练网络的训练参数

conv_base = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_shape=(256, 256, 3), pooling='avg')

weights="imagenet"使用预训练权重,include_top= False不包含全链接层

建立模型

model = tf.keras.Sequential()
conv_base.trainable = False
conv_base.summary()
model.add(conv_base)
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
conv_base.summary()
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0005), loss='binary_crossentropy', metrics=['acc'])
model.fit(train_image_dataset, epochs=initial_epochs, steps_per_epoch=train_count//BATCHSIZE, validation_data=test_image_dataset, validation_steps=test_count//BATCHSIZE)

微调

initial_epochs = 5
conv_base.trainable=True
print(len(conv_base.layers))

fine_tune_at = -33
for layer in conv_base.layers[:fine_tune_at]:
    conv_base.trainable = False

微调后,网络需要重新编译后再训练

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0005/10), loss='binary_crossentropy', metrics=['acc'])
fine_tune_epochs = 5
total_epochs = fine_tune_epochs + initial_epochs
model.fit(train_image_dataset, epochs=total_epochs, initial_epoch=initial_epochs, steps_per_epoch=train_count//BATCHSIZE, validation_data=test_image_dataset, validation_steps=test_count//BATCHSIZE)

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