神经网络学习小记录20——ResNet50模型的复现详解_resnet50复现-程序员宅基地

技术标签: 神经网络学习小记录  复现  神经网络  详解  ResNet  

神经网络学习小记录20——ResNet50模型的复现详解

学习前言

最近看yolo3里面讲到了残差网络,对这个网络结构很感兴趣,于是了解到这个网络结构最初的使用是在ResNet网络里。
在这里插入图片描述

什么是残差网络

Residual net(残差网络):
将靠前若干层的某一层数据输出直接跳过多层引入到后面数据层的输入部分。
意味着后面的特征层的内容会有一部分由其前面的某一层线性贡献。
其结构如下:
在这里插入图片描述
深度残差网络的设计是为了克服由于网络深度加深而产生的学习效率变低与准确率无法有效提升的问题。

什么是ResNet50模型

ResNet50有两个基本的块,分别名为Conv Block和Identity Block,其中Conv Block输入和输出的维度是不一样的,所以不能连续串联,它的作用是改变网络的维度;Identity Block输入维度和输出维度相同,可以串联,用于加深网络的。
Conv Block的结构如下:

在这里插入图片描述
Identity Block的结构如下:
在这里插入图片描述
这两个都是残差网络结构。
总的网络结构如下:
在这里插入图片描述
这样看起来可能比较抽象,还有一副很好的我从网上找的图,可以拉到最后面去看哈,放前面太占位置了。

ResNet50网络部分实现代码

#-------------------------------------------------------------#
#   ResNet50的网络部分
#-------------------------------------------------------------#
from __future__ import print_function

import numpy as np
from keras import layers

from keras.layers import Input
from keras.layers import Dense,Conv2D,MaxPooling2D,ZeroPadding2D,AveragePooling2D
from keras.layers import Activation,BatchNormalization,Flatten
from keras.models import Model

from keras.preprocessing import image
import keras.backend as K
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import decode_predictions
from keras.applications.imagenet_utils import preprocess_input


def identity_block(input_tensor, kernel_size, filters, stage, block):

    filters1, filters2, filters3 = filters

    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = Conv2D(filters1, (1, 1), name=conv_name_base + '2a')(input_tensor)
    x = BatchNormalization(name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters2, kernel_size,padding='same', name=conv_name_base + '2b')(x)

    x = BatchNormalization(name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
    x = BatchNormalization(name=bn_name_base + '2c')(x)

    x = layers.add([x, input_tensor])
    x = Activation('relu')(x)
    return x


def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):

    filters1, filters2, filters3 = filters

    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'

    x = Conv2D(filters1, (1, 1), strides=strides,
               name=conv_name_base + '2a')(input_tensor)
    x = BatchNormalization(name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters2, kernel_size, padding='same',
               name=conv_name_base + '2b')(x)
    x = BatchNormalization(name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)

    x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
    x = BatchNormalization(name=bn_name_base + '2c')(x)

    shortcut = Conv2D(filters3, (1, 1), strides=strides,
                      name=conv_name_base + '1')(input_tensor)
    shortcut = BatchNormalization(name=bn_name_base + '1')(shortcut)

    x = layers.add([x, shortcut])
    x = Activation('relu')(x)
    return x


def ResNet50(input_shape=[224,224,3],classes=1000):

    img_input = Input(shape=input_shape)
    x = ZeroPadding2D((3, 3))(img_input)

    x = Conv2D(64, (7, 7), strides=(2, 2), name='conv1')(x)
    x = BatchNormalization(name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2))(x)

    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')

    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')

    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')

    x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')

    x = AveragePooling2D((7, 7), name='avg_pool')(x)

    x = Flatten()(x)
    x = Dense(classes, activation='softmax', name='fc1000')(x)

    model = Model(img_input, x, name='resnet50')

    model.load_weights("resnet50_weights_tf_dim_ordering_tf_kernels.h5")

    return model

图片预测

建立网络后,可以用以下的代码进行预测。

if __name__ == '__main__':
    model = ResNet50()
    model.summary()
    img_path = 'elephant.jpg'
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)

    print('Input image shape:', x.shape)
    preds = model.predict(x)
    print('Predicted:', decode_predictions(preds))

预测所需的已经训练好的ResNet50模型可以在https://github.com/fchollet/deep-learning-models/releases下载。非常方便。
预测结果为:

Predicted: [[('n01871265', 'tusker', 0.41107917), ('n02504458', 'African_elephant', 0.39015812), ('n02504013', 'Indian_elephant', 0.12260196), ('n03000247', 'chain_mail', 0.023176488), ('n02437312', 'Arabian_camel', 0.020982226)]]

ResNet50模型的完整的结构图如下:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44791964/article/details/102790260

智能推荐

某鱼wasm逆向_某鱼 逆向-程序员宅基地

文章浏览阅读1.2k次,点赞18次,收藏15次。斗鱼、wasm、js逆向、web逆向。_某鱼 逆向

sicily1029 Rabbit 中大OJ解题报告-程序员宅基地

文章浏览阅读737次。由于中大的oj需要内网才能进去,就提供不了原始题目了,但是题目的意思就是说,开始有一对成年兔子,一对成年兔子每年能生一对幼兔,幼兔等m个月才成长为成年兔子,问d个月后总共有多少对兔子。输入m d 2 3 3 5 1 100输出 5 9 100题目意思相信大家都能明白,那么解题思路又是怎么样的呢我来大概说一下,先找到兔子增长_中大oj

