小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN

这篇具有很好参考价值的文章主要介绍了小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        本文以实验为导向,使用vgg16+GLCM实现一场精彩的新冠肺炎的分类识别,并且对比不加GLCM后的效果。在这之前,我们需要弄明白一些前缀知识和概念问题:

GLCM(Gray-Level Co-occurrence Matrix),中文称为灰度共生矩阵,是一种用于图像纹理特征提取的统计方法。它是由Tamura等人在1978年首次提出的,用于描述图像中灰度级别之间的相互关系。GLCM在图像处理和计算机视觉领域中广泛应用,特别是在纹理分析、目标识别和图像分类等任务中作为单独特征提取的一环,并与CNN结合达到非凡的效果。

灰度级别:是指图像中每个像素的灰度值的取值范围。在数字图像中,每个像素的灰度值表示了该像素在灰度图像中的亮度程度。灰度级别通常用整数表示,其取值范围取决于图像的位深度。在一个8位灰度图像中,灰度级别的范围为0到255,其中0表示最暗的黑色,255表示最亮的白色。这意味着该图像中每个像素的灰度值可以取256个不同的值,这些值之间以等间距分布。对于一个黑白图像,每个像素只有一个灰度值,而对于彩色图像,每个像素则有多个通道,每个通道都有自己的灰度级别范围。

一、GLCM算法原理🍉 

1.1 GLCM计算原理🎈

        共生矩阵用两个位置的像素的联合概率密度来定义,它不仅反映亮度的分布特性,也反映具有同样亮度或接近亮度的象素之间的位置分布特性,是有关图象亮度变化的二阶统计特征。它是定义一组纹理特征的基础。一幅图象的灰度共生矩阵能反映出图象灰度关于方向、相邻间隔、变化幅度的综合信息,它是分析图象的局部模式和它们排列规则的基础。

设为一幅二维数字图像,其大小为M × N,灰度级别为,则满足一定空间关系的灰度共生矩阵为:

{(x1,y1),(x2,y2)∈M×N|f(x1,y1)=i, f(x2,y2)=j}
其中表示集合x中的元素个数,显然P为Ng×Ng的矩阵,若(x1,y1)与(x2,y2)间距离为d,两者与坐标横轴的夹角为θ,则可以得到各种间距及角度的灰度共生矩阵:

  • i:为f(x,y)中灰度值为i的元素位置列表;
  • j:为f(x,y)中灰度值为j的元素位置列表;
  • d:为(x1,y1)(x2,y2)之间的距离;
  • θ:为(x1,y1)(x2,y2)之间连线与横坐标的夹角;

最后我们遍历i,j列表,找出和(d,θ)所描述的空间位置一样的一对位置(x1,y1)和(x2,y2)有多少个,从而得到P(i,j)的值。也就是说,这其实不是最终形态的灰度共生矩阵,真正的灰度共生矩阵应该是一个大小和一样的,但它可以从中得到:

假设我们令(d=1,θ=0°), 以P(x,y,1,0°)点为例:

  • P(1,1,1,0°)= 1 ,即GLCM(1,1),说明左侧原图只有一对灰度为1的像素水平相邻。
  • P(1,2,1,0°)= 2, 即GLCM(1,2),说明左侧原图有两对灰度为1和2的像素水平相邻。

小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN,# sklearn,图像处理,# 图像分类,cnn,人工智能,神经网络

根据不同的(d, θ)组合,其实我们可以得到不同纹理的灰度共生矩阵,在GLCM(灰度共生矩阵)中,不同的距离和角度意味着在图像中计算纹理特征时考虑的像素之间的相对位置和方向,从而影响到后续纹理特征的提取。

  1. 距离(Distance): 距离指的是在GLCM中计算像素对共现频率时像素之间的间隔距离。通常,距离会影响纹理特征的大小和尺度。较小的距离可以捕捉图像中更细小的纹理细节,而较大的距离则能够考虑更广阔的像素关系,提取出更大范围的纹理特征。选择合适的距离取决于应用场景和所关注的纹理细节大小。

  2. 角度(Angle): 角度是指在GLCM中计算像素对共现频率时相对于水平方向的偏转角度。常用的角度通常是0°、45°、90°和135°。不同的角度能够捕捉图像中不同方向的纹理特征。例如,0°角度对应着水平方向的纹理,能够检测到图像中水平的纹理结构;45°和135°角度对应着对角线方向的纹理,能够检测到图像中的对角线纹理结构;90°角度对应着垂直方向的纹理,能够检测到图像中垂直的纹理结构。因此,选择不同的角度可以从不同方向上提取纹理信息。

