功能:用于建立densenet(密集网络)
keras-master\keras\applications\densenet.py
代码注释
# -*- coding: utf-8 -*-
"""DenseNet models for Keras.
基于keras的DenseNet模型
# Reference paper
论文
- [Densely Connected Convolutional Networks]
密集连接卷积网络
(https://arxiv.org/abs/1608.06993) (CVPR 2017 Best Paper Award)
CVPR是IEEE Conference on Computer Vision and Pattern Recognition的缩写,即IEEE国际计算机视觉与模式识别会议。
# Reference implementation
参考实现
- [Torch DenseNets]
(https://github.com/liuzhuang13/DenseNet/blob/master/models/densenet.lua)
- [TensorNets]
(https://github.com/taehoonlee/tensornets/blob/master/tensornets/densenets.py)
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
from .. import backend as K
from ..models import Model
from ..layers import Activation
from ..layers import AveragePooling2D
from ..layers import BatchNormalization
from ..layers import Concatenate
from ..layers import Conv2D
from ..layers import Dense
from ..layers import GlobalAveragePooling2D
from ..layers import GlobalMaxPooling2D
from ..layers import Input
from ..layers import MaxPooling2D
from ..layers import ZeroPadding2D
from ..utils.data_utils import get_file
from ..engine.topology import get_source_inputs
from . import imagenet_utils
from .imagenet_utils import decode_predictions
from .imagenet_utils import _obtain_input_shape
# 权重下载地址
DENSENET121_WEIGHT_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet121_weights_tf_dim_ordering_tf_kernels.h5'
DENSENET121_WEIGHT_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet121_weights_tf_dim_ordering_tf_kernels_notop.h5'
DENSENET169_WEIGHT_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet169_weights_tf_dim_ordering_tf_kernels.h5'
DENSENET169_WEIGHT_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet169_weights_tf_dim_ordering_tf_kernels_notop.h5'
DENSENET201_WEIGHT_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet201_weights_tf_dim_ordering_tf_kernels.h5'
DENSENET201_WEIGHT_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.8/densenet201_weights_tf_dim_ordering_tf_kernels_notop.h5'
def dense_block(x, blocks, name):
"""A dense block.
密集的模块
# Arguments
参数
x: input tensor.
x: 输入参数
blocks: integer, the number of building blocks.
blocks: 整型,生成块的个数。
name: string, block label.
name: 字符串,块的标签
# Returns
返回
output tensor for the block.
为块输出张量
"""
for i in range(blocks):
x = conv_block(x, 32, name=name + '_block' + str(i + 1))
return x
def transition_block(x, reduction, name):
"""A transition block.
转换块
# Arguments
参数
x: input tensor.
x: 输入参数
reduction: float, compression rate at transition layers.
reduction: 浮点数,转换层的压缩率
name: string, block label.
name: 字符串,块标签
# Returns
返回
output tensor for the block.
块输出张量
"""
bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
x = BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
name=name + '_bn')(x)
x = Activation('relu', name=name + '_relu')(x)
x = Conv2D(int(K.int_shape(x)[bn_axis] * reduction), 1, use_bias=False,
name=name + '_conv')(x)
x = AveragePooling2D(2, strides=2, name=name + '_pool')(x)
return x
def conv_block(x, growth_rate, name):
"""A building block for a dense block.
密集块正在建立的块
# Arguments
参数
x: input tensor.
x: 输入张量
growth_rate: float, growth rate at dense layers.
growth_rate:浮点数,密集层的增长率。
name: string, block label.
name: 字符串,块标签
# Returns
返回
output tensor for the block.
块输出张量
"""
bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
x1 = BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
name=name + '_0_bn')(x)
x1 = Activation('relu', name=name + '_0_relu')(x1)
x1 = Conv2D(4 * growth_rate, 1, use_bias=False,
name=name + '_1_conv')(x1)
x1 = BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
name=name + '_1_bn')(x1)
x1 = Activation('relu', name=name + '_1_relu')(x1)
x1 = Conv2D(growth_rate, 3, padding='same', use_bias=False,
name=name + '_2_conv')(x1)
x = Concatenate(axis=bn_axis, name=name + '_concat')([x, x1])
return x
def DenseNet(blocks,
include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
"""Instantiates the DenseNet architecture.
实例化DenseNet结构
Optionally loads weights pre-trained
on ImageNet. Note that when using TensorFlow,
for best performance you should set
`image_data_format='channels_last'` in your Keras config
at ~/.keras/keras.json.
可选择加载预训练的ImageNet权重。注意,如果是Tensorflow,最好在Keras配置中设置`image_data_format='channels_last'
The model and the weights are compatible with
TensorFlow, Theano, and CNTK. The data format
convention used by the model is the one
specified in your Keras config file.
模型和权重兼容TensorFlow, Theano, and CNTK.模型使用的数据格式约定是Keras配置文件中指定的一种格式。
# Arguments
参数
blocks: numbers of building blocks for the four dense layers.
blocks: (构建)4个密集层需要块数量
include_top: whether to include the fully-connected
layer at the top of the network.
include_top: 在网络的顶层(一般指最后一层)师傅包含全连接层
weights: one of `None` (random initialization),
'imagenet' (pre-training on ImageNet),
or the path to the weights file to be loaded.
以下的一个:`None` (随机初始化),'imagenet' (ImageNet预训练),或者下载权重文件的路径。
input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
to use as image input for the model.
input_tensor: 可选的Keras张量(即,`layers.Input()`的输出),用作模型的图像输入。
input_shape: optional shape tuple, only to be specified
if `include_top` is False (otherwise the input shape
has to be `(224, 224, 3)` (with `channels_last` data format)
or `(3, 224, 224)` (with `channels_first` data format).
It should have exactly 3 inputs channels.
input_shape: 可选的形状元组,只有`include_top`是False(否则,输入形状必须
是“(224, 224, 3)”(带有`channels_first` 数据格式。))时需要确认,它应该有3个输入通道。
pooling: optional pooling mode for feature extraction
when `include_top` is `False`.
可选,当 `include_top`是FALSE,特征提取的池化模式。
- `None` means that the output of the model will be
the 4D tensor output of the
last convolutional layer.
`None` 表示,模型输出层是4维张量,从上一个的卷积层输出。
- `avg` means that global average pooling
will be applied to the output of the
last convolutional layer, and thus
the output of the model will be a 2D tensor.
`avg`表示全局平均池化被应用到上一个的卷积层输出,所以模型输出是2维张量。
- `max` means that global max pooling will
be applied.
`max` 表示全局最大池化被应用
classes: optional number of classes to classify images
into, only to be specified if `include_top` is True, and
if no `weights` argument is specified.
classes: 可选的类数分类的图像,只有指定,如果'include_top'是真的,如果没有'weights'参数被指定。
# Returns
返回
A Keras model instance.
一个Keras模型实例
# Raises
补充
ValueError: in case of invalid argument for `weights`,
or invalid input shape.
ValueError: weights`无效的参数,或者无效的输入形状
"""
if not (weights in {'imagenet', None} or os.path.exists(weights)):
raise ValueError('The `weights` argument should be either '
'`None` (random initialization), `imagenet` '
'(pre-training on ImageNet), '
'or the path to the weights file to be loaded.')
if weights == 'imagenet' and include_top and classes != 1000:
raise ValueError('If using `weights` as imagenet with `include_top`'
' as true, `classes` should be 1000')
# Determine proper input shape
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=221,
data_format=K.image_data_format(),
require_flatten=include_top,
weights=weights)
if input_tensor is None:
img_input = Input(shape=input_shape)
else:
if not K.is_keras_tensor(input_tensor):
img_input = Input(tensor=input_tensor, shape=input_shape)
else:
img_input = input_tensor
bn_axis = 3 if K.image_data_format() == 'channels_last' else 1
x = ZeroPadding2D(padding=((3, 3), (3, 3)))(img_input)
x = Conv2D(64, 7, strides=2, use_bias=False, name='conv1/conv')(x)
x = BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
name='conv1/bn')(x)
x = Activation('relu', name='conv1/relu')(x)
x = ZeroPadding2D(padding=((1, 1), (1, 1)))(x)
x = MaxPooling2D(3, strides=2, name='pool1')(x)
x = dense_block(x, blocks[0], name='conv2')
x = transition_block(x, 0.5, name='pool2')
x = dense_block(x, blocks[1], name='conv3')
x = transition_block(x, 0.5, name='pool3')
x = dense_block(x, blocks[2], name='conv4')
x = transition_block(x, 0.5, name='pool4')
x = dense_block(x, blocks[3], name='conv5')
x = BatchNormalization(axis=bn_axis, epsilon=1.001e-5,
name='bn')(x)
if include_top:
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(classes, activation='softmax', name='fc1000')(x)
else:
if pooling == 'avg':
x = GlobalAveragePooling2D(name='avg_pool')(x)
elif pooling == 'max':
x = GlobalMaxPooling2D(name='max_pool')(x)
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
# 确保模型考虑到任何潜在的前缀“input_tensor”。
if input_tensor is not None:
inputs = get_source_inputs(input_tensor)
else:
inputs = img_input
# Create model.
# 建立模型
if blocks == [6, 12, 24, 16]:
model = Model(inputs, x, name='densenet121')
elif blocks == [6, 12, 32, 32]:
model = Model(inputs, x, name='densenet169')
elif blocks == [6, 12, 48, 32]:
model = Model(inputs, x, name='densenet201')
else:
model = Model(inputs, x, name='densenet')
# Load weights.
# 加载权重
if weights == 'imagenet':
if include_top:
if blocks == [6, 12, 24, 16]:
weights_path = get_file(
'densenet121_weights_tf_dim_ordering_tf_kernels.h5',
DENSENET121_WEIGHT_PATH,
cache_subdir='models',
file_hash='0962ca643bae20f9b6771cb844dca3b0')
elif blocks == [6, 12, 32, 32]:
weights_path = get_file(
'densenet169_weights_tf_dim_ordering_tf_kernels.h5',
DENSENET169_WEIGHT_PATH,
cache_subdir='models',
file_hash='bcf9965cf5064a5f9eb6d7dc69386f43')
elif blocks == [6, 12, 48, 32]:
weights_path = get_file(
'densenet201_weights_tf_dim_ordering_tf_kernels.h5',
DENSENET201_WEIGHT_PATH,
cache_subdir='models',
file_hash='7bb75edd58cb43163be7e0005fbe95ef')
else:
if blocks == [6, 12, 24, 16]:
weights_path = get_file(
'densenet121_weights_tf_dim_ordering_tf_kernels_notop.h5',
DENSENET121_WEIGHT_PATH_NO_TOP,
cache_subdir='models',
file_hash='4912a53fbd2a69346e7f2c0b5ec8c6d3')
elif blocks == [6, 12, 32, 32]:
weights_path = get_file(
'densenet169_weights_tf_dim_ordering_tf_kernels_notop.h5',
DENSENET169_WEIGHT_PATH_NO_TOP,
cache_subdir='models',
file_hash='50662582284e4cf834ce40ab4dfa58c6')
elif blocks == [6, 12, 48, 32]:
weights_path = get_file(
'densenet201_weights_tf_dim_ordering_tf_kernels_notop.h5',
DENSENET201_WEIGHT_PATH_NO_TOP,
cache_subdir='models',
file_hash='1c2de60ee40562448dbac34a0737e798')
model.load_weights(weights_path)
elif weights is not None:
model.load_weights(weights)
return model
def DenseNet121(include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
return DenseNet([6, 12, 24, 16],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
def DenseNet169(include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
return DenseNet([6, 12, 32, 32],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
def DenseNet201(include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000):
return DenseNet([6, 12, 48, 32],
include_top, weights,
input_tensor, input_shape,
pooling, classes)
def preprocess_input(x, data_format=None):
"""Preprocesses a numpy array encoding a batch of images.
预处理:对一批图像进行编码numpy数组。
# Arguments
参数
x: a 3D or 4D numpy array consists of RGB values within [0, 255].
x: 3维或4维的numpy数组,组成了基于[0, 255]之间的RGB值(例如:(255,255,255))
data_format: data format of the image tensor.
data_format: 图像张量的数据格式。
# Returns
返回
Preprocessed array.
预处理后的数组。
"""
return imagenet_utils.preprocess_input(x, data_format, mode='torch')
setattr(DenseNet121, '__doc__', DenseNet.__doc__)
setattr(DenseNet169, '__doc__', DenseNet.__doc__)
setattr(DenseNet201, '__doc__', DenseNet.__doc__)
代码执行
Keras详细介绍
中文:http://keras-cn.readthedocs.io/en/latest/
实例下载
https://github.com/keras-team/keras
https://github.com/keras-team/keras/tree/master/examples
完整项目下载
方便没积分童鞋,请加企鹅452205574,共享文件夹。
包括:代码、数据集合(图片)、已生成model、安装库文件等。