第45步 深度学习图像识别:Nasnet建模(Tensorflow)

这篇具有很好参考价值的文章主要介绍了第45步 深度学习图像识别:Nasnet建模(Tensorflow)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于WIN10的64位系统演示

一、写在前面

(1)Nasnet

NASNet是由Google Brain团队在2017年提出的一种神经网络架构搜索(Neural Architecture Search,简称NAS)的结果。NAS是一种用于自动化设计深度学习模型的技术。在NAS中,机器学习算法通过搜索和优化一系列可能的神经网络架构,然后挑选出性能最好的那一个。

NASNet的全称是"Neural Architecture Search Network",是一种基于卷积神经网络(Convolutional Neural Network,CNN)的模型。它主要包括两种重复的模块,分别称为Normal Cell和Reduction Cell。Normal Cell用于保持特征图的尺寸不变,而Reduction Cell则用于减半特征图的尺寸。

需要注意的是,NASNet的训练过程非常耗时耗力。虽然在许多任务上表现出色,但其高昂的计算成本使得这种方法并不适合所有的应用场景。为了解决这个问题,Google团队还开发了一种轻量级的NASNet版本,称为NASNet-Mobile,适用于移动设备和其他计算资源有限的环境。

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

(2)Nasnet的预训练版本

Keras有Nasnet的预训练模型,包括NASNet-Mobile和NASNet-Large,省事:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 

由于我的显卡不行,这里我就测试NASNet-Mobile版本了。

二、Nasnet迁移学习代码实战

我们继续胸片的数据集:肺结核病人和健康人的胸片的识别。其中,肺结核病人700张,健康人900张,分别存入单独的文件夹中。

(a)导入包

from tensorflow import keras
import tensorflow as tf
from tensorflow.python.keras.layers import Dense, Flatten, Conv2D, MaxPool2D, Dropout, Activation, Reshape, Softmax, GlobalAveragePooling2D
from tensorflow.python.keras.layers.convolutional import Convolution2D, MaxPooling2D
from tensorflow.python.keras import Sequential
from tensorflow.python.keras import Model
from tensorflow.python.keras.optimizers import adam_v2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator, image_dataset_from_directory
from tensorflow.python.keras.layers.preprocessing.image_preprocessing import RandomFlip, RandomRotation, RandomContrast, RandomZoom, RandomTranslation
import os,PIL,pathlib
import warnings
#设置GPU
gpus = tf.config.list_physical_devices("GPU")

if gpus:
    gpu0 = gpus[0] #如果有多个GPU,仅使用第0个GPU
    tf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用
    tf.config.set_visible_devices([gpu0],"GPU")
    
warnings.filterwarnings("ignore")             #忽略警告信息
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    # 用来正常显示负号

(b)导入数据集

#1.导入数据
data_dir = "./cat_dog"
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*')))
print("图片总数为:",image_count)

batch_size = 32
img_height = 224
img_width  = 224

train_ds = image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

val_ds = image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

class_names = train_ds.class_names
print(class_names)
print(train_ds)


#2.检查数据
for image_batch, labels_batch in train_ds:
    print(image_batch.shape)
    print(labels_batch.shape)
    break

#3.配置数据
AUTOTUNE = tf.data.AUTOTUNE

def train_preprocessing(image,label):
    return (image/255.0,label)

train_ds = (
    train_ds.cache()
    .shuffle(800)
    .map(train_preprocessing)
    .prefetch(buffer_size=AUTOTUNE)
)

val_ds = (
    val_ds.cache()
.map(train_preprocessing)
    .prefetch(buffer_size=AUTOTUNE)
)

#4. 数据可视化
plt.figure(figsize=(10, 8))  
plt.suptitle("数据展示")

class_names = ["Dog","Cat"]

for images, labels in train_ds.take(1):
    for i in range(15):
        plt.subplot(4, 5, i + 1)
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(images[i])
        plt.xlabel(class_names[labels[i]-1])

plt.show()

这里注意,NASNetMobile模型的默认输入尺寸是224x224。改成其他的,会直接报错:

ValueError: Dimensions must be equal, but are 12 and 13 for '{{node NASNet/normal_add_1_0/add}} = AddV2[T=DT_FLOAT](NASNet/separable_conv_2_bn_normal_left1_0/FusedBatchNormV3, NASNet/separable_conv_2_bn_normal_right1_0/FusedBatchNormV3)' with input shapes: [?,12,12,44], [?,13,13,44].

(c)数据增强

data_augmentation = Sequential([
  RandomFlip("horizontal_and_vertical"),
  RandomRotation(0.2),
  RandomContrast(1.0),
  RandomZoom(0.5,0.2),
  RandomTranslation(0.3,0.5),
])

def prepare(ds):
    ds = ds.map(lambda x, y: (data_augmentation(x, training=True), y), num_parallel_calls=AUTOTUNE)
    return ds
train_ds = prepare(train_ds)

(d)导入Nasnet

#获取预训练模型对输入的预处理方法
from tensorflow.python.keras.applications import nasnet
from tensorflow.python.keras import Input
IMG_SIZE = (img_height, img_width, 3)
base_model = nasnet.NASNetMobile(include_top=False, #是否包含顶层的全连接层
                                    weights='imagenet')

inputs = Input(shape=IMG_SIZE)
#模型
x = base_model(inputs, training=False) #参数不变化
#全局池化
x = GlobalAveragePooling2D()(x)
#BatchNormalization
x = BatchNormalization()(x)
#Dropout
x = Dropout(0.8)(x)
#Dense
x = Dense(128, kernel_regularizer=regularizers.l2(0.3))(x)  # 全连接层减少到128,添加 L2 正则化
#BatchNormalization
x = BatchNormalization()(x)
#激活函数
x = Activation('relu')(x)
#输出层
outputs = Dense(2, kernel_regularizer=regularizers.l2(0.3))(x)  # 添加 L2 正则化
#BatchNormalization
outputs = BatchNormalization()(outputs)
#激活函数
outputs = Activation('sigmoid')(outputs)
#整体封装
model = Model(inputs, outputs)
#打印模型结构
print(model.summary())

然后打印出模型的结构:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 (e)编译模型