在实际应用中,通常会对多个距离和角度进行计算,得到多个GLCM,然后结合这些GLCM来计算一系列的纹理特征,如对比度、能量、相关性等。通过考虑不同的距离和角度,可以全面地捕捉图像中的纹理信息,使得GLCM在纹理分析、图像分类和目标识别等任务中发挥出更强大的能力。

1.2 GLCM纹理特征提取原理🎈 

        纹理特征提取的一种有效方法是以灰度级的空间相关矩阵即共生矩阵为基础的,因为图像中相距(Δx,Δy)的两个灰度像素同时出现的联合频率分布可以用灰度共生矩阵来表示。若将图像的灰度级定为N级,那么共生矩阵为N×N矩阵,可表示为M(Δx,Δy)(h,k),其中位于(h,k)的元素m(h,k)的值表示一个灰度为h而另一个灰度为k的两个相距为(Δx,Δy)的像素对出现的次数。
对粗纹理的区域,其灰度共生矩阵的m(h,k)值较集中于主对角线附近。因为对于粗纹理,像素对趋于具有相同的灰度。而对于细纹理的区域,其灰度共生矩阵中的mhk值则散布在各处。
为了能更直观地以共生矩阵描述纹理状况,从共生矩阵导出一些反映矩阵状况的参数,典型的有以下几种:
(1)能量:是灰度共生矩阵元素值的平方和,所以也称能量,反映了图像灰度分布均匀程度和纹理粗细度。如果共生矩阵的所有值均相等,则ASM值小;相反,如果其中一些值大而其它值小,则ASM值大。当共生矩阵中元素集中分布时,此时ASM值大。ASM值大表明一种较均一和规则变化的纹理模式。
(2)对比度:反映了图像的清晰度和纹理沟纹深浅的程度。纹理沟纹越深,其对比度越大,视觉效果越清晰;反之,对比度小,则沟纹浅,效果模糊。灰度差即对比度大的象素对越多,这个值越大。灰度公生矩阵中远离对角线的元素值越大,CON越大。
(3相关:它度量空间灰度共生矩阵元素在行或列方向上的相似程度,因此,相关值大小反映了图像中局部灰度相关性。当矩阵元素值均匀相等时,相关值就大;相反,如果矩阵像元值相差很大则相关值小。如果图像中有水平方向纹理,则水平方向矩阵的COR大于其余矩阵的COR值。
(4)熵:是图像所具有的信息量的度量,纹理信息也属于图像的信息,是一个随机性的度量,当共生矩阵中所有元素有最大的随机性、空间共生矩阵中所有值几乎相等时,共生矩阵中元素分散分布时,熵较大。它表示了图像中纹理的非均匀程度或复杂程度。
(5)逆差距:反映图像纹理的同质性,度量图像纹理局部变化的多少。其值大则说明图像纹理的不同区域间缺少变化,局部非常均匀。

1.3 GLCM代码实践🥒

#import package
from skimage.feature import graycomatrix, graycoprops
import numpy as np
import pandas as pd

#Feature Extraction with GLCM
def feature_extractor(images):
    image_dataset = pd.DataFrame()
    for image in images:
        df = pd.DataFrame()

        #greycomatrix(image, distances, angles, levels=256, symmetric=False, normed=False)
        #distances - List of pixel pair distance offsets.
        #angles - List of pixel pair angles in radians.

        #5 configuration for the grey-level co-occurrence matrix calculation
        dists = [[1],[3],[5],[3],[3]]
        angles = [[0],[0],[0],[np.pi/4],[np.pi/2]]

        for n ,(dist, angle) in enumerate(zip(dists, angles)):

            GLCM = graycomatrix(image, dist, angle)
            GLCM_Energy = graycoprops(GLCM, 'energy')[0]
            df['Energy'+str(n)] = GLCM_Energy
            GLCM_corr = graycoprops(GLCM, 'correlation')[0]
            df['Corr'+str(n)] = GLCM_corr
            GLCM_diss = graycoprops(GLCM, 'dissimilarity')[0]
            df['Diss_sim'+str(n)] = GLCM_diss
            GLCM_hom = graycoprops(GLCM, 'homogeneity')[0]
            df['Homogen'+str(n)] = GLCM_hom
            GLCM_contr = graycoprops(GLCM, 'contrast')[0]
            df['Contrast'+str(n)] = GLCM_contr

        image_dataset = image_dataset.append(df)

    return image_dataset

        看懂上面的理论知识,相信这份code已经不需要解释了。

二、GLCM+CNN网络构成👑

2.1 数据集构成🎈

2.2.2 CNN网络训练数据集 😊

train_images = torch.tensor(images_train,dtype=torch.float32).unsqueeze(1)#Convert the shape of the training set images to [*, 1, 256, 256].
train_labels = torch.tensor(labels,dtype=torch.int64)
val_images = torch.tensor(images_val,dtype=torch.float32).unsqueeze(1)#Convert the shape of the validation set images to [*, 1, 256, 256].
val_labels = torch.tensor(labels_val,dtype=torch.int64)
test_images = torch.tensor(images_test,dtype=torch.float32).unsqueeze(1)#Convert the shape of the test set images to [*, 1, 256, 256].
test_labels = torch.tensor(labels_test,dtype=torch.int64)

2.2.3 GLCM网络训练数据集😀

NOTE:images_train、images_val、images_test是numpy数组形式的数据集,用于提取GLCM特征。

train_extr_features = feature_extractor(images_train)
val_extr_features = feature_extractor(images_val)
test_extr_features = feature_extractor(images_test)

NOTE: 提取完特征后,变成torch.tensor类型,用于nn线性分类器网络训练。

trainFeatures = np.array(train_extr_features)
train_features = torch.tensor(trainFeatures,dtype=torch.float32)
validFeatures = np.array(val_extr_features)
valid_features = torch.tensor(validFeatures,dtype=torch.float32)
testFeatures = np.array(test_extr_features)
test_features = torch.tensor(testFeatures,dtype=torch.float32)

2.2 GLCM_CNN网络结构🎈


class GLCM_CNN(nn.Module):

    def __init__(self):
        super(GLCM_CNN,self).__init__()
        # 构建VGG16网络
        self.img_output = nn.Sequential(
                            #input is (*,1,256,256)
                            #nn.Conv2d(in_channels=1,out_channels=64,kernel_size=3,stride=1,padding='same'),
                            nn.Conv2d(in_channels=1,out_channels=64,kernel_size=3,stride=1,padding=(1, 1)),
                            # nn.BatchNorm2d(64),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=64,out_channels=64,kernel_size=3,stride=1,padding='same'),
                            nn.Conv2d(in_channels=64,out_channels=64,kernel_size=3,stride=1,padding=(1, 1)),
                            # nn.BatchNorm2d(64),
                            nn.ReLU(inplace=True),
                            nn.MaxPool2d(kernel_size=2,stride=2),
                            # input is (*,64,128,128)
                            # nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(128),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(128),
                            nn.ReLU(inplace=True),
                            nn.MaxPool2d(kernel_size=2, stride=2),
                            # input is (*,128,64,64)
                            # nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(256),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(256),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(256),
                            nn.ReLU(inplace=True),
                            nn.MaxPool2d(kernel_size=2,stride=2),
                            # input is (*,256,32,32)
                            # nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            nn.MaxPool2d(kernel_size=2, stride=2),
                            # input is (*,512,16,16)
                            # nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            # nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding='same'),
                            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=(1, 1)),
                            # nn.BatchNorm2d(512),
                            nn.ReLU(inplace=True),
                            nn.MaxPool2d(kernel_size=2, stride=2),
                            # input is (*,512,8,8)
                            nn.AdaptiveAvgPool2d((7, 7)),
                            nn.Flatten(),
                            nn.Linear(in_features=512*7*7,out_features=4096),
                            nn.ReLU(inplace=True),
                            nn.Dropout(0.5),
                            nn.Linear(in_features=4096,out_features=4096),
                            nn.ReLU(inplace=True),
                            nn.Dropout(0.5),
                            nn.Linear(in_features=4096,out_features=8)

        )
        # 构建GLCM特征提取分类网络
        self.feature_output = nn.Sequential(

                             nn.Linear(in_features=25,out_features=8),
                             nn.ReLU(),
                             nn.Linear(in_features=8,out_features=4),
                             # nn.ReLU(),

        )
        # 构建整合网络
        self.model = nn.Sequential(

                     nn.Linear(in_features=12,out_features=8),
                     nn.ReLU(),
                     nn.Linear(in_features=8,out_features=2),
                  )
    # 前向传播
    def forward(self,train_extr_features,imgs):

        img_output = self.img_output(imgs)
        feature= self.feature_output(train_extr_features)
        concat = torch.cat([feature,img_output],dim=1)
        return self.model(concat)
  • 🌹self.img_output是一个VGG16的CNN网络,用于提取原数据的特征进行前向传播,得到各个神经元的激活值,也就是 原始数据的各个特征值。
  • 🌹self.feature_output是一个线性分类器,是用GLCM从源数据中提取的特征,是一个大小为25的向量(通过1.3代码可知),然后投入线性分类器做与上述一样的操作。
  • 🌹最后将两者得到的特征值进行合并,传入最后一个融合网络,得到输出层最终的预测结果,用于反向传播,权重更新等进行网络训练。

