深度残差收缩网络(Deep Residual Shrinkage Networks for Fault Diagnosis )

news2024/11/24 15:51:00

摘要-本文开发了新的深度学习方法,即深度残余收缩网络,提高来自高噪声振动信号的特征学习能力,并实现较高的故障诊断准确性。软阈值作为非线性转换层插入到深层体系结构中,以消除不重要的特征。此外,考虑到通常为阈值设置适当的值具有挑战性,开发的深度残余收缩网络集成了一些专门的神经网络作为可训练的模块来自动确定阈值,因此不需要信号处理方面的专业知识。通过各种噪声的实验验证了所开发方法的有效性。

引言

深度残差网络 (ResNets) 是ConvNets的一个有吸引力的变体,它使用身份快捷方式来缓解参数优化的难度 [15]。在ResNets中,梯度不仅逐层向后传播,而且还通过身份快捷方式直接流回初始层 [16]。

处理高噪声的振动信号时,ResNets的特征学习能力通常会降低。Resnet中用作本地特征提取器的卷积内核可能由于噪声的干扰而无法检测到与故障相关的特征。在这种情况下,在输出层学习的高级特征通常没有足够的区分性来正确分类故障。因此,有必要开发新的深度学习方法,用于在强背景噪声下基于振动的旋转机械故障诊断。

本文的贡献:

  1. 软阈值 (即一种流行的收缩函数) 作为非线性转换层插入到深度架构中,以有效消除噪声相关特征
  2. 使用专门设计的子网自适应地确定阈值,以便每个振动信号都可以具有自己的阈值集。
  3. 软阈值中考虑了两种阈值,即信道共享阈值和信道方式阈值

方法

身份捷径是使ResNet优于一般ConvNets的部分。交叉熵误差的梯度在通用ConvNet中逐层向后传播。通过使用身份快捷方式,梯度可以有效地流向靠近输入层的较早层,从而可以更有效地更新参数。减小输出特征图的宽度的动机是减少以下各层的计算量,增加输出特征图的通道数的动机是便于将不同特征集成为判别特征。

理论背景

在过去的20年中,软阈值通常被用作许多信号去噪方法中的关键步骤 [23],[24]。通常,将原始信号转换为接近零的数字不重要的域,然后应用软阈值将接近零的特征转换为零。例如,作为一种经典的信号去噪方法,小波阈值化通常由小波分解、软阈值化和小波重构三个步骤组成。为了确保信号去噪的良好性能,小波阈值的关键任务是设计一种滤波器,该滤波器可以将有用的信息转换为非常正的或负的特征,并将噪声信息转换为接近零的特征。然而,设计这样的滤波器需要大量的信号处理专业知识,并且一直是一个具有挑战性的问题。深度学习为解决这一问题提供了一种新的方法。深度学习可以使用梯度下降算法自动学习过滤器,而不是由专家人为地设计过滤器。因此,软阈值和深度学习的集成可能是消除噪声相关信息和构建高度区分性特征的一种有前途的方法。软阈值:

其中,x为输入特征,y为输出特征,τ 为阈值,即为正参数。软阈值化不是将relu激活函数中的负特征设置为零,而是将近零特征设置为零,这样可以保留有用的负特征。

 

 可以看出,输入输出的导数为1或0,这在防止梯度消失和爆炸。

经典的信号去噪算法中,通常很难为阈值设置适当的值

drsn-cs的体系结构

已开发的drsn-cs是ResNet的一种变体,它使用软阈值处理来消除与噪声相关的功能。软阈值作为非线性转换层插入到单元中。而且,可以在单元中学习阈值的值,这将在下面介绍。

