Keras快速搭建深度残差收缩网络(及深度残差网络)

从本质上讲,深度残差收缩网络属于卷积神经网络,是深度残差网络(deep residual network, ResNet)的一个变种。它的核心思想在于,在深度学习进行特征学习的过程中,剔除冗余信息是非常重要的;软阈值化是一种非常灵活的、删除冗余信息的方式。

1.深度残差网络

首先,在介绍深度残差收缩网络的时候,经常需要从深度残差网络开始讲起。下图展示了深度残差网络的基本模块,包括一些非线性层(残差路径)和一个跨层的恒等连接。恒等连接是深度残差网络的核心,是其优异性能的一个保障。

2.深度残差收缩网络

深度残差收缩网络,就是对深度残差网络的残差路径进行收缩的一种网络。这里的“收缩”指的就是软阈值化。

软阈值化是许多信号降噪方法的核心步骤,它是将接近于零(或者说绝对值低于某一阈值τ)的特征置为0,也就是将[-τ, τ]区间内的特征置为0,让其他的、距0较远的特征也朝着0进行收缩。

如果和前一个卷积层的偏置b放在一起看的话,这个置为零的区间就变成了[-τ+b, τ+b]。因为τ和b都是可以自动学习得到的参数,这个角度看的话,软阈值化其实是可以将任意区间的特征置为零,是一种更灵活的、删除某个取值范围特征的方式,也可以理解成一种更灵活的非线性映射。

从另一个方面来看,前面的两个卷积层、两个批标准化和两个激活函数,将冗余信息的特征,变换成接近于零的值;将有用的特征,变换成远离零的值。之后,通过自动学习得到一组阈值,利用软阈值化将冗余特征剔除掉,将有用特征保留下来。

通过堆叠一定数量的基本模块,可以构成完整的深度残差收缩网络,如下图所示:

3.图像识别及Keras编程

虽然深度残差收缩网络原先是应用于基于振动信号的故障诊断,但是深度残差收缩网络事实上是一种通用的特征学习方法,相信在很多任务(计算机视觉、语音、文本)中都可能有一定的用处。

下面是基于深度残差收缩网络的MNIST手写数字识别程序(程序很简单,仅供参考):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 28 23:24:05 2019

Implemented using TensorFlow 1.0.1 and Keras 2.2.1

M. Zhao, S. Zhong, X. Fu, et al., Deep Residual Shrinkage Networks for Fault Diagnosis,
IEEE Transactions on Industrial Informatics, 2019, DOI: 10.1109/TII.2019.2943898

