tensorflow2.0使用VGG16预训练模型实现猫狗数据集2分类

tensorflow2.0使用VGG16预训练模型实现猫狗数据集2分类

准备:

  1. tensorflow2.0.0或以上,最好是GPU版本
  2. python3.7或以上环境,推荐使用Anaconda发行版,本站有相关教程
  3. 数据集,这里放出网盘链接:猫狗数据集,提取码:ijtz
  4. VGG16预训练模型:VGG16,提取码:ouac,在下面代码中,直接调用keras内置的,需要从国外网站下载,速度慢, 这里给出网盘文件,下载后放到C盘**.用户/yourPCname/.keras **文件夹下
  5. 看到的小伙伴们有什么问题可以在下方评论,一起交流学习

直接上代码:

'''
2021-3-4, edit by wyf
python3.7, tensorflow2.0.0
'''
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import glob
import os
import datetime
train_image_path = glob.glob('C:/Users/wyf1998/PycharmProjects/tf20/datasets/dc_2000/train/*/*.jpg')#猫狗数据集存放路径
test_image_path = glob.glob('C:/Users/wyf1998/PycharmProjects/tf20/datasets/dc_2000/test/*/*.jpg')

train_image_label = [int(p.split('\\')[1] == 'cat') for p in train_image_path]#从文件夹名称获取label名称,并编码,cat为1,dog为0
test_image_label = [int(p.split('\\')[1] == 'cat') for p in test_image_path]


def load_preprocess_image(path, label):
    '''
    :param path: 数据集输入路径
    :param label: 编码后的标签
    :return:
    '''
    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
    return image, label


train_image_ds = tf.data.Dataset.from_tensor_slices((train_image_path, train_image_label))
test_image_ds = tf.data.Dataset.from_tensor_slices((test_image_path, test_image_label))
AUTOTUNE = tf.data.experimental.AUTOTUNE#自动并行,加快加载速度
train_count = len(train_image_path)
test_count = len(test_image_path)
BATCH_SIZE = 28
train_image_ds = train_image_ds.map(load_preprocess_image, num_parallel_calls=AUTOTUNE)
train_image_ds = train_image_ds.shuffle(train_count).batch(BATCH_SIZE)
test_image_ds = test_image_ds.map(load_preprocess_image, num_parallel_calls=AUTOTUNE)
test_image_ds = test_image_ds.batch(BATCH_SIZE)

conv_base = tf.keras.applications.VGG16(weights='imagenet', include_top=False)#加载VGG16预训练模型
'''
下面三行为VGG模型微调,经测试可提高正确率,如不需要微调,则可将conv_base.trainable设置为FALSE,后面三行注释
'''
conv_base.trainable = True
fine_tune_at = -3
for layer in conv_base.layers[:fine_tune_at]:
    layer.trainable = False
model = tf.keras.Sequential()
model.add(conv_base)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.summary()
img_, label_ = next(iter(train_image_ds))
pred_ = model.predict(img_)#此tensorflow版本在训练前,必须要先使用model.predict方法,否则后面训练会报错,原因未知
print(pred_.shape)


loss_func = tf.keras.losses.BinaryCrossentropy(from_logits=False)
optimizer = tf.keras.optimizers.Adam()
train_loss = tf.keras.metrics.Mean('train_loss')
train_acc = tf.keras.metrics.BinaryAccuracy('train_acc')

test_loss = tf.keras.metrics.Mean('test_loss')
test_acc = tf.keras.metrics.BinaryAccuracy('test_acc')


def train_step(model, images, labels):
    with tf.GradientTape() as t:
        predict = model(images)
        loss_step = loss_func(labels, predict)
    grads = t.gradient(loss_step, model.trainable_variables)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))
    train_loss(loss_step)
    train_acc(labels, predict)


def test_step(model, images, labels):
    pred = model(images)
    loss_step = loss_func(labels, pred)
    test_loss(loss_step)
    test_acc(labels, pred)