三、实验结果👑

3.1 GLCM+CNN🎈

3.1.1 前10个epoch🥒

小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN,# sklearn,图像处理,# 图像分类,cnn,人工智能,神经网络

3.1.2 后10个epoch🥒

小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN,# sklearn,图像处理,# 图像分类,cnn,人工智能,神经网络

3.2 CNN🎈

哎呀,实验的时候忘记加验证集了,反正最后结果是valid Accuracy:93.012几来着,哈哈,尴尬了这就,写到这里才发现,,ԾㅂԾ,,文章来源地址https://www.toymoban.com/news/detail-629103.html

到了这里,关于小成本大幅度增幅CNN鲁棒性,完美的结合GLCM+CNN的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习鲁棒性笔记

    鲁棒性(Robustness)在统计学和数据分析中是一个重要的概念。它指的是某个统计方法或模型对于异常值或偏离数据集正常分布的情况的敏感程度。一个鲁棒性较好的方法能够在存在异常值或数据分布不符合假设的情况下依然给出可靠的结果,而不会被极端值影响太大。 鲁棒

    2024年02月14日
    浏览(38)
  • 脆弱性-鲁棒性-反脆弱性

    哈喽大家好,我是咸鱼   在开始本篇文章之前,我想先问小伙伴们一个问题:   每个人都渴望稳定且有序的生活,但如果一个人的生活过于稳定有秩序且可预测,会有什么不好的影响吗?   如果你每天做同样的事情,都按照同样的方式来度过,一旦出现不可预测的变故,你

    2024年02月16日
    浏览(36)
  • 图像鲁棒性--常见14种图像攻击matlab实现

    一、14种图像攻击 ( a )JPEG压缩。质量因子Q分别为10%、30%、50%、70%、90%。 ( b )高斯噪声。平均μ为0,方差σ分别为0.001、0.005和0.1。 ( c )椒盐噪音。平均μ为0,方差σ分别为0.001、0.005、0.1。 ( d )散斑噪声。平均μ为0,方差σ分别为0.01、0.05、0.1。 ( e )平均滤波。窗口大小分别为3

    2024年02月05日
    浏览(39)
  • 手机类目知识图谱的对抗学习与鲁棒性

    手机类目知识图谱的对抗学习与鲁棒性 作者:禅与计算机程序设计艺术 在电子商务行业,构建高质量的产品类目知识图谱对于提升搜索体验、推荐系统和供应链管理等关键业务至关重要。然而,由于类目信息的复杂性、动态性和噪声干扰,如何构建鲁棒、准确的知识图谱一直是

    2024年04月15日
    浏览(44)
  • 利用AI技术提高智能家庭的安全和鲁棒性

    作者:禅与计算机程序设计艺术 随着人们生活节奏的加快、信息化程度的提升、数字化、物联网等新技术的应用,传统的日常生活已经发生了翻天覆地的变化。而智能家居产品也正在受到越来越多人的青睐。然而,在这个日益开放的世界里,人们对安全和隐私保护的关注程度

    2024年02月06日
    浏览(49)
  • 深度学习中的鲁棒性和泛化性有什么区别

    鲁棒性(Robustness)和泛化性(Generalization)是评估模型性能时常用的两个术语,尤其在机器学习和统计建模领域。虽然这两个概念相关,但它们关注的方面有所不同。 鲁棒性 鲁棒性指的是模型在面对输入数据的小幅变动或存在噪声时仍能保持性能不受显著影响的能力。一个

    2024年02月21日
    浏览(42)
  • TransFusion:利用 Transformer 进行鲁棒性融合来进行 3D 目标检测

    Input-dependent 以往 Query 位置是随机生成或学习作为网络参数的,而与输入数据无关,因此需要额外的阶段(解码器层)来学习模型向真实对象中心移动的过程。 论文提出了一种基于center heatmap 的 input-dependent 初始化策略。(decoder :6 layers — 1 layer) 给定一个 d d d 维的 LiDAR

    2024年02月11日
    浏览(55)
  • 【从零开始数学建模(3)】敏感性和鲁棒性分析例

    敏感性与强健(鲁棒)性          灵敏度分析 是研究与分析一个系统(或模型)的状态或输出变化对系统参数或周围条件变化的敏感程度的方法。在最优化方法中经常利用灵敏度分析来研究原始数据不准确或发生变化时最优解的稳定性。通过灵敏度分析还可以决定哪些参

    2024年02月04日
    浏览(52)
  • MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性

      💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 ​ 主

    2024年02月10日
    浏览(52)
  • 用AI技术提高智能安防摄像头的鲁棒性和安全性

    作者:禅与计算机程序设计艺术 随着人工智能技术的飞速发展,智能安防摄像头作为其应用场景之一,得到了越来越广泛的应用。然而,智能安防摄像头在面临各种挑战时,如图像识别、目标检测、运动跟踪等,依然存在许多的鲁棒性和安全性问题。为了解决这些问题,本文

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包