28- ResNet模型 (TensorFlow系列) (深度学习)

知识要点

  • ResNet2015年由微软实验室提出, 效果非常好.


一  ResNet模型

1.1 简介

ResNet2015年由微软实验室提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。(啥也别说了,就是NB

网络中的亮点

  • 超深的网络结构(突破1000层)
  • 提出residual模块
  • 使用Batch Normalization加速训练(丢弃dropout)

标准模块:

1.2 residual结构

 

  • 1x1的卷积核 用来降维和升维
  • 注意:主分支与shortcut的输出特征矩阵shape必须相同

1.3 Batch Normalization解析

1.4 图示

二 代码实现

2.1 导包

from tensorflow import keras
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

cpu=tf.config.list_physical_devices("CPU")
tf.config.set_visible_devices(cpu)
print(tf.config.list_logical_devices())

2.2 restnet 建模

class BasicBlock(keras.layers.Layer):
    expansion = 1

    def __init__(self, out_channel, strides=1, downsample=None, **kwargs):
        super().__init__(**kwargs)
        self.conv1 = keras.layers.Conv2D(out_channel,
                                         kernel_size=3,
                                         strides=strides,   # !!!怎么少打的一行
                                         padding='SAME',
                                         use_bias=False)
        self.bn1 = keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)
        self.conv2 = keras.layers.Conv2D(out_channel,
                                         kernel_size=3,
                                         strides=1,
                                         padding='SAME',
                                         use_bias=False)
        self.bn2 = keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)
        self.relu = keras.layers.ReLU()
        self.add = keras.layers.Add()
        self.downsample = downsample

    def call(self, inputs, training=False):
        identity = inputs
        if self.downsample is not None:
            identity = self.downsample(inputs)

        x = self.conv1(inputs)
        x = self.bn1(x, training=training)
        x = self.relu(x)

        x = self.conv2(x)
        x = self.bn2(x, training=training)

        x = self.add([identity, x])
        x = self.relu(x)
        return x


class Bottleneck(keras.layers.Layer):
    expansion = 4
    def __init__(self, out_channel, strides=1, downsample=None, **kwargs):
        super().__init__(**kwargs)
        # 卷积
        self.conv1 = keras.layers.Conv2D(out_channel,
                                         kernel_size=1,  # 卷积核大小
                                         strides=strides,  # 步长
                                         padding='SAME',
                                         use_bias=False)  # 一般在BN层不使用bias
        # BN层
        self.bn1 = keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)

        self.conv2 = keras.layers.Conv2D(out_channel,
                                         kernel_size=3,  # 卷积核大小
                                         strides=strides,  # 步长
                                         padding='SAME',
                                         use_bias=False)  # 一般在BN层不使用bias
        self.bn2 = keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)

        self.conv3 = keras.layers.Conv2D(out_channel * self.expansion,
                                         kernel_size=1,  # 卷积核大小
                                         strides=strides,  # 步长
                                         padding='SAME',
                                         use_bias=False)  # 一般在BN层不使用bias
        self.bn3 = keras.layers.BatchNormalization(momentum=0.9, epsilon=1e-5)

        self.relu = keras.layers.Relu()
        self.add = keras.layers.Add()
        self.downsample = downsample

    # 基础的block
    def call(self, inputs, training=False):
        identity = inputs
        if self.downsample is not None:
            identity = self.downsample(inputs)

        x = self.conv1(inputs)
        x = self.bn1(x, training=training)
        x = self.relu(x)

        x = self.conv2(x)
        x = self.bn2(x, training=training)
        x = self.relu(x)

        x = self.conv3(x)
        x = self.bn3(x, training=training)

        x = self.add([identity, x])
        x = self.relu(x)

        return x

def _make_layer(block, in_channel, channel, block_num, name, strides = 1):
    downsample = None
    if strides != 1 or in_channel != channel * block.expansion:
        downsample = keras.Sequential([
            keras.layers.Conv2D(channel * block.expansion, kernel_size = 1,
                                strides = strides,
                                use_bias = False,
                                name = 'conv1'),
            keras.layers.BatchNormalization(momentum = 0.9,  # BN层, 虚线操作
                                            epsilon = 1e-5,
                                            name = 'BatchNorm')
        ], name = 'shortcut')

    layers_list = []
    layers_list.append(block(channel,
                             downsample = downsample,
                             strides = strides,
                             name = 'unit_1'))
    for index in range(1, block_num):
        layers_list.append(block(channel, name = 'unit_' + str(index + 1)))

    return keras.Sequential(layers_list, name = name)