@author: me
"""

from __future__ import print_function
import keras
import numpy as np
from keras.datasets import mnist
from keras.layers import Dense, Conv2D, BatchNormalization, Activation
from keras.layers import AveragePooling2D, Input, GlobalAveragePooling2D
from keras.optimizers import Adam
from keras.regularizers import l2
from keras import backend as K
from keras.models import Model
from keras.layers.core import Lambda
K.set_learning_phase(1)

# Input image dimensions
img_rows, img_cols = 28, 28

# The data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == ‘channels_first‘:
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

# Noised data
x_train = x_train.astype(‘float32‘) / 255. + 0.5*np.random.random([x_train.shape[0], img_rows, img_cols, 1])
x_test = x_test.astype(‘float32‘) / 255. + 0.5*np.random.random([x_test.shape[0], img_rows, img_cols, 1])
print(‘x_train shape:‘, x_train.shape)
print(x_train.shape[0], ‘train samples‘)
print(x_test.shape[0], ‘test samples‘)

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

def abs_backend(inputs):
    return K.abs(inputs)

def expand_dim_backend(inputs):
    return K.expand_dims(K.expand_dims(inputs,1),1)

def sign_backend(inputs):
    return K.sign(inputs)

def pad_backend(inputs, in_channels, out_channels):
    pad_dim = (out_channels - in_channels)//2
    return K.spatial_3d_padding(inputs, padding = ((0,0),(0,0),(pad_dim,pad_dim)))

# Residual Shrinakge Block
def residual_shrinkage_block(incoming, nb_blocks, out_channels, downsample=False,
                             downsample_strides=2):

    residual = incoming
    in_channels = incoming.get_shape().as_list()[-1]

    for i in range(nb_blocks):

        identity = residual

        if not downsample:
            downsample_strides = 1

        residual = BatchNormalization()(residual)
        residual = Activation(‘relu‘)(residual)
        residual = Conv2D(out_channels, 3, strides=(downsample_strides, downsample_strides),
                          padding=‘same‘, kernel_initializer=‘he_normal‘,
                          kernel_regularizer=l2(1e-4))(residual)

        residual = BatchNormalization()(residual)
        residual = Activation(‘relu‘)(residual)
        residual = Conv2D(out_channels, 3, padding=‘same‘, kernel_initializer=‘he_normal‘,
                          kernel_regularizer=l2(1e-4))(residual)

        # Calculate global means
        residual_abs = Lambda(abs_backend)(residual)
        abs_mean = GlobalAveragePooling2D()(residual_abs)

        # Calculate scaling coefficients
        scales = Dense(out_channels, activation=None, kernel_initializer=‘he_normal‘,
                       kernel_regularizer=l2(1e-4))(abs_mean)
        scales = BatchNormalization()(scales)
        scales = Activation(‘relu‘)(scales)
        scales = Dense(out_channels, activation=‘sigmoid‘, kernel_regularizer=l2(1e-4))(scales)
        scales = Lambda(expand_dim_backend)(scales)

        # Calculate thresholds
        thres = keras.layers.multiply([abs_mean, scales])

        # Soft thresholding
        sub = keras.layers.subtract([residual_abs, thres])
        zeros = keras.layers.subtract([sub, sub])
        n_sub = keras.layers.maximum([sub, zeros])
        residual = keras.layers.multiply([Lambda(sign_backend)(residual), n_sub])

        # Downsampling (it is important to use the pooL-size of (1, 1))
        if downsample_strides > 1:
            identity = AveragePooling2D(pool_size=(1,1), strides=(2,2))(identity)

        # Zero_padding to match channels (it is important to use zero padding rather than 1by1 convolution)
        if in_channels != out_channels:
            identity = Lambda(pad_backend)(identity, in_channels, out_channels)

        residual = keras.layers.add([residual, identity])

    return residual

# define and train a model
inputs = Input(shape=input_shape)
net = Conv2D(8, 3, padding=‘same‘, kernel_initializer=‘he_normal‘, kernel_regularizer=l2(1e-4))(inputs)
net = residual_shrinkage_block(net, 1, 8, downsample=True)
net = BatchNormalization()(net)
net = Activation(‘relu‘)(net)
net = GlobalAveragePooling2D()(net)
outputs = Dense(10, activation=‘softmax‘, kernel_initializer=‘he_normal‘, kernel_regularizer=l2(1e-4))(net)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss=‘categorical_crossentropy‘, optimizer=Adam(), metrics=[‘accuracy‘])
model.fit(x_train, y_train, batch_size=100, epochs=5, verbose=1, validation_data=(x_test, y_test))

# get results
K.set_learning_phase(0)
DRSN_train_score = model.evaluate(x_train, y_train, batch_size=100, verbose=0)
print(‘Train loss:‘, DRSN_train_score[0])
print(‘Train accuracy:‘, DRSN_train_score[1])
DRSN_test_score = model.evaluate(x_test, y_test, batch_size=100, verbose=0)
print(‘Test loss:‘, DRSN_test_score[0])
print(‘Test accuracy:‘, DRSN_test_score[1])

为方便对比,深度残差网络的代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 28 23:19:03 2019

Implemented using TensorFlow 1.0 and Keras 2.2.1
K. He, X. Zhang, S. Ren, J. Sun, Deep Residual Learning for Image Recognition, CVPR, 2016.

@author: me
"""

from __future__ import print_function
import numpy as np
import keras
from keras.datasets import mnist
from keras.layers import Dense, Conv2D, BatchNormalization, Activation
from keras.layers import AveragePooling2D, Input, GlobalAveragePooling2D
from keras.optimizers import Adam
from keras.regularizers import l2
from keras import backend as K
from keras.models import Model
from keras.layers.core import Lambda
K.set_learning_phase(1)

# input image dimensions
img_rows, img_cols = 28, 28

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == ‘channels_first‘:
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

# Noised data
x_train = x_train.astype(‘float32‘) / 255. + 0.5*np.random.random([x_train.shape[0], img_rows, img_cols, 1])
x_test = x_test.astype(‘float32‘) / 255. + 0.5*np.random.random([x_test.shape[0], img_rows, img_cols, 1])
print(‘x_train shape:‘, x_train.shape)
print(x_train.shape[0], ‘train samples‘)
print(x_test.shape[0], ‘test samples‘)

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

