2020中国华录杯·数据湖算法大赛—定向算法赛(吸烟打电话检测)-tensorflow2.3-python3.6-迁移学习

学习一下迁移学习。。。

1.inceptionV3

在这里插入图片描述

"""
python=3.6
tf=2.3.1
"""
import os
import tensorflow as tf
from tensorflow.keras.models import *
from tensorflow.keras.layers import *
from tensorflow.keras.applications import *
from tensorflow.keras.preprocessing.image import *
from tensorflow import keras as keras
import numpy as np
# import cv2
from  PIL import Image
import matplotlib.pyplot as plt

#2.加载数据
train_normal = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\normal"
train_phone = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\calling"
train_smoke = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\smoking"

train_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train"

val_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val"#验证集用01_train_test_splict.py生成
val_normal = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\normal"
val_phone = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\calling"
val_smoke = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\smoking"

test_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\test"#测试集是需要我们预测结果

train_normal_num = len(os.listdir(train_normal))
train_phone_num = len(os.listdir(train_phone))
train_smoke_num = len(os.listdir(train_smoke))

val_normal_num = len(os.listdir(val_normal))
val_phone_num = len(os.listdir(val_phone))
val_smoke_num = len(os.listdir(val_smoke))

train_all = train_normal_num + train_phone_num + train_smoke_num
val_all = val_normal_num + val_phone_num + val_smoke_num

test_num = len(os.listdir(test_dir))

print("train normal number: ", train_normal_num)
print("train phone_num: ", train_phone_num)
print("train_smoke_num: ", train_smoke_num)
print("all train images: ", train_all)

print("val normal number: ", val_normal_num)
print("val phone_num: ", val_phone_num)
print("val_smoke_num: ", val_smoke_num)
print("all val images: ", val_all)

print("all test images: ", test_num)

# 3.设置超参数
batch_size = 512        #显存内存允许的情况下尽量大
epochs = 1000            #有早停技术,尽量大

height = 299
width = 299
num_classes = 3

# 4.数据增强
# 读取训练数据并作数据增强
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    # 给resnet50预处理图像的函数
    preprocessing_function = tf.keras.applications.resnet50.preprocess_input,
    # 图片旋转的角度范围,用来数据增强
    rotation_range = 40,
    # 水平平移
    width_shift_range = 0.2,
    # 高度平移
    height_shift_range = 0.2,
    # 剪切强度
    shear_range = 0.2,
    # 缩放强度
    zoom_range = 0.2,
    # 水平翻转
    horizontal_flip = True,
    # 对图片做处理时需要填充图片,用最近的像素点填充
    fill_mode = "nearest"
)
# 读取训练数据
train_generator = train_datagen.flow_from_directory(
    train_dir,
    # 读取后将图片存什么大小
    target_size = (height, width),
    batch_size = batch_size,
    seed = 7,
    shuffle = True,
    # label的编码格式:这里为one-hot编码
    class_mode = 'categorical')

# 读取验证数据
valid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = tf.keras.applications.resnet50.preprocess_input)
valid_generator = valid_datagen.flow_from_directory(
    val_dir,
    # 读取后将图片存什么大小
    target_size = (height, width),
    batch_size = batch_size,
    seed = 7,
    shuffle = False,
    # label的编码格式:这里为one-hot编码
    class_mode = 'categorical')


#5.搭建模型
imagenet_weight = "./model/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5"
base_model = InceptionV3(input_tensor=Input(shape=(299, 299, 3)), weights=imagenet_weight, include_top=False)
base_model.summary()
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(base_model.input, predictions)

for layer in base_model.layers:
    layer.trainable = False

model.compile(keras.optimizers.SGD(lr=0.001, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy'])


#6.添加callbacks:早停,检查点,tensorboard,训练记录
stop_callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', min_delta=0.0001,
    patience=13
)

# 在文件名中包含 epoch (使用 `str.format`)
checkpoint_path = "saved_model/best_incptionv3.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建一个回调,每 5 个 epochs 保存模型的权重
cp_callback = tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_path,
    verbose=1,
    save_weights_only=False,
    save_best_only=True)
# # 使用 `checkpoint_path` 格式保存权重
# model_new.save_weights(checkpoint_path.format(epoch=0))

logdir = "./model/inceptionv3"
tb_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir), #log_dir将输出的日志保存在所要保存的路径中

log_callback = tf.keras.callbacks.CSVLogger(
    "training_log_inceptionv3", separator=',', append=False
)
callbacks = [stop_callback,cp_callback,*tb_callback,log_callback]#tb_callback是元组,加*展开
# print(type(stop_callback),type(cp_callback),type(tb_callback),type(log_callback))

#7.训练
#数据是generator出来的,所以不能直接用fit
history = model.fit_generator(train_generator,
                              steps_per_epoch = train_all // batch_size,
                               epochs=epochs,
                              validation_data = valid_generator,
                              validation_steps = val_all // batch_size,
                              callbacks=callbacks,
                              verbose=2
                             )
model.save('./saved_model/inceptionV3_model.h5')
print("模型保存成功")

2.resnet50迁移学习

在这里插入图片描述

"""
tf2.3.0
python3.6
"""
# 1.导入包

import numpy as np
import os
import tensorflow as tf

from tensorflow.keras.applications.resnet50 import ResNet50
# # 2.加载数据
train_normal = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\normal"
train_phone = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\calling"
train_smoke = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train\smoking"

train_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\train"

val_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val"#验证集用01_train_test_splict.py生成
val_normal = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\normal"
val_phone = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\calling"
val_smoke = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\val\smoking"