def _resnet(block, blocks_num, im_width = 224, im_height = 224, num_classes = 1000, include_top = True):
    input_image = keras.layers.Input(shape = (im_height, im_width, 3),
                                     dtype = 'float32')
    x = keras.layers.Conv2D(64, kernel_size = 7,
                            strides = 2,
                            padding = 'SAME',
                            name = 'conv1',
                            use_bias = False)(input_image)
    x = keras.layers.BatchNormalization(momentum = 0.9, epsilon = 1e-5)(x)
    # relu
    x = keras.layers.ReLU()(x)
    x = keras.layers.MaxPool2D(pool_size = 3, strides = 2, padding = 'SAME')(x)

    # 导入循环包
    x = _make_layer(block, x.shape[-1], 64, blocks_num[0], name = 'block1')(x)
    x = _make_layer(block, x.shape[-1], 128, blocks_num[1], name='block2', strides=2)(x)
    x = _make_layer(block, x.shape[-1], 256, blocks_num[2], name='block3', strides= 2)(x)
    x = _make_layer(block, x.shape[-1], 512, blocks_num[3], name='block4', strides= 2)(x)

    if include_top:
        x = keras.layers.GlobalAvgPool2D()(x)  # pool + flatten
        x = keras.layers.Dense(num_classes)(x)
        predict = keras.layers.Softmax()(x)
    else:
        predict = x
    model = keras.models.Model(inputs = input_image, outputs = predict)
    return model

# 生成具体模型
def resnet34(im_width = 224, im_height = 224, num_classes = 1000, include_top = True):
    return _resnet(BasicBlock,
                   [3, 4, 6, 3],
                   im_width,
                   im_height,
                   num_classes,
                   include_top= include_top)

def restnet50(im_width = 224, im_height = 224, num_classes = 1000, include_top = True):
    return _resnet(Bottleneck,
                   [3, 4, 6, 3],
                   im_width,
                   im_height,
                   num_classes,
                   include_top= include_top)

2.3 数据导入并训练

train_dir = './training/training/'
valid_dir = './validation/validation/'
# 图片数据生成

# 整体封装

train_datagen = keras.preprocessing.image.ImageDataGenerator(
    rescale = 1./255,
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True,
    vertical_flip = True,
    fill_mode = 'nearest'
)

height = 224
width = 224
channels = 3
batch_size = 32
num_classes = 10

train_generator = train_datagen.flow_from_directory(train_dir,
                                                    target_size= (height, width),
                                                    batch_size = batch_size,
                                                    shuffle= True,
                                                    seed = 7,
                                                    class_mode= 'categorical')

valid_datagen = keras.preprocessing.image.ImageDataGenerator(rescale = 1./ 255)

valid_generator = valid_datagen.flow_from_directory(valid_dir,
                                                    target_size= (height, width),
                                                    batch_size= batch_size,
                                                    shuffle= True,
                                                    seed = 7,
                                                    class_mode= 'categorical')
print(train_generator.samples)
print(valid_generator.samples)

model34 = resnet34(num_classes=10)
model34.compile(optimizer = 'adam',
                loss = 'categorical_crossentropy',
                metrics = ['acc'])

histroy = model34.fit(train_generator,
                      steps_per_epoch= train_generator.samples // batch_size,
                      epochs = 10,
                      validation_data = valid_generator,
                      validation_steps= valid_generator.samples // batch_size)

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Inception-ResNet是一种深度卷积神经网络模型,它结合了Inception模块和ResNet模块的特点。关于Inception-ResNet的具体实现,提供的引用内容中有三个部分。 引用中给出了一些用到的包和构建二维卷积模块的代码。通过导入相关的包和定义一个函数`conv2d_bn`来实现二维卷积和批归一化等操作。 引用中给出了一个使用Inception-ResNet模块构建深度网络的前向传播过程的代码。通过调用`Stem`、`Inception_ResNet_A`、`Reduction_A`、`Inception_ResNet_B`、`Reduction_B`、`Inception_ResNet_C`等函数来构建网络的不同模块。 引用中提供了一个基于Tensorflow的Inception-ResNet-V2的代码复现,该代码复现了原论文中的网络结构,并适用于Tensorflow 2.12版本。这可以作为学习和参考的资源。 综上所述,如果你想在Tensorflow中实现Inception-ResNet网络,可以参考上述提供的引用内容和代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [基于Tensorflow的Inception-Resnet-V2代码复现](https://blog.csdn.net/weixin_45506188/article/details/130102377)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [TensorFlow实现inception-resnet](https://blog.csdn.net/u014524930/article/details/79330316)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值