current_time = datetime.datetime.now().strftime("%Y-%m-%d--%H-%M-%S")#tensorboard可视化,需要在根目录创建logs文件夹(手动)
train_log_dir = 'logs/gradient_tape' + current_time + '/train'
test_log_dir = 'logs/gradient_tape' + current_time + '/test'
train_writer = tf.summary.create_file_writer(train_log_dir)
test_writer = tf.summary.create_file_writer(test_log_dir)


def train(epoch_nums):
    for epoch in range(1, epoch_nums):
        for (batch, (images, labels)) in enumerate(train_image_ds):
            train_step(model, images, labels)
            print('epoch{}/{}, train_loss={:.3f}, train_acc={:.3f}'.format(epoch,
                                                                           batch,
                                                                           train_loss.result(),
                                                                           train_acc.result()))
        with train_writer.as_default():
            tf.summary.scalar('train_loss', data=train_loss.result(), step=epoch)
            tf.summary.scalar('train_acc', data=train_acc.result(), step=epoch)

        for (batch, (images, labels)) in enumerate(test_image_ds):
            test_step(model, images, labels)
            print('\repoch{}-val------, test_loss={:.3f}, test_acc={:.3f}'.format(epoch,
                                                                                  test_loss.result(),
                                                                                  test_acc.result()))
        with test_writer.as_default():
            tf.summary.scalar('test_loss', data=test_loss.result(), step=epoch)
            tf.summary.scalar('test_acc', data=test_acc.result(), step=epoch)

        print('Epoch {}, loss= {}, acc= {}, test_loss= {}, test_acc= {}'.format(epoch,
                                                                                train_loss.result(),
                                                                                train_acc.result(),
                                                                                test_loss.result(),
                                                                                test_acc.result()))
        train_loss.reset_states()
        train_acc.reset_states()
        test_loss.reset_states()
        test_acc.reset_states()


if __name__ == '__main__':
    train(epoch_nums=20)

tensorboard使用方法:训练完成之后,进入对应文件的目录(logs文件夹的主目录),在终端输入:tensorboard --logdir=logs,按enter键会得到一个网站,复制到浏览器打开即可
在这里插入图片描述

train_loss和train_acc可视化

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
下面是基于TensorFlow 2.0和VGG16模型添加SENet进行人脸表情识别的示例代码: ```python import tensorflow as tf from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout, GlobalAveragePooling2D, Reshape, Multiply, Add from tensorflow.keras.models import Model from tensorflow.keras.applications.vgg16 import VGG16 # 定义SE模块 def se_module(input_feature, ratio=8): channel = input_feature.shape[-1] gap = GlobalAveragePooling2D()(input_feature) fc1 = Dense(channel // ratio, activation='relu')(gap) fc2 = Dense(channel, activation='sigmoid')(fc1) fc2 = Reshape((1, 1, channel))(fc2) return Multiply()([input_feature, fc2]) # 加载VGG16模型 base_model = VGG16(weights='imagenet', include_top=False, input_shape=(48, 48, 3)) for layer in base_model.layers: layer.trainable = False # 添加SE模块 x = base_model.output x = se_module(x) x = Flatten()(x) x = Dense(128, activation='relu')(x) x = Dropout(0.5)(x) predictions = Dense(7, activation='softmax')(x) model = Model(inputs=base_model.input, outputs=predictions) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(train_generator, epochs=10, validation_data=val_generator) ``` 其中,`se_module`函数定义了SE模块,`ratio`参数用于控制FC层输出通道数与输入通道数的比例,默认为8。 在加载VGG16模型后,通过调用`base_model.output`获取模型输出,然后将输出作为SE模块的输入,并将SE模块输出后的结果通过Flatten层压平,接着添加一个全连接层、一个Dropout层和一个Softmax层,最终构建出完整的SENet-VGG16模型,并使用`model.compile`编译模型,使用`model.fit`训练模型。 需要注意的是,本示例代码中的`train_generator`和`val_generator`需要根据具体情况进行替换,以适配训练数据的输入形式和标签形式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值