test_dir = r"C:\Users\Administrator\PycharmProjects\pythonProject\01_tf2_somking_calling\data\test"#测试集是需要我们预测结果

train_normal_num = len(os.listdir(train_normal))
train_phone_num = len(os.listdir(train_phone))
train_smoke_num = len(os.listdir(train_smoke))

val_normal_num = len(os.listdir(val_normal))
val_phone_num = len(os.listdir(val_phone))
val_smoke_num = len(os.listdir(val_smoke))

train_all = train_normal_num + train_phone_num + train_smoke_num
val_all = val_normal_num + val_phone_num + val_smoke_num

test_num = len(os.listdir(test_dir))

print("train normal number: ", train_normal_num)
print("train phone_num: ", train_phone_num)
print("train_smoke_num: ", train_smoke_num)
print("all train images: ", train_all)

print("val normal number: ", val_normal_num)
print("val phone_num: ", val_phone_num)
print("val_smoke_num: ", val_smoke_num)
print("all val images: ", val_all)

print("all test images: ", test_num)

# 3.设置超参数
batch_size = 512        #显存内存允许的情况下尽量大
epochs = 500              #有早停技术,尽量大

height = 224
width = 224
num_classes = 3


# 8.数据增强
# 读取训练数据并作数据增强
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    # 给resnet50预处理图像的函数
    preprocessing_function = tf.keras.applications.resnet50.preprocess_input,
    # 图片旋转的角度范围,用来数据增强
    rotation_range = 40,
    # 水平平移
    width_shift_range = 0.2,
    # 高度平移
    height_shift_range = 0.2,
    # 剪切强度
    shear_range = 0.2,
    # 缩放强度
    zoom_range = 0.2,
    # 水平翻转
    horizontal_flip = True,
    # 对图片做处理时需要填充图片,用最近的像素点填充
    fill_mode = "nearest"
)
# 读取训练数据
train_generator = train_datagen.flow_from_directory(
    train_dir,
    # 读取后将图片存什么大小
    target_size = (height, width),
    batch_size = batch_size,
    seed = 7,
    shuffle = True,
    # label的编码格式:这里为one-hot编码
    class_mode = 'categorical')

# 读取验证数据
valid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    preprocessing_function = tf.keras.applications.resnet50.preprocess_input)
valid_generator = valid_datagen.flow_from_directory(
    val_dir,
    # 读取后将图片存什么大小
    target_size = (height, width),
    batch_size = batch_size,
    seed = 7,
    shuffle = False,
    # label的编码格式:这里为one-hot编码
    class_mode = 'categorical')

# 4. 搭建模型
imagenet_weight = "./model/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5"

resnet50_fine_tune = tf.keras.models.Sequential()
# resnet50最后一层有1000类,所以在本例中把最后一层去掉(include_top = False)
# resnet的倒数第二层是一个三维矩阵,所以无法与全连接层连接,故要pooling
# weights = 'imagenet': 下载一个模型,然后在这个模型的基础上进行训练
# weights = 'None':从头开始训练
resnet50_fine_tune.add(ResNet50(include_top = False,
                                pooling = 'avg',
                                weights = imagenet_weight
                                ))
resnet50_fine_tune.add(tf.keras.layers.Dense(num_classes,activation = 'softmax'))
resnet50_fine_tune.layers[0].trainable = False

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)#自定义,便于修改学习率
resnet50_fine_tune.compile(loss="categorical_crossentropy",
             optimizer=optimizer,
             metrics = ["accuracy"])
resnet50_fine_tune.summary()

#添加callbacks:早停,检查点,tensorboard,训练记录
stop_callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', min_delta=0.0001,
    patience=10
)

# 在文件名中包含 epoch (使用 `str.format`)
checkpoint_path = "saved_model/resnet50_best.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建一个回调,每 5 个 epochs 保存模型的权重
cp_callback = tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_path,
    verbose=1,
    save_weights_only=False,
    save_best_only=True)
# # 使用 `checkpoint_path` 格式保存权重
# model_new.save_weights(checkpoint_path.format(epoch=0))

logdir = "./model/resnet50"
tb_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir), #log_dir将输出的日志保存在所要保存的路径中

log_callback = tf.keras.callbacks.CSVLogger(
    "training_log_resnet50", separator=',', append=False
)
callbacks = [stop_callback,cp_callback,*tb_callback,log_callback]#tb_callback是元组,加*展开
# print(type(stop_callback),type(cp_callback),type(tb_callback),type(log_callback))

# 数据是generator出来的,所以不能直接用fit
history = resnet50_fine_tune.fit_generator(train_generator,
                               steps_per_epoch = train_all // batch_size,
                               epochs=epochs,
                              validation_data = valid_generator,
                              validation_steps = val_all // batch_size,
                              callbacks=callbacks,
                              verbose=2
                             )
resnet50_fine_tune.save('./saved_model/resnet50_fine_tune_model.h5')
print("模型保存成功")

3.对比:


 1. 几乎没调参
 2. 效果来看在跑50epoch下,resnet50在线上准确率85%左右,前几十名都在九十几。。。
 3. 图像增强小技巧用的也少,见过其他版本用图像模糊,马赛克增强等技巧效果可能会好些,期待AIers友们的代码,我自己写的太简单了,只是参考tf2官网上的猫狗分类代码;
 4.复赛增加了吸烟&打电话一起的图片,可能目标检测网络会好些

补上数据20210205:

  1. 训练集
  2. 测试集
  3. 验证集
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值