ResNet在计算机视觉中的应用

本文介绍了ResNet在计算机视觉中的应用,通过解决深度网络中的退化问题,提高图像分类的准确性。通过对比传统的卷积神经网络,展示了ResNet的残差学习框架如何通过跳跃连接优化优化过程,减少了梯度消失问题。使用辛普森字符数据集进行实验,ResNet在测试集上的准确率显著高于基准模型。结论强调了ResNet在深度学习中的优势及其潜力。
摘要由CSDN通过智能技术生成

1.介绍

深度卷积神经网络极大地改变了图像分类的研究前景[1]。

随着更多层的添加,模型的表达能力增强;它能够学习更复杂的表示法。在某种程度上,网络的深度与模型的准确性之间似乎存在正相关关系。

另一方面,随着网络的深入,逐渐消失/爆炸的梯度问题变得更加严重。规范化初始化和规范化层最终解决了这个问题,深度网络开始收敛。

然而,与随后的实验之前的直觉推理不同,随着深度的增加,模型的准确性开始饱和,然后实际上迅速下降。这不是由于过拟合,而是由于用于优化模型的当前解算器的局限性[2]。

引入ResNet解决了退化问题[2]。它引入了一种系统的方法来使用跳跃连接,即跳过一个或多个层的连接。这些短连接只是执行标识映射,它们的输出被添加到堆叠层的输出中(这不会增加额外的参数或计算复杂性)。其背后的想法是,如果多个非线性层可以渐近逼近复杂函数(仍在理论上研究,但是深入学习的基础),那么残差函数也可能发生同样的情况。其优点是,同时简化了求解器的工作。在[3]中研究了其他类型的连接,如缩放、1x1卷积的跳跃连接。

我们的任务是对一系列带标签的图像进行分类。

我们想比较两种不同方法的准确性;第一种是经典的卷积神经网络,第二种是残差网络。我们的目标是展示残差网络的力量,即使在不太深的网络中。

这是一个很好的方法来帮助优化过程,同时解决退化问题。我们对残差网络进行了经验测试,发现它更容易过拟合。为了解决这一问题,我们采用数据扩充策略对数据集进行了综合扩充。

我们使用辛普森字符数据集[4]。我们只过滤数据集以包含包含100多个图像的类(字符)。在对训练、验证和测试数据集进行分割后,数据集的结果大小如下:12411个用于训练的图像、3091个用于验证的图像和950个用于测试的图像。

代码和数据也像往常一样在我的GitHub上可用。

https://github.com/luisroque/deep-learning-articles

2.数据预处理

我们创建生成器将数据提供给模型。我们还应用了一个转换来规范化数据,在训练数据集和验证数据集之间分割数据,并定义32的批大小(请参见[5],以便更好地理解预处理和生成器)。

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Layer, BatchNormalization, Conv2D, Dense, Flatten, Add, Dropout, BatchNormalization
import numpy as np
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
from tensorflow.keras import Input, layers
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
import time

directory_train = "./simpsons_data_split/train/"
directory_test = "./simpsons_data_split/test/"

def get_ImageDataGenerator(validation_split=None):
    image_generator = ImageDataGenerator(rescale=(1/255.),
                                         validation_split=validation_split)
    return image_generator

image_gen_train = get_ImageDataGenerator(validation_split=0.2)

def get_generator(image_data_generator, directory, train_valid=None, seed=None):
    train_generator = image_data_generator.flow_from_directory(directory, 
                                                               batch_size=32, 
                                                                 class_mode='categorical', 
                                                               target_size=(128,128), 
                                                               subset=train_valid, 
                                                               seed=seed)    
    return train_generator

train_generator = get_generator(image_gen_train, directory_train, train_valid='training', seed=1)
validation_generator = get_generator(image_gen_train, directory_train, train_valid='validation')

Found 12411 images belonging to 19 classes.
Found 3091 images belonging to 19 classes.

我们还创建了一个增强数据集,通过应用一组几何和光度变换来减少过拟合的可能性。

几何变换改变图像的几何结构,使CNN在位置和方向上保持不变。光度变换通过调整图像的颜色通道,使CNN对颜色和照明的变化保持不变。

def get_ImageDataGenerator_augmented(validation_split=None):
    image_generator = ImageDataGenerator(rescale=(1/255.),
                                        rotation_range=40,
                                        width_shift_range=0.2,
                                        height_shift_range=0.2,
                                        shear_range=0.2,
                                        zoom_range=0.1,
                                        brightness_range=[0.8,1.2],
                                        horizontal_flip=True,
                                        validation_split=validation_split)
    return image_generator
    
image_gen_train_aug = get_ImageDataGenerator_augmented(validation_split=0.2)
train_generator_aug = get_generator(image_gen_train_aug, directory_train, train_valid='training', seed=1)
validation_generator_aug = get_generator(image_gen_train_aug, directory_train, train_valid='validation')

Found 12411 images belonging to 19 classes.
Found 3091 images belonging to 19 classes.

我们可以遍历生成器,得到一组大小等于上面定义的批量大小的图像。

target_labels = next(os.walk(directory_train))[1]

target_labels.sort()

batch = next(train_generator)
batch_images = np.array(batch[0])
batch_labels = np.array(batch[1])

target_labels = np.asarray(target_labels)

plt.figure(figsize=(15,10))
for n, i in enumerate(np.arange(10)):
    ax = plt.subplot(3,5,n+1)
    plt.imshow(batch_images[i])
    plt.title(target_labels[np.where(batch_labels[i]==1)[0][0]])
    plt.axis('off')

44bfd856aa3c7744ae4457e0216f60a7.png

3.基准模型

我们定义了一个简单的CNN作为基准模型。

它使用2D卷积层(对图像执行空间卷积)和最大池操作。紧随其后的是具有128个单元和ReLU激活功能的Dense层,以及Dropout率为0.5的Dropout层。最后,最后一层产生我们网络的输出,该网络的单元数等于目标标签的数量,并使用softmax激活函数。

该模型使用Adam优化器编译,具有默认设置和分类交叉熵损失。

def get_benchmark_model(input_shape):
    x = Input(shape=input_shape)
    h = Conv2D(32, padding='same', kernel_size=(3,3), activation='relu')(x)
    h = Conv2D(32, padding='same', kernel_size=(3,3), activation='relu')(x)
    h = MaxPooling2D(pool_size=(2,2))(h)
    h = Conv2D(64, padding='same', kernel_size=(3,3), activation='relu')(h)
    h = Conv2D(64, padding='same'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值