def pad_backend(inputs, in_channels, out_channels):
    pad_dim = (out_channels - in_channels)//2
    return K.spatial_3d_padding(inputs, padding = ((0,0),(0,0),(pad_dim,pad_dim)))

def residual_block(incoming, nb_blocks, out_channels, downsample=False,
                             downsample_strides=2):

    residual = incoming
    in_channels = incoming.get_shape().as_list()[-1]

    for i in range(nb_blocks):

        identity = residual

        if not downsample:
            downsample_strides = 1

        residual = BatchNormalization()(residual)
        residual = Activation(‘relu‘)(residual)
        residual = Conv2D(out_channels, 3, strides=(downsample_strides, downsample_strides),
                          padding=‘same‘, kernel_initializer=‘he_normal‘,
                          kernel_regularizer=l2(1e-4))(residual)

        residual = BatchNormalization()(residual)
        residual = Activation(‘relu‘)(residual)
        residual = Conv2D(out_channels, 3, padding=‘same‘, kernel_initializer=‘he_normal‘,
                          kernel_regularizer=l2(1e-4))(residual)

        # Downsampling (it is important to use the pooL-size of (1, 1))
        if downsample_strides > 1:
            identity = AveragePooling2D(pool_size=(1, 1), strides=(2, 2))(identity)

        # Zero_padding to match channels (it is important to use zero padding rather than 1by1 convolution)
        if in_channels != out_channels:
            identity = Lambda(pad_backend)(identity, in_channels, out_channels)

        residual = keras.layers.add([residual, identity])

    return residual

# define and train a model
inputs = Input(shape=input_shape)
net = Conv2D(8, 3, padding=‘same‘, kernel_initializer=‘he_normal‘, kernel_regularizer=l2(1e-4))(inputs)
net = residual_block(net, 1, 8, downsample=True)
net = BatchNormalization()(net)
net = Activation(‘relu‘)(net)
net = GlobalAveragePooling2D()(net)
outputs = Dense(10, activation=‘softmax‘, kernel_initializer=‘he_normal‘, kernel_regularizer=l2(1e-4))(net)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss=‘categorical_crossentropy‘, optimizer=Adam(), metrics=[‘accuracy‘])
model.fit(x_train, y_train, batch_size=100, epochs=5, verbose=1, validation_data=(x_test, y_test))

# get results
K.set_learning_phase(0)
resnet_train_score = model.evaluate(x_train, y_train, batch_size=100, verbose=0)
print(‘Train loss:‘, resnet_train_score[0])
print(‘Train accuracy:‘, resnet_train_score[1])
resnet_test_score = model.evaluate(x_test, y_test, batch_size=100, verbose=0)
print(‘Test loss:‘, resnet_test_score[0])
print(‘Test accuracy:‘, resnet_test_score[1])

备注:
(1)深度残差收缩网络的结构比普通的深度残差网络复杂,也许更难训练。
(2)程序里只设置了一个基本模块,在更复杂的数据集上,可适当增加。
(3)如果遇到这个TypeError:softmax() got an unexpected keyword argument ‘axis‘,就点开tensorflow_backend.py,将return tf.nn.softmax(x, axis=axis)中的第一个axis改成dim即可。

转载网址:

https://segmentfault.com/a/1190000021437510

参考文献:

M. Zhao, S. Zhong, X. Fu, et al., Deep residual shrinkage networks for fault diagnosis, IEEE Transactions on Industrial Informatics, 2019, DOI: 10.1109/TII.2019.2943898

https://ieeexplore.ieee.org/document/8850096

原文地址:https://www.cnblogs.com/yc-9527/p/12127956.html

时间: 2024-08-04 08:12:23

Keras快速搭建深度残差收缩网络(及深度残差网络)的相关文章

深度残差收缩网络:(四)注意力机制下的阈值设置

对于基于深度学习的分类算法,其关键不仅在于提取与标签相关的目标信息,剔除无关的信息也是非常重要的,所以要在深度神经网络中引入软阈值化.阈值的自动设置,是深度残差收缩网络的核心贡献.需要注意的是,软阈值化中的阈值,需要满足一定的条件.这篇文章中的阈值设置,事实上,是在注意力机制下进行的.下面分别介绍阈值需要满足的条件.注意力机制以及具体的阈值设置方法. (1)阈值需要满足的条件 在软阈值化中,阈值的取值有一定的要求:首先,阈值必须是正数:其次,阈值不能太大,否则输出会全部为零. 更重要的是,每个样