C程序设计第五版谭浩强 || 第四章习题答案-程序员宅基地

文章浏览阅读1.5k次,点赞40次,收藏34次。【代码】C程序设计第五版谭浩强 || 第四章习题答案

CPO-CNN-LSTM分类预测,【24新算法】冠豪猪算法CPO优化卷积神经网络-长短期记忆网络多特征分类预测-程序员宅基地

文章浏览阅读161次。CPO-CNN-LSTM分类预测,【24新算法】冠豪猪算法CPO优化卷积神经网络-长短期记忆网络多特征分类预测

非Root或Administrator账户下运行Nginx_nginx用什么用户启动-程序员宅基地

文章浏览阅读1.4k次。这样,就可以在CentOS系统中使用普通用户身份来管理和启动Nginx服务了。请注意,对于其他需要管理员权限才能完成的操作(如修改系统文件等),还需要使用sudo命令或者切换到管理员账户进行操作。下载并安装Nginx,保证Nginx可执行文件所在的路径对普通用户具有可读、可执行的权限。安装过程中,在指定 Nginx 配置文件路径时要特别注意,确保可访问并正确填写。启动Nginx服务。是您实际安装Nginx时配置文件存放的路径。_nginx用什么用户启动

【解决】无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]_无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[h-程序员宅基地

文章浏览阅读6.8k次。问题描述:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]在调用<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>时出现异常调用tomcat服务器时,页面出错:原因分析:首先确认导入的jar包是否正确经过多次导包还是老样子,在网上也找了挺多方法,但都不凑效解决方案:方案一:重新导入jar包如果是jar包缺失_无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[h

随便推点

pipenv—不可不知的python包管理利器-程序员宅基地

文章浏览阅读258次。一 前言最近我们的檀神在学习python时提了一个很好的问题,让我觉得有必要把它梳理下分享给更多的学习者。剧情回顾:檀神安装了python3的版本,想在我16年基于python2写的工具的基础上增加功能,但发现工具的一个模块还不支持python3。这就尴尬了,是要重装python2的版本?还是用python3的模块重写工具?不管哪种方式,似乎都挺折腾。其实,这只是python..._launching subshell in virtual environment... windows powershell 版权所有(c)

Oracle列转行函数 Listagg() 语法详解及应用实例_oracle9 listagg-程序员宅基地

文章浏览阅读6w次,点赞12次,收藏65次。工作中用到一段比较复杂的SQL查询脚本,使用了listagg()函数实现了具有多个值的字段的填充(即,列表聚合,list aggregation(我猜的))。说简单点,listagg()函数可以实现多列记录聚合为一条记录,从而实现数据的压缩、致密化(data densification)。以下内容转载自http://dacoolbaby.iteye.com/blog/1698957,SQL脚本做了..._oracle9 listagg

InnoDB在SQL查询中的关键功能和优化策略-程序员宅基地

文章浏览阅读1.9k次,点赞41次,收藏32次。通过上篇文章《MySQL的体系结构与SQL的执行流程》了解了SQL语句的执行流程以及MySQL体系结构中**「连接器」「SQL接口」「解析器」「优化器」「执行器」**的功能以及在整个流程中的作用。不过上篇文章留了个尾巴,在执行器调用存储引擎后,存储引擎内部做了什么事没有进一步说明,本文会对此展开介绍,使得我们对SQL整体的执行流程有更加清晰的认识。先了解下存储引擎是干什么的。

优动漫PAINT-超简单灌木教程-程序员宅基地

文章浏览阅读93次。超简单灌木教程~零基础神马的都能神还原哦!优动漫PAINT下载:http://wm.makeding.com/iclk/?zoneid=18597想要Get到更多有关优动漫的信息包括软件下载,可关注优动漫PAINT中文官网哦!转载于:https://www.cnblogs.com/danzi/p/8527177.html..._优动漫边缘上色

Netty 1-程序员宅基地

文章浏览阅读716次,点赞24次,收藏27次。Channel与BufferJava NIO系统的核心通道(Channel)和缓冲区(Buffer)。通道表示打开到 IO 设备(例如:文件、套接字)的连接。若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理简而言之,通道负责传输,缓冲区负责存储常见的Channel有以下四种,其中FileChannel主要用于文件传输,其余三种用于网络通信Buffer有以下几种,其中使用较多的是ByteBufferByteBuffer。

VS 设置 C# 以下划线 _ 开头命名全局字段_visual studio 命名规则以_开头给-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏5次。VS 设置 C# 以下划线 _ 开头命名全局字段设置方法之前在某位大神的博客有看到这个设置方法,换电脑以后再找那个文章却找不到了,按回忆找到了设置方法,故写出来分享给大家。private readonly SearchResult _searchResult;设置方法以2019企业版为例,找到:工具 - 选项 - 文本编辑器 - C# - 代码样式 - 命名点击“管理命名样式”,然后再点左下角加号,新建一个命名规范,标题可以自己拟定,设置“必填前缀”为“_”,选择“camel 事例名称”,确_visual studio 命名规则以_开头给

推荐文章

热门文章

相关标签