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

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

首先需要下载相关的数据集,可从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)
<ParallelMapDataset shapes: ((256, 256, 3), (1,)), types: (tf.float32, tf.int32)>

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

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

conv_base = tf.keras.applications.VGG16(weights='imagenet', include_top=False)

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

建立模型

model = tf.keras.Sequential()# 建立一个顺序模型
model.add(conv_base)# 添加vgg16卷积机
model.add(tf.keras.layers.GlobalAveragePooling2D())# 全局平均池化,深度神经网络中经常使用的一个层,使用前后的
#尺寸分别为[B,H,W,C]->[B,C].特别要注意,这个层使用之后特征图尺寸的维度变成了2维而非4维。
model.add(tf.keras.layers.Dense(512, activation='relu'))# 输出512个单元
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
print('train_count//BATCHSIZE={}'.format(train_count//BATCHSIZE))# 输出1个单元,sigmoid概率值
conv_base.trainable = False
model.summary()
train_count//BATCHSIZE=31
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
vgg16 (Functional)           (None, None, None, 512)   14714688  
_________________________________________________________________
global_average_pooling2d (Gl (None, 512)               0         
_________________________________________________________________
dense (Dense)                (None, 512)               262656    
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 513       
=================================================================
Total params: 14,977,857
Trainable params: 263,169
Non-trainable params: 14,714,688
_________________________________________________________________

conv_base.trainable = False表示预训练网络参数不用训练

网络编译

model.compile(loss='binary_crossentropy', optimizer = tf.keras.optimizers.Adam(lr=0.001), metrics = ['acc'])
history = model.fit(train_image_dataset, steps_per_epoch=train_count//BATCHSIZE, epochs=22, validation_data=test_image_dataset, validation_steps=test_count//BATCHSIZE)
Epoch 1/22
2021-04-29 15:15:44.026091: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:127] None of the MLIR optimization passes are enabled (registered 2)
2021-04-29 15:15:44.049180: I tensorflow/core/platform/profile_utils/cpu_utils.cc:112] CPU Frequency: 2200000000 Hz
31/31 [==============================] - 173s 6s/step - loss: 0.6341 - acc: 0.6004 - val_loss: 0.5192 - val_acc: 0.7969
Epoch 2/22
31/31 [==============================] - 167s 5s/step - loss: 0.4738 - acc: 0.8237 - val_loss: 0.3943 - val_acc: 0.8719
Epoch 3/22
31/31 [==============================] - 166s 5s/step - loss: 0.4006 - acc: 0.8487 - val_loss: 0.3665 - val_acc: 0.8500
Epoch 4/22
31/31 [==============================] - 166s 5s/step - loss: 0.3203 - acc: 0.8930 - val_loss: 0.2979 - val_acc: 0.8854
Epoch 5/22
31/31 [==============================] - 166s 5s/step - loss: 0.2848 - acc: 0.8966 - val_loss: 0.2752 - val_acc: 0.8927
Epoch 6/22
31/31 [==============================] - 166s 5s/step - loss: 0.2582 - acc: 0.9079 - val_loss: 0.2459 - val_acc: 0.9104
Epoch 7/22
31/31 [==============================] - 167s 5s/step - loss: 0.2698 - acc: 0.8956 - val_loss: 0.2359 - val_acc: 0.9125
Epoch 8/22
31/31 [==============================] - 167s 5s/step - loss: 0.2320 - acc: 0.9108 - val_loss: 0.2445 - val_acc: 0.9010
Epoch 9/22
31/31 [==============================] - 166s 5s/step - loss: 0.2460 - acc: 0.9084 - val_loss: 0.2183 - val_acc: 0.9146
Epoch 10/22
31/31 [==============================] - 166s 5s/step - loss: 0.1846 - acc: 0.9353 - val_loss: 0.2485 - val_acc: 0.8906
Epoch 11/22
31/31 [==============================] - 166s 5s/step - loss: 0.1846 - acc: 0.9352 - val_loss: 0.2215 - val_acc: 0.8906
Epoch 12/22
31/31 [==============================] - 166s 5s/step - loss: 0.1846 - acc: 0.9353 - val_loss: 0.2485 - val_acc: 0.8906

训练到Epoch 12正探究训练的变化,调整学习率再接着上面继续训练
对网络微调,最后三层进行解冻

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

前面训练了12个epoch,在训练10个epoch

initial_epochs = 12
fine_tune_epochs = 10
total_epochs = initial_epochs + fine_tune_epochs

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

model.compile(loss='binary_crossentropy', optimizer = tf.keras.optimizers.Adam(lr=0.005/10), metrics = ['acc'])
history = model.fit(train_image_dataset, steps_per_epoch=train_count//BATCHSIZE, epochs=total_epochs, initial_epoch=initial_epochs, validation_data=test_image_dataset, validation_steps=test_count//BATCHSIZE)
Epoch 13/22
2021-04-29 15:48:18.064376: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:127] None of the MLIR optimization passes are enabled (registered 2)
2021-04-29 15:48:18.089134: I tensorflow/core/platform/profile_utils/cpu_utils.cc:112] CPU Frequency: 2200000000 Hz
31/31 [==============================] - 167s 5s/step - loss: 0.5921 - acc: 0.6774 - val_loss: 0.4773 - val_acc: 0.8083
Epoch 14/22
31/31 [==============================] - 166s 5s/step - loss: 0.4690 - acc: 0.8059 - val_loss: 0.3827 - val_acc: 0.8583
Epoch 15/22
31/31 [==============================] - 170s 6s/step - loss: 0.3718 - acc: 0.8638 - val_loss: 0.3203 - val_acc: 0.8813
Epoch 16/22
31/31 [==============================] - 171s 6s/step - loss: 0.3022 - acc: 0.8843 - val_loss: 0.3238 - val_acc: 0.8615
Epoch 17/22
31/31 [==============================] - 171s 6s/step - loss: 0.2840 - acc: 0.8904 - val_loss: 0.2703 - val_acc: 0.9031
Epoch 18/22
31/31 [==============================] - 172s 6s/step - loss: 0.2385 - acc: 0.9247 - val_loss: 0.2568 - val_acc: 0.9000
Epoch 19/22
31/31 [==============================] - 172s 6s/step - loss: 0.2533 - acc: 0.9037 - val_loss: 0.2431 - val_acc: 0.9104
Epoch 20/22
31/31 [==============================] - 172s 6s/step - loss: 0.2168 - acc: 0.9187 - val_loss: 0.3080 - val_acc: 0.8552
Epoch 21/22
31/31 [==============================] - 172s 6s/step - loss: 0.2370 - acc: 0.9059 - val_loss: 0.2200 - val_acc: 0.9208
Epoch 22/22
31/31 [==============================] - 167s 5s/step - loss: 0.2030 - acc: 0.9307 - val_loss: 0.2123 - val_acc: 0.9146
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值