深度残差收缩网络:(一)背景知识

深度残差收缩网络(Deep Residual Shrinkage Network)是深度残差学习(Deep Residual Network, ResNet)的一种改进,发表在IEEE Transactions on Industrial Informatics上,面向的是数据包含噪声的情况. 简单地讲,深度残差收缩网络就是,将软阈值化作为可训练的模块,嵌入到ResNet之中.接下来结合自己的理解,解读一下相关的背景知识. (1)噪声的含义 如上所述,深度残差收缩网络面向的是数据包含噪声的情况.

深度残差收缩网络:(三)网络结构

(1)回顾一下深度残差网络的结构 在下图中,(a)-(c)分别是三种残差模块,(d)是深度残差网络的整体示意图.BN指的是批标准化(Batch Normalization),ReLU指的是整流线性单元激活函数(Rectifier Linear Unit),Conv指的是卷积层(Convolutional layer),Identity shortcut指的是跨层的恒等映射,RBU指的是残差模块(Residual Building Unit),GAP是全局均值池化(Global Average P

深度残差收缩网络:(五)实验验证

实验部分将所提出的两种深度残差收缩网络,即“通道之间共享阈值的深度残差收缩网络(Deep Residual Shrinkage Networks with Channel-shared Thresholds,简称DRSN-CS)”,和“逐通道不同阈值的深度残差收缩网络(Deep Residual Shrinkage Networks with Channel-wise Thresholds,简称DRSN-CW)”,与传统的卷积神经网络(Convolutional Neural Networks,

TFLearn实现深度残差收缩网络(MNIST数据集)

深度残差收缩网络是一种新颖的深度学习算法,实际上是深度残差网络的升级版本,能够在一定程度上提高深度学习方法在含噪数据上的特征学习效果. 首先,简单回顾一下深度残差网络,深度残差网络的基本模块如下图所示.相较于普通的卷积神经网络,深度残差网络引入了跨层的恒等映射,来减小模型训练的难度,提高准确率. 然后,在深度残差网络的基础上,深度残差收缩网络引入了一个小型的子网络,用这个子网络学习得到一组阈值,对特征图的各个通道进行软阈值化.这个过程其实可以看成一个可训练的特征选择的过程.具体而言,就是通过前面

基于深度残差收缩网络的故障诊断

论文题目:Deep residual shrinkage networks for fault diagnosis 题目翻译:基于深度残差收缩网络的故障诊断 期刊:IEEE Transactions on Industrial Informatics 面向问题:强噪声(或冗余信息繁多) 创新:①在深度残差网络中引入软阈值化,②并且自动设置阈值 本质:在注意力机制下实现特征的软阈值化 M. Zhao, S, Zhong, X. Fu, et al. Deep residual shrinkage

利用 TFLearn 快速搭建经典深度学习模型

利用 TFLearn 快速搭建经典深度学习模型 使用 TensorFlow 一个最大的好处是可以用各种运算符(Ops)灵活构建计算图,同时可以支持自定义运算符(见本公众号早期文章<TensorFlow 增加自定义运算符>).由于运算符的粒度较小,在构建深度学习模型时,代码写出来比较冗长,比如实现卷积层:5, 9 这种方式在设计较大模型时会比较麻烦,需要程序员徒手完成各个运算符之间的连接,像一些中间变量的维度变换.运算符参数选项.多个子网络连接处极易发生问题,肉眼检查也很难发现代码中潜伏的 bu

学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统地讲解了深度学习的基本知识.建模过程和应用,并以深度学习在推荐系统.图像识别.自然语言处理.文字生成和时间序列中的具体应用为案例,详细介绍了从工具准备.数据获取和处理到针对问题进行建模的整个过程和实践经验. <Keras快速上手>PDF,531页,带书签目录,彩色配图,文字可以复制. 配套源代码和

9款一键快速搭建PHP运行环境的好工具

原文链接: http://www.cmhello.com/a-key-build-php-environment.html 内容提要: 建立一个PHP网站,首先需要搭建PHP的开发和运行环境,对于PHP初学者也是一个难题,下面介绍部分一站式PHP环境搭建安装程序.小编推荐使用APMServ或者phpnow. 一键搭建PHP运行环境工具 1.APMServ http://apmserv.s135.com/国内研发,功能强大,操作简单,无需安装,只需鼠标一点,即可在自己的电脑上傻瓜全自动搭建一个完美