如图4(a) 所示,名为 “具有信道共享阈值的剩余收缩构建单元 (RSBU-CS)” 的构建单元与图2(a) 中的RBU的不同之处在于,RSBU-CS具有用于估计要在软阈值中使用的阈值的特殊模块。在特殊模块中,将GAP应用于特征图x的绝对值,以获得一维向量。然后,将一维向量传播到两层FC网络中以获得缩放参数,该缩放参数类似于 [25] 中提供的缩放参数。然后在两层FC网络的末尾应用sigmoid函数,从而将缩放参数缩放到 (0,1) 的范围

 

 代码:

import torch
import torch.nn as nn

class BasicBlock(nn.Module):

    expansion = 1
    
    def __init__(self, in_channels, out_channels, stride=1):
        super().__init__()
        self.shrinkage = Shrinkage(out_channels, gap_size=(1, 1))
        #residual function
        self.residual_function = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Conv2d(out_channels, out_channels * BasicBlock.expansion, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(out_channels * BasicBlock.expansion),
            self.shrinkage
        )
        #shortcut
        self.shortcut = nn.Sequential()

        #the shortcut output dimension is not the same with residual function
        #use 1*1 convolution to match the dimension
        if stride != 1 or in_channels != BasicBlock.expansion * out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels * BasicBlock.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels * BasicBlock.expansion)
            )

    def forward(self, x):
        return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x))


class Shrinkage(nn.Module):
    def __init__(self,  channel, gap_size):
        super(Shrinkage, self).__init__()
        self.gap = nn.AdaptiveAvgPool2d(gap_size)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel),
            nn.BatchNorm1d(channel),
            nn.ReLU(inplace=True),
            nn.Linear(channel, channel),
            nn.Sigmoid(),
        )

    def forward(self, x):
        x_raw = x
        x = torch.abs(x)
        x_abs = x
        x = self.gap(x)
        x = torch.flatten(x, 1)
        # average = torch.mean(x, dim=1, keepdim=True)
        average = x
        x = self.fc(x)
        x = torch.mul(average, x)
        x = x.unsqueeze(2).unsqueeze(2)
        # soft thresholding
        sub = x_abs - x
        zeros = sub - sub
        n_sub = torch.max(sub, zeros)
        x = torch.mul(torch.sign(x_raw), n_sub)
        return x

class RSNet(nn.Module):

    def __init__(self, block, num_block, num_classes=100):
        super().__init__()

        self.in_channels = 64

        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True))
        #we use a different inputsize than the original paper
        #so conv2_x's stride is 1
        self.conv2_x = self._make_layer(block, 64, num_block[0], 1)
        self.conv3_x = self._make_layer(block, 128, num_block[1], 2)
        self.conv4_x = self._make_layer(block, 256, num_block[2], 2)
        self.conv5_x = self._make_layer(block, 512, num_block[3], 2)
        self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512 * block.expansion, num_classes)

    def _make_layer(self, block, out_channels, num_blocks, stride):
        """make rsnet layers(by layer i didnt mean this 'layer' was the
        same as a neuron netowork layer, ex. conv layer), one layer may
        contain more than one residual shrinkage block

        Args:
            block: block type, basic block or bottle neck block
            out_channels: output depth channel number of this layer
            num_blocks: how many blocks per layer
            stride: the stride of the first block of this layer

        Return:
            return a rsnet layer
        """

        # we have num_block blocks per layer, the first block
        # could be 1 or 2, other blocks would always be 1
        strides = [stride] + [1] * (num_blocks - 1)
        layers = []
        for stride in strides:
            layers.append(block(self.in_channels, out_channels, stride))
            self.in_channels = out_channels * block.expansion

        return nn.Sequential(*layers)

    def forward(self, x):
        output = self.conv1(x)
        output = self.conv2_x(output)
        output = self.conv3_x(output)
        output = self.conv4_x(output)
        output = self.conv5_x(output)
        output = self.avg_pool(output)
        output = output.view(output.size(0), -1)
        output = self.fc(output)

        return output

def rsnet18():
    """ return a RSNet 18 object
    """
    return RSNet(BasicBlock, [2, 2, 2, 2])