#定义优化器
from tensorflow.python.keras.optimizers import adam_v2, rmsprop_v2
#from tensorflow.python.keras.optimizer_v2.gradient_descent import SGD
optimizer = adam_v2.Adam()
#optimizer = SGD(learning_rate=0.001)
#optimizer = rmsprop_v2.RMSprop()
#编译模型
model.compile(optimizer=optimizer,
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

#训练模型
from tensorflow.python.keras.callbacks import ModelCheckpoint, Callback, EarlyStopping, ReduceLROnPlateau, LearningRateScheduler

NO_EPOCHS = 100
PATIENCE  = 10
VERBOSE   = 1

# 设置动态学习率
annealer = LearningRateScheduler(lambda x: 1e-5 * 0.99 ** (x+NO_EPOCHS))

# 设置早停
earlystopper = EarlyStopping(monitor='loss', patience=PATIENCE, verbose=VERBOSE)

# 
checkpointer = ModelCheckpoint('mtb_jet_best_model_ResNet50.h5',
                                monitor='val_accuracy',
                                verbose=VERBOSE,
                                save_best_only=True,
                                save_weights_only=True)

train_model  = model.fit(train_ds,
                  epochs=NO_EPOCHS,
                  verbose=1,
                  validation_data=val_ds,
                  callbacks=[earlystopper, checkpointer, annealer])

#保存模型
model.save('mtb_jet_best_model_ResNet50.h5')
print("The trained model has been saved.")

模型训练速度也比较慢,一个迭代需要48s。然而,准确率波动比较比较小:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

(f)Accuracy和Loss可视化

import matplotlib.pyplot as plt

loss = train_model.history['loss']
acc = train_model.history['accuracy']
val_loss = train_model.history['val_loss']
val_acc = train_model.history['val_accuracy']
epoch = range(1, len(loss)+1)

fig, ax = plt.subplots(1, 2, figsize=(10,4))
ax[0].plot(epoch, loss, label='Train loss')
ax[0].plot(epoch, val_loss, label='Validation loss')
ax[0].set_xlabel('Epochs')
ax[0].set_ylabel('Loss')
ax[0].legend()
ax[1].plot(epoch, acc, label='Train acc')
ax[1].plot(epoch, val_acc, label='Validation acc')
ax[1].set_xlabel('Epochs')
ax[1].set_ylabel('Accuracy')
ax[1].legend()
plt.show()

通过这个图,观察模型训练情况:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 蓝色为训练集,橙色为验证集。可以看到loss还是总体呈现下降趋势,验证集的loss几乎没有波动,跟训练集完全重合。准确度曲线,验证集的波动也是比较小,跟训练集差不多。

(g)混淆矩阵可视化以及模型参数

import numpy as np
import matplotlib.pyplot as plt
from tensorflow.python.keras.models import load_model
from matplotlib.pyplot import imshow
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import pandas as pd
import math
# 定义一个绘制混淆矩阵图的函数
def plot_cm(labels, predictions):
    
    # 生成混淆矩阵
    conf_numpy = confusion_matrix(labels, predictions)
    # 将矩阵转化为 DataFrame
    conf_df = pd.DataFrame(conf_numpy, index=class_names ,columns=class_names)  
    
    plt.figure(figsize=(8,7))
    
    sns.heatmap(conf_df, annot=True, fmt="d", cmap="BuPu")
    
    plt.title('混淆矩阵',fontsize=15)
    plt.ylabel('真实值',fontsize=14)
    plt.xlabel('预测值',fontsize=14)

val_pre   = []
val_label = []

for images, labels in val_ds:#这里可以取部分验证数据(.take(1))生成混淆矩阵
    for image, label in zip(images, labels):
        # 需要给图片增加一个维度
        img_array = tf.expand_dims(image, 0) 
        # 使用模型预测图片中的人物
        prediction = model.predict(img_array)
        val_pre.append(np.argmax(prediction))
        val_label.append(label)

plot_cm(val_label, val_pre)

cm_val = confusion_matrix(val_label, val_pre)    
a_val = cm_val[0,0]
b_val = cm_val[0,1]
c_val = cm_val[1,0]
d_val = cm_val[1,1]
acc_val = (a_val+d_val)/(a_val+b_val+c_val+d_val) #准确率:就是被分对的样本数除以所有的样本数
error_rate_val = 1 - acc_val #错误率:与准确率相反,描述被分类器错分的比例
sen_val = d_val/(d_val+c_val) #灵敏度:表示的是所有正例中被分对的比例,衡量了分类器对正例的识别能力
sep_val = a_val/(a_val+b_val) #特异度:表示的是所有负例中被分对的比例,衡量了分类器对负例的识别能力
precision_val = d_val/(b_val+d_val) #精确度:表示被分为正例的示例中实际为正例的比例
F1_val = (2*precision_val*sen_val)/(precision_val+sen_val) #F1值:P和R指标有时候会出现的矛盾的情况,这样就需要综合考虑他们,最常见的方法就是F-Measure(又称为F-Score)
MCC_val = (d_val*a_val-b_val*c_val) / (math.sqrt((d_val+b_val)*(d_val+c_val)*(a_val+b_val)*(a_val+c_val))) #马修斯相关系数(Matthews correlation coefficient):当两个类别具有非常不同的大小时,可以使用MCC
print("验证集的灵敏度为:",sen_val, 
      "验证集的特异度为:",sep_val,
      "验证集的准确率为:",acc_val, 
      "验证集的错误率为:",error_rate_val,
      "验证集的精确度为:",precision_val, 
      "验证集的F1为:",F1_val,
      "验证集的MCC为:",MCC_val)
    
train_pre   = []
train_label = []
for images, labels in train_ds:#这里可以取部分验证数据(.take(1))生成混淆矩阵
    for image, label in zip(images, labels):
        # 需要给图片增加一个维度
        img_array = tf.expand_dims(image, 0)
        # 使用模型预测图片中的人物
        prediction = model.predict(img_array)

        train_pre.append(np.argmax(prediction))
        train_label.append(label)
        
plot_cm(train_label, train_pre)

cm_train = confusion_matrix(train_label, train_pre)  
a_train = cm_train[0,0]
b_train = cm_train[0,1]
c_train = cm_train[1,0]
d_train = cm_train[1,1]
acc_train = (a_train+d_train)/(a_train+b_train+c_train+d_train)
error_rate_train = 1 - acc_train
sen_train = d_train/(d_train+c_train)
sep_train = a_train/(a_train+b_train)
precision_train = d_train/(b_train+d_train)
F1_train = (2*precision_train*sen_train)/(precision_train+sen_train)
MCC_train = (d_train*a_train-b_train*c_train) / (math.sqrt((d_train+b_train)*(d_train+c_train)*(a_train+b_train)*(a_train+c_train))) 
print("训练集的灵敏度为:",sen_train, 
      "训练集的特异度为:",sep_train,
      "训练集的准确率为:",acc_train, 
      "训练集的错误率为:",error_rate_train,
      "训练集的精确度为:",precision_train, 
      "训练集的F1为:",F1_train,
      "训练集的MCC为:",MCC_train)

效果好不错,就是验证集的灵敏度还没到0.8,可以通过调整阈值来改善:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 (g)AUC曲线绘制

from sklearn import metrics
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.python.keras.models import load_model
from matplotlib.pyplot import imshow
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import pandas as pd
import math

def plot_roc(name, labels, predictions, **kwargs):
    fp, tp, _ = metrics.roc_curve(labels, predictions)

    plt.plot(fp, tp, label=name, linewidth=2, **kwargs)
    plt.plot([0, 1], [0, 1], color='orange', linestyle='--')
    plt.xlabel('False positives rate')
    plt.ylabel('True positives rate')
    ax = plt.gca()
    ax.set_aspect('equal')


val_pre_auc   = []
val_label_auc = []

for images, labels in val_ds:
    for image, label in zip(images, labels):      
        img_array = tf.expand_dims(image, 0) 
        prediction_auc = model.predict(img_array)
        val_pre_auc.append((prediction_auc)[:,1])
        val_label_auc.append(label)
auc_score_val = metrics.roc_auc_score(val_label_auc, val_pre_auc)


train_pre_auc   = []
train_label_auc = []

for images, labels in train_ds:
    for image, label in zip(images, labels):
        img_array_train = tf.expand_dims(image, 0) 
        prediction_auc = model.predict(img_array_train)
        train_pre_auc.append((prediction_auc)[:,1])#输出概率而不是标签!
        train_label_auc.append(label)
auc_score_train = metrics.roc_auc_score(train_label_auc, train_pre_auc)

plot_roc('validation AUC: {0:.4f}'.format(auc_score_val), val_label_auc , val_pre_auc , color="red", linestyle='--')
plot_roc('training AUC: {0:.4f}'.format(auc_score_train), train_label_auc, train_pre_auc, color="blue", linestyle='--')
plt.legend(loc='lower right')
#plt.savefig("roc.pdf", dpi=300,format="pdf")

print("训练集的AUC值为:",auc_score_train, "验证集的AUC值为:",auc_score_val)

ROC曲线如下:

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 很完美的ROC曲线!

三、调整过程

几乎没有什么调整,Nasnet在这个数据集上的表现堪称完美,唯一的缺点就是训练的比较慢罢了。

四、Nasnet、ResNet50、InceptionResnetV2、Mobilenet、Efficientnet、DenseNet201、Inception V3和VGG19的对比

第45步 深度学习图像识别:Nasnet建模(Tensorflow),《100 Steps to Get ML》—JET学习笔记,深度学习,tensorflow,人工智能,图像识别

 

五、数据

链接:https://pan.baidu.com/s/15vSVhz1rQBtqNkNp2GQyVw?pwd=x3jf

提取码:x3jf 文章来源地址https://www.toymoban.com/news/detail-517615.html

到了这里,关于第45步 深度学习图像识别:Nasnet建模(Tensorflow)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第59步 深度学习图像识别:误判病例分析(TensorFlow)

    一、写在前面 本期内容对等于机器学习二分类系列的误判病例分析(传送门)。既然前面的数据可以这么分析,那么图形识别自然也可以。 本期以mobilenet_v2模型为例,因为它建模速度快。 同样,基于GPT-4辅助编程,后续会分享改写过程。 二、误判病例分析实战 继续使用胸片

    2024年02月11日
    浏览(34)
  • 第56步 深度学习图像识别:CNN梯度权重类激活映射(TensorFlow)

    一、写在前面 类激活映射(Class Activation Mapping,CAM)和梯度权重类激活映射(Gradient-weighted Class Activation Mapping,Grad-CAM) 是两种可视化深度学习模型决策过程的技术。他们都是为了理解模型的决策过程,特别是对于图像分类任务,它们可以生成一种热力图,这种图可以突出显

    2024年02月13日
    浏览(52)
  • 第62步 深度学习图像识别:多分类建模(Pytorch)

    一、写在前面 上期我们基于TensorFlow环境做了图像识别的多分类任务建模。 本期以健康组、肺结核组、COVID-19组、细菌性(病毒性)肺炎组为数据集,基于Pytorch环境,构建SqueezeNet多分类模型,因为它建模速度快。 同样,基于GPT-4辅助编程,这次改写过程就不展示了。 二、多

    2024年02月11日
    浏览(40)
  • 第55步 深度学习图像识别:CNN特征层和卷积核可视化(TensorFlow)

    一、写在前面 (1)CNN可视化 在理解和解释卷积神经网络(CNN)的行为方面,可视化工具起着重要的作用。以下是一些可以用于可视化的内容: (a)激活映射(Activation maps): 可以显示模型在训练过程中的激活情况,这可以帮助我们理解每一层(或每个过滤器)在识别图像

    2024年02月14日
    浏览(82)
  • 第53步 深度学习图像识别:Bottleneck Transformer建模(Pytorch)

    一、写在前面 (1)Bottleneck Transformer \\\"Bottleneck Transformer\\\"(简称 \\\"BotNet\\\")是一种深度学习模型,在2021年由Google的研究人员在论文\\\"Bottleneck Transformers for Visual Recognition\\\"中提出。 BotNet的核心思想是 将Transformer模型的自注意力机制(Self-Attention Mechanism)引入到了ResNet模型的瓶颈结构

    2024年02月16日
    浏览(40)
  • 第64步 深度学习图像识别:多分类建模误判病例分析(Pytorch)

    一、写在前面 上期我们基于TensorFlow环境介绍了多分类建模的误判病例分析。 本期以健康组、肺结核组、COVID-19组、细菌性(病毒性)肺炎组为数据集,基于Pytorch环境,构建SqueezeNet多分类模型,分析误判病例,因为它建模速度快。 同样,基于GPT-4辅助编程。 二、误判病例分

    2024年02月10日
    浏览(44)
  • 第54步 深度学习图像识别:MLP-Mixer建模(Pytorch)

    一、写在前面 (1)MLP-Mixer MLP-Mixer(Multilayer Perceptron Mixer)是Google在2021年提出的 一种 新型的 视觉模型结构 。它的主要特点是 完全使用 多层感知机(MLP)来处理图像, 而不是使用常见的卷积(Convolution)或者自注意力(Self-Attention)机制。 MLP-Mixer的结构主要包括两种类型的

    2024年02月16日
    浏览(36)
  • 基于tensorflow深度学习的猫狗分类识别

      🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 实验背景 实验目的 实验环境 实验过程 1.加载数据 2.数据预处理 3.构建模型 4.训练模

    2024年02月10日
    浏览(47)
  • 大数据深度学习:基于Tensorflow深度学习卷积神经网络CNN算法垃圾分类识别系统

    随着社会的发展和城市化进程的加速,垃圾分类已经成为了环境保护和可持续发展的重要课题。然而,传统的垃圾分类方法通常依赖于人工识别,效率低下且易出错。因此,本项目旨在利用大数据和深度学习技术,构建一个基于 TensorFlow 深度学习的神经网络 CNN(Convolutional

    2024年04月14日
    浏览(108)
  • 深度学习实战:基于TensorFlow与OpenCV的手语识别系统

    本期内容:基于TensorFlow与OpenCV的手语识别系统 实验环境: python(3.11.4) tensorflow(2.13.0) cv2(4.8.0) 下载地址:https://download.csdn.net/download/m0_68111267/88518189 这些是Python中的标准库及第三方库及其相关的模块。 具体来说,这个代码导入了以下库: Pandas:数据分析和数据处理库。 NumP

    2024年02月06日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包