头图

本教程的知识点为:深度学习介绍 1.1 深度学习与机器学习的区别 TensorFlow介绍 2.4 张量 2.4.1 张量(Tensor) 2.4.1.1 张量的类型 TensorFlow介绍 1.2 神经网络基础 1.2.1 Logistic回归 1.2.1.1 Logistic回归 TensorFlow介绍 总结 每日作业 神经网络与tf.keras 1.3 神经网络基础 神经网络与tf.keras 1.3 Tensorflow实现神经网络 1.3.1 TensorFlow keras介绍 1.3.2 案例:实现多层神经网络进行时装分类 神经网络与tf.keras 1.4 深层神经网络 为什么使用深层网络 1.4.1 深层神经网络表示 卷积神经网络 3.1 卷积神经网络(CNN)原理 为什么需要卷积神经网络 原因之一:图像特征数量对神经网络效果压力 卷积神经网络 3.1 卷积神经网络(CNN)原理 为什么需要卷积神经网络 原因之一:图像特征数量对神经网络效果压力 卷积神经网络 2.2案例:CIFAR100类别分类 2.2.1 CIFAR100数据集介绍 2.2.2 API 使用 卷积神经网络 2.4 BN与神经网络调优 2.4.1 神经网络调优 2.4.1.1 调参技巧 卷积神经网络 2.4 经典分类网络结构 2.4.1 LeNet-5解析 2.4.1.1 网络结构 卷积神经网络 2.5 CNN网络实战技巧 2.5.1 迁移学习(Transfer Learning) 2.5.1.1 介绍 卷积神经网络 总结 每日作业 商品物体检测项目介绍 1.1 项目演示 商品物体检测项目介绍 3.4 Fast R-CNN 3.4.1 Fast R-CNN 3.4.1.1 RoI pooling YOLO与SSD 4.3 案例:SSD进行物体检测 4.3.1 案例效果 4.3.2 案例需求 商品检测数据集训练 5.2 标注数据读取与存储 5.2.1 案例:xml读取本地文件存储到pkl 5.2.1.1 解析结构

完整笔记资料代码:https://gitee.com/yinuo112/AI/tree/master/深度学习/嘿马深度学...

感兴趣的小伙伴可以自取哦~


全套教程部分目录:


部分文件图片:

卷积神经网络

2.5 CNN网络实战技巧

学习目标

  • 目标

    • 了解迁移学习以及技巧
  • 应用

我们来看一个个问题如果我们要做一个具体场景的计算机视觉任务,那么从头开始训练一个网络是合适的选择吗?怎么样才能避免浪费过多的计算时间?

2.5.1 迁移学习(Transfer Learning)

2.5.1.1 介绍
  • 定义

    • 迁移学习就是利用数据、任务或模型之间的相似性,将在旧的领域学习过或训练好的模型,应用于新的领域这样的一个过程。
    • 两个任务的输入属于同一性质:要么同是图像、要么同是语音或其他

迁移学习到底在什么情况下使用呢?有两个方面需要我们考虑的

  • 1、当我们有海量的数据资源时,可以不需要迁移学习,机器学习系统很容易从海量数据中学习到一个鲁棒性很强的模型。但通常情况下,我们需要研究的领域可获得的数据极为有限,在少量的训练样本上精度极高,但是泛化效果极差。
  • 2、训练成本,很少去从头开始训练一整个深度卷积网络,从头开始训练一个卷积网络通常需要较长时间且依赖于强大的 GPU 计算资源。
2.5.1.2 方法
  • 最常见的称呼叫做fine tuning,即微调

    • 已训练好的模型,称之为Pre-trained model