def rsnet34():
    """ return a RSNet 34 object
    """
    return RSNet(BasicBlock, [3, 4, 6, 3])

参考文献:

深度残差收缩网络(完整PyTorch程序) - 腾讯云开发者社区-腾讯云 (tencent.com)

注意力机制与残差网络:深度残差收缩网络 - 简书 (jianshu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据编程实验一:HDFS常用操作和Spark读取文件系统数据

大数据编程实验一:HDFS常用操作和Spark读取文件系统数据 文章目录大数据编程实验一:HDFS常用操作和Spark读取文件系统数据一、前言二、实验目的与要求三、实验内容四、实验步骤1、HDFS常用操作2、Spark读取文件系统的数据五、最后我想说一、前言 这是我…

Swift基础——字典

Swift基础——字典 嗯。。。前面我们已经学习了数组(相关文章地址),我们知道了在Swift中,苹果提供了两种集合类型来存储集合的值即Array和Dictionary。 Dictionary字典 字典:一种存储多个相同类型值的容器&#xff…

谈谈Java对象的生命周期

经过前面的分析 ,我们现在来看一下创建的对象到底是什么东西,并且完整的总结一下一个对象从创建到回收到底经过了哪些阶段。 1 对象的创建 对象创建的主要流程: 1.类加载检查 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常…

【趣学算法】贪心算法、海盗古董装船问题

14天阅读挑战赛 努力是为了不平庸~ 算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法! 文章目录贪心本质贪心选择最优子结构最优装载问题sort函数总结贪心本质 一个贪心算法总是做出当前最好的选择,也就是说…

R语言“优雅地“进行医学统计分析

本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。 医学和生信笔记,专注R语言在临床医学中的使用,R语言数据分析和可视化。 文章目录主要函数描述性统计比较均值增强R中的ANOVA事后检验(post-hoc&…

嘉立创EDA的一些使用技巧

立创EDA专业版-使用教程 (lceda.cn):https://prodocs.lceda.cn/cn/faq/editor/index.html绘制板框:https://blog.csdn.net/gutie_bartholomew/article/details/122936253和 mil 的切换,按【Q】切换单位测量 AltM,方便地测量物件之间的距离。按…

MySQL调优之索引在什么情况下会失效?

MySQL中提高性能的一个最有效的方式是对数据表设计合理的索引。索引提供了高效访问数据的方法,并且加快查询的速度,因此索引对查询的速度有着至关重要的影响。 使用索引可以快速地定位表中的某条记录,从而提高数据库查询的速度,提…

Spring JdbcTemplate.queryForObject()

Spring JdbcTemplate 是JDBC核心包中的中心类。它简化了 JDBC 与 Spring 的使用&#xff0c;并有助于避免常见错误。在此页面上&#xff0c;我们将学习使用它的queryForObject 方法。 JdbcTemplate.queryForObject不同参数的方法。1. <T> T queryForObject(String sql, …

继承-安全-设计模式

继承 与 原型、原型链 1. 继承是什么&#xff1f; 继承就是一个对象可以访问另外一个对象中的属性和方法 2. 继承的目的&#xff1f; 继承的目的就是实现原来设计与代码的重用 3. 继承的方式 java、c等&#xff1a;class**javaScript&#xff1a; 原型链 ** ES2015/ES6 中…

数据导入与预处理-拓展-pandas可视化

数据导入与预处理-拓展-pandas可视化1. 折线图1.1 导入数据1.2 绘制单列折线图1.3 绘制多列折线图1.4 绘制折线图-双y轴2. 条形图2.1 单行垂直/水平条形图2.2 多行条形图3. 直方图3.1 生成数据3.2 透明度/刻度/堆叠直方图3.3 拆分子图4. 散点图4.1生成数据4.2 绘制大小不一的散…

自动化测试的使用场景有哪些?如何正确使用?

目录 前言 什么是自动化测试&#xff1f; 自动化测试的使用场景有哪些&#xff1f; 自动化测试有什么好处&#xff1f; 总结 前言 本文将通过介绍 自动化测试是什么 &#xff0c; 哪些场景适用于自动化测试 &#xff0c; 自动化测试的好处 &#xff0c; 以及通过 具体的自…

vue如何二次封装一个高频可复用的组件

在我们的业务里&#xff0c;我们通常会二次封装一些高频业务组件&#xff0c;比如弹框&#xff0c;抽屉&#xff0c;表单等这些业务组件&#xff0c;为什么要二次封装&#xff1f;我们所有人心里的答案肯定是&#xff0c;同样类似的代码太多了&#xff0c;我想复用组件&#xf…

2004-2020中小企业板上市公司财务报表股票交易董事高管等面板数据

1200变量&#xff01;中小企业板上市公司面板数据大全 2004-2020年 1、时间&#xff1a;2004-2020年 2、数据范围&#xff1a;共计973家上市公司 3、数据指标&#xff1a;包括财务报表、股票交易、董事高管等1200变量 4、用途&#xff1a;进行上市公司高管股权激励与公司绩…

C语言刷题系列——1.将三个整数按从大到小输出

将三个整数按从大到小输出1.输入三个整数2.最大的值放在a中&#xff0c;最小值放在c中&#xff0c;剩余的一个放在bstep1&#xff1a;a和b比较step2&#xff1a;a和c比较step3&#xff1a;b和c比较3.最终的代码1.输入三个整数 先写好main函数、头文件 #include <stdio.h&g…

用高并发技巧解决redis热key问题

​ 这篇文章我将介绍工作中处理热key问题的常用手段&#xff0c;可能介绍的不是很全&#xff0c;毕竟不同的业务场景可能有不同的解决方案&#xff0c;但是相信通过这部分的介绍能提供一个热key问题的思路。 热key问题&#xff0c;简单来说就是对某一资源的访问量过高问题&…

Unity学习shader笔记[一百零八]简单萤火效果

之前用粒子系统基于原有萤火虫的粒子改了一波慢萤火效果就被惊艳到了&#xff0c;开始大家讨论&#xff0c;就都觉得这样大数量的粒子消耗挺大的&#xff0c;后面测试过才发现单纯的粒子系统在总粒子数量3000&#xff0c;每秒300的生成数量&#xff0c;屏幕呈现有1000多个粒子的…

【黄啊码】MySQL入门—17、在没有备份的情况下,如何恢复数据库数据?

大家好&#xff01;我是黄啊码&#xff0c;MySQL的入门篇已经讲到第16个课程了&#xff0c;今天我们继续讲讲大白篇系列——科技与狠活之恢复数据库 在没做数据库备份&#xff0c;没有开启使用 Binlog 的情况下&#xff0c;尽可能地找回数据。 今天的内容主要包括以下几个部分…

2022NISCTF--web

easyssrf 打开题目&#xff0c;显示的是 尝试输入&#xff0c; 发现输入flag有东西 读取文件 访问下一个网站 读取文件 不能以file开头 直接伪协议&#xff0c;base64解码 checkIn 奇怪的unicode编码 当选中左边的时候右边也会被选中 我们在vscode看看 这样的额 展示的是UTF-1…

Linux系统中利用open函数多次打开同一个文件操作方法

大家好。 今天的话主要和大家聊一聊&#xff0c;在Linux系统中如果一个文件被打开多次会出现什么情况。 目录 第一&#xff1a;多次打开同一个文件 ​第二&#xff1a;一个文件被打开多次&#xff0c;在内存中不会存在多份动态文件 ​第三&#xff1a;多次open打开同一…

第一章 - Windows安装VMware Workstation Pro

文章目录前言一、VMware Workstation Pro安装的前提条件二、VMware Workstation Pro下载三、VMware Workstation Pro安装前言 Linux是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发已经得到业界认可&#xff0c;目前很多企业级的项目都会部署到Linux系统…