通常我们需要加载以训练好的模型,这些可以是一些机构或者公司在ImageNet等类似比赛上进行训练过的模型。TensorFlow同样也提供了相关模型地址:[

下图是其中包含的一些模型:

2.5.1.3 过程

这里我们举一个例子,假设有两个任务A和B,任务 A 拥有海量的数据资源且已训练好,但并不是我们的目标任务,任务 B 是我们的目标任务。下面的网络模型假设是已训练好的1000个类别模型

而B任务假设是某个具体场景如250个类别的食物识别,那么该怎么去做

  • 1、建立自己的网络,在A的基础上,修改最后输出结构,并加载A的模型参数
  • 2、根据数据大小调整

    • 如果B任务数据量小,那么我们可以选择将A模型的所有的层进行freeze(可以通过Tensorflow的trainable=False参数实现),而剩下的输出层部分可以选择调整参数训练
    • 如果B任务的数据量大,那么我们可以将A中一半或者大部分的层进行freeze,而剩下部分的layer可以进行新任务数据基础上的微调

卷积神经网络

3.1 迁移学习案例

学习目标

  • 目标

    • 说明数据增强的作用
  • 应用

    • 应用Keras基于VGG对五种图片类别识别的迁移学习

3.1.1 案例:基于VGG对五种图片类别识别的迁移学习

3.1.1.2 数据集以及迁移需求

数据集是某场景下5个类别图片的识别

我们利用现有的VGG模型去进行微调

3.1.1.3 思路和步骤

  • 读取本地的图片数据以及类别

    • keras.preprocessing.image import ImageDataGenerator提供了读取转换功能
  • 模型的结构修改(添加我们自定的分类层)
  • freeze掉原始VGG模型
  • 编译以及训练和保存模型方式
  • 输入数据进行预测

3.1.1.4 训练的时候读取本地图片以及类别

  • 使用一个ImageDataGenerator图片生成器,定义图片处理以及数据增强相关

    • train_generator = ImageDataGenerator( ​ rescale=1.0 / 255, # 标准化 ​ rotation_range=20, # 旋转 ​ width_shift_range=0.2, ​ height_shift_range=0.2, shear_range=0.2, ​ zoom_range=0.2, horizontal_flip=True)
    • 这个API提供数据处理相关功能,以及数据增强功能
    • train_generator.flow_from_directory(directory=path,# 读取目录 ​ target_size=(h,w),# 目标形状 ​ batch_size=size,# 批数量大小 ​ class_mode='binary', # 目标值格式 ​ shuffle=True)

      • 这个API固定了读取的目录格式,参考:

    data/

        train/
            dogs/
                dog001.jpg
                dog002.jpg
                ...
            cats/
                cat001.jpg
                cat002.jpg
                ...
        validation/
            dogs/
                dog001.jpg
                dog002.jpg
                ...
            cats/
                cat001.jpg
                cat002.jpg
                ...
    ```
    
    
    
    
    
    

    代码:

    首先导入包

    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.python.keras.preprocessing.image import ImageDataGenerator

    我们定义一个迁移学习的类,然后进行相关属性设置和读取代码

    class TransferModel(object):
    
      def __init__(self):
    
          self.model_size = (224, 224)
          self.train_dir = "./data/train/"
          self.test_dir = "./data/test/"
          self.batch_size = 32
    
          self.train_generator = ImageDataGenerator(rescale=1.0 / 255)
          self.test_generator = ImageDataGenerator(rescale=1.0 / 255)
    
      def read_img_to_generator(self):
          """
          读取本地固定格式数据
          :return:
          """
          train_gen = self.train_generator.flow_from_directory(directory=self.train_dir,
                                                               target_size=self.model_size,
                                                               batch_size=self.batch_size,
                                                               class_mode='binary',
                                                               shuffle=True)
          test_gen = self.test_generator.flow_from_directory(directory=self.test_dir,
                                                             target_size=self.model_size,
                                                             batch_size=self.batch_size,
                                                             class_mode='binary',
                                                             shuffle=True)
          return train_gen, test_gen

    3.1.1.5 VGG模型的修改添加全连接层-GlobalAveragePooling2D

    对于VGG最后的1000输出结果,我们选择不动,在这基础之上我们添加若干层全连接层。

  • 一个GlobalAveragePooling2D + 两个全连接层

    • 在图像分类任务中,模型经过最后CNN层后的尺寸为[bath_size, img_width, img_height, channels],通常的做法是:接一个flatten layer,将尺寸变为[batch_size, w h channels],再至少接一个FC layer,这样做的最大问题是:模型参数多,且容易过拟合。利用pooling layer来替代最后的FC layer

    解释如下:

    from keras.layers import Dense, Input, Conv2D
    from keras.layers import MaxPooling2D, GlobalAveragePooling2D

x = Input(shape=[8, 8, 2048])

假定最后一层CNN的层输出为(None, 8, 8, 2048)

x = GlobalAveragePooling2D(name='avg_pool')(x) # shape=(?, 2048)

取每一个特征图的平均值作为输出,用以替代全连接层

x = Dense(1000, activation='softmax', name='predictions')(x) # shape=(?, 1000)

100为类别




* 5类图片识别模型修改

我们需要拿到基础VGG模型,并且VGG提供所有层参数训练好的模型和没有全连接层参数的模型notop模型

* notop模型:

   * **是否包含最后的3个全连接层(whether to include the 3 fully-connected layers at the top of the network)。用来做fine-tuning专用,专门开源了这类模型。**


‘weights='imagenet'’,意思是VGG在在ResNet结构预训练的权重

在__init__中添加

self.base_model = VGG16(weights='imagenet', include_top=False)




base_model会有相关属性,模型的输入结构:inputs,模型的输出结构,我们修改需要得到已有VGG的输入和自定义模型的输出构建成一个新的模型。

def refine_vgg_model(self):

    """
    添加尾部全连接层
    :return:
    """
    x = self.base_model.outputs[0]

    x = keras.layers.GlobalAveragePooling2D()(x)
    x = keras.layers.Dense(1024, activation=tf.nn.relu)(x)
    y_predict = keras.layers.Dense(5, activation=tf.nn.softmax)(x)

    model = keras.Model(inputs=self.base_model.inputs, outputs=y_predict)

    return model




  
  
### 3.1.1.6 freeze VGG模型结构
  
  


目的:让VGG结构当中的权重参数不参与训练

* 通过使用每一层的layer.trainable=False

def freeze_vgg_model(self):

    """
    freeze掉VGG的结构
    :return:
    """
    for layer in self.base_model.layers:
        layer.trainable = False




  
  
### 3.1.1.7 编译和训练
  
  


* 编译

同样还是进行编译, 在迁移学习中算法:学习率初始化较小的值,0.001,0.0001,因为已经在已训练好的模型基础之上更新,所以不需要太大学习率去学习

def compile(self, model):

    model.compile(optimizer=keras.optimizers.Adam(),
                  loss=keras.losses.sparse_categorical_crossentropy,
                  metrics=['accuracy'])



* 训练

训练的时候通常有两种格式需要保存,H5和ckpt格式,所以选择保存两者

* ckpt保存:使用checkpint工具,ModelCheckpoint指定相关参数

   * save_weights

def fit(self, model, train_gen, test_gen):

    """
    :param model:
    :param train_gen:
    :param test_gen:
    :return:
    """
    check = ModelCheckpoint('./ckpt/transferModel',
                            monitor='val_loss', # 需要监视的值
                            save_best_only=False,
  

程序员一诺python
16 声望17 粉丝

python技术发烧友 资料收集狂