传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)

代码以及视频讲解

本文所涉及所有资源均在传知代码平台可获取

论文链接:https://www.sciencedirect.com/science/article/abs/pii/S1076633223003537?__cf_chl_rt_tk=J9Aipfxyk5d.leu48P20ePFNd4B2aunaSmzVpXCg.7g-1721292386-0.0.1.1-6249

论文概述

在这里插入图片描述

今天我们把视线转回到AI应用的另外一个大领域——智慧医疗,来看看目前人工智能在这一领域的最新进展。

发表在影像学经典期刊《Academic Radiology》上的论文《Development and Validation of a Feature-Based Broad-Learning System for Opportunistic Osteoporosis Screening Using Lumbar Spine Radiographs》第一次阐述了在智慧医疗领域,纹理特征和卷积特征对于医学影像信息的抽取功能有什么差异,并给出了具体实验验证和指标分析。

作者指出,“宽度学习系统(BLS)的主要优势之一是其简单的平面结构,这使得学习特征表示和分类数据变得容易。与具有复杂架构的其他机器学习算法不同,BLS 具有简洁的设计,便于特征表示学习和数据分类。这种简单的结构还使得模型能够在大数据集上高效运行,而不需要大量的计算资源。BLS 模型的另一个优势是其权重通过解析计算确定,从而降低了过拟合的风险。就基于纹理特征(RF)的 BLS 模型而言,它产生的结果比基于深度卷积特征(DF) 的 BLS 模型更容易解释。原因是 RF 与 BMD 高度相关,这使得理解输入特征与输出之间的关系变得更容易。DF 可以捕捉高级语义信息,这对于某些类型的数据可能是有益的。然而,在这种情况下,基于 RF 的 BLS 模型的分类性能高于基于 DF 的 BLS 模型,表明 RF 更适合这个特定任务。输入特征的选择,例如 RF 或 DF,会影响结果的可解释性和准确性,在开发 BLS 模型时应谨慎考虑。”

纹理特征和深度卷积特征

在这里插入图片描述

  • 纹理特征是图像处理和计算机视觉中常用的概念,用于描述图像中像素的局部模式和结构,帮助区分不同类型的物体或场景。常见的纹理特征包括统计特征、频域特征、模型特征和结构特征。统计特征如灰度共生矩阵(GLCM)和局部二值模式(LBP),通过计算像素间的联合概率分布和局部二进制模式来描述纹理。频域特征如傅里叶变换和小波变换,通过分析图像的频率成分和多尺度细节来捕捉纹理信息。模型特征如自回归模型(AR),假设像素值可以用其周围像素的线性组合来表示,从而描述纹理。结构特征如边缘方向直方图(HOG)和Gabor滤波器,通过计算图像中局部梯度方向分布和使用一组不同方向和尺度的滤波器来提取纹理特征。这些纹理特征在图像分割、分类、模式识别和检索等应用中非常重要,例如在医学图像分析中可以检测和分类不同类型的组织,在遥感图像处理中可以区分不同类型的地表覆盖。

  • 深度卷积特征是由深度卷积神经网络(CNN)提取的特征,用于图像处理和计算机视觉任务。CNN通过多个卷积层、池化层和全连接层的级联,能够从原始图像中自动学习并提取出层次化的特征表示。在CNN中,低层的卷积层通常提取图像中的边缘、纹理和简单形状等低级特征;随着网络的加深,中间层会捕捉到更复杂的模式和结构,如角点、轮廓和局部区域;高层的卷积层则能够提取到语义级别的特征,如物体的类别和具体形状等高级特征。通过这种层次化的特征提取,CNN能够在图像分类、目标检测、图像分割等任务中取得显著的效果。卷积操作通过滑动窗口的方式,将滤波器(卷积核)应用于输入图像,生成特征图。每个卷积核能够检测特定的特征模式,如边缘或纹理。池化层则通过下采样操作,减小特征图的尺寸,从而降低计算复杂度并提高模型的鲁棒性。深度卷积特征的一个重要优势是它们能够自动从大量标注数据中学习特征表示,而无需人工设计特征。这使得深度学习模型能够在各种复杂的视觉任务中表现出色。此外,预训练的深度卷积网络(如VGG、ResNet、Inception等)可以用于迁移学习,通过在新的任务上进行微调,迅速适应不同的应用场景。总之,深度卷积特征在现代计算机视觉领域具有重要的地位,广泛应用于图像分类、目标检测、图像分割、图像生成等多种任务中,显著提升了这些任务的性能和准确性。

算法流程

在这里插入图片描述

下面我们来介绍一下论文中所设计的算法流程,原论文采用了两种不同方面的特征提取技术——纹理特征和深度卷积特征,并比较了他们的性能效果。对于纹理特征,论文采用了GLCM、GLRLM、GLDM、GLSZM、NGTDM和一阶形态学特征融合提取的方法来全面地提取到医学影像中的纹理信息。对于深度卷积特征,论文中使用了最经典的ResNet18和VGG11两种深度卷积网络来对医学影像进行特征提取。

下面我们将具体地讲解这篇文章所用到的数据预处理方法,纹理特征提取、深度卷积特征提取和分类网络搭建这四个步骤

数据预处理方法

首先,感兴趣区域(ROIs)在L1-L4椎体(前后视图)上手动分割,以确保诊断模型与DXA测试之间的准确对应。该操作使用开源软件ITK-SNAP (www.itk-snap.org)进行。分割由一位具有6年肌肉骨骼影像经验的放射科医生完成,并由一位具有20年肌肉骨骼影像经验的高级放射科医生验证。阅片者对患者的临床信息和DXA结果均不知情。

为了规范化,ROI图块被转换为灰度图像,并使用双线性插值方法调整为128 × 64像素。这种方法在图像处理应用中常用,因为它在计算效率和图像质量之间提供了一种折衷。使用对比度受限自适应直方图均衡化(CLAHE)对图像进行增强,以提高对比度并提供更清晰的特征细节可视化。CLAHE在增强医学图像方面具有优势,因为它不会增加噪声,并能保留大部分图像纹理细节。使用定量度量结构相似性指数(SSIM)评估CLAHE的效率。在训练集中的直方图均衡化后,SSIM方差显著降低(0.00102 vs. 0.00056,P < .0001),在测试集中也是如此(0.00196 vs. 0.00102,P < .0001)。图2展示了原始和增强的ROI图像及其灰度直方图。

为了处理数据集样本分布不均的问题,使用了合成少数过采样技术(SMOTE)。SMOTE分析少数样本,根据少数样本人工合成额外样本,并将其添加到数据集中,以防止模型学到的知识过于专门化而缺乏广泛性。

纹理特征提取

论文作者们利用PyRadiomics 3.0 从每个感兴趣区域(ROI)中提取二维形态特征和纹理特征。形态特征包括网格表面、像素表面、周长、周长与表面比、球形度、球形不对称、长轴长度、短轴长度和伸长率。纹理特征包括灰度共生矩阵(n = 24)、灰度游程长度矩阵(n = 16)、灰度尺寸区矩阵(n = 16)、相邻灰度差矩阵(n = 5)和灰度依赖矩阵(n = 14)。这些特征与多种骨骼特性有关,包括骨密度(BMD)、骨微观结构和骨组织成分。形态特征和纹理特征的计算和提取是根据图像生物标记标准化倡议(Image Biomarker Standardisation Initiative)指南进行的,以确保一致性和标准化。

深度卷积特征提取

他们使用了两种广泛应用的卷积神经网络(CNN)架构,即ResNet18和VGG11,作为任务的骨干网络。ResNet18由四个残差块组成,每个残差块包含两个卷积层,配有批量归一化和ReLU激活函数。这些层之后是一个快捷连接,将输入添加到第二个卷积层的输出中。而VGG11的特点是其架构中一致使用小的3×3卷积滤波器,这种方法确保了较大的感受野,同时保持了相对较少的参数。VGG11架构由五个堆叠的卷积层组成,称为“vggblocks”,并使用ReLU激活函数。它采用最大池化,并以几层全连接层结束。

他们利用了预训练CNN与迁移学习的强大功能,有效地从图像数据中生成并提取准确且富有表现力的特征。具体来说,他们使用了已经在ImageNet数据集上预训练的ResNet18和VGG11模型。在特征提取过程中,他们冻结了大部分卷积模块,并添加了新的展平和全连接层,以获得所需的特征维度。具体来说,对于VGG11,他们选择并冻结了五个vggblocks。随后,添加了自适应平均池化层和全连接层,以获得4096维的特征表示。对于ResNet18,他们冻结了前四层,每层包含两个Basicblock模块,并添加了自适应平均池化层,以实现512维的特征表示。

分类网络搭建

在这里插入图片描述

BLS基于随机向量功能连接神经网络和伪逆理论设计,使其能够快速、增量地学习,并且无需重新训练即可重构系统。BLS模型(如图所示)由输入层、特征和增强节点复合层以及输出层组成。在复合层中,使用不同组的随机权重从输入数据生成多个映射特征组,形成特征节点。此外,特征节点被增强为增强节点,每个增强节点使用不同的随机权重生成。输出是通过所有连接到输出层的特征节点和增强节点计算得出的。

BLS的一个显著优势是训练和输出结果所需的时间非常少。由于采用伪逆理论,输出层的权重可以通过简单的矩阵运算与上一层的数据进行快速计算和更新。RF和DF被用作BLS模型的输入,用于图像分类。

代码复现

本文的复现代码我放在了附件当中,大家可以自行下载下来进行对比实验。下面我将结合伪代码流程图对代码的逻辑进行简单地讲解

BLS_Model.py文件——分类器搭建

1. 初始化必要的库和函数- numpy, sklearn.preprocessing, numpy.random, scipy.linalg, time, sklearn.metrics- 函数: show_accuracy, tansig, sigmoid, linear, tanh, relu, pinv, shrinkage, sparse_bls2. 定义函数 show_accuracy- 输入: predictLabel, Label- 计算正确预测的数量- 使用混淆矩阵计算灵敏度(Sen), 特异度(Spe), 阴性预测值(npv), 阳性预测值(ppv), AUC- 返回: 准确率, Sen, Spe, npv, ppv, auc, 预测标签, 实际标签3. 定义激活函数 tansig, sigmoid, linear, tanh, relu4. 定义函数 pinv- 输入: A, reg- 计算伪逆矩阵- 返回: 伪逆矩阵5. 定义函数 shrinkage- 输入: a, b- 计算收缩结果- 返回: z6. 定义函数 sparse_bls- 输入: A, b- 设置参数 lam, itrs- 初始化变量- 迭代计算稀疏BLS- 返回: wk7. 定义函数 BLS_AddFeatureEnhanceNodes- 输入: train_x, train_y, test_x, test_y, N1, N2, N3, L, M1, s, c, M2, M3- 初始化变量 u, train_x, FeatureOfInputDataWithBias, OutputOfFeatureMappingLayer, Beta1OfEachWindow, distOfMaxAndMin, minOfEachWindow, train_acc, test_acc, train_time, test_time- 记录开始时间 time_start- 对每个窗口进行以下操作:- 生成随机权重- 计算窗口特征- 预处理特征- 计算稀疏BLS- 计算窗口输出- 记录最大最小值- 规范化窗口输出- 更新输出特征映射层- 生成增强层输入- 计算增强层权重- 计算增强层输出- 计算输出层输入- 计算输出权重- 记录结束时间 time_end- 计算训练时间 trainTime- 计算训练输出- 调用 show_accuracy 计算训练准确率等- 记录训练准确率和时间- 对测试数据进行同样的处理- 记录结束时间 time_end- 计算测试时间 testTime- 计算测试输出- 调用 show_accuracy 计算测试准确率等- 记录测试准确率和时间- 返回: testAcc, trainAcc, Sentr, Spetr, npvtr, ppvtr, auctr, Sen, Spe, npv, ppv, auc, predtt, labeltt, predtr, labeltr

在BLS_Model.py文件中,我实现了基于随机向量功能连接神经网络和伪逆理论的快速增量学习方法。代码首先导入必要的库和函数,包括用于数据预处理、矩阵运算、时间测量和模型评估的库。定义了一些辅助函数,例如激活函数(tansig、sigmoid、linear、tanh、relu),用于计算伪逆矩阵的函数(pinv),以及用于稀疏BLS计算的函数(sparse_bls)。主要的函数是BLS_AddFeatureEnhanceNodes,它实现了BLS模型的训练和测试。首先对输入数据进行预处理,将其标准化并添加偏置项。然后,在特征映射层中,使用不同组的随机权重生成多个映射特征组,形成特征节点,并通过稀疏BLS方法计算每个窗口的权重和输出。接着,在增强层中,生成增强节点,并计算其输出。在输出层中,结合特征映射层和增强层的输出,计算输出权重。训练阶段,记录训练时间,并计算训练输出,通过show_accuracy函数评估模型的训练准确率、灵敏度、特异度、阴性预测值、阳性预测值和AUC。同样地,在测试阶段,对测试数据进行同样的处理,记录测试时间,并评估模型的测试性能。最终,返回测试准确率、训练准确率及其他评估指标。整个过程旨在通过快速、增量地学习,从输入数据中提取特征,并通过简单的矩阵运算进行模型的更新和评估。

pyradioextraction.py文件——纹理特征提取

1. 导入必要的库和模块
2. 定义函数 listdirInMac:a. 初始化空列表 listsb. 遍历输入列表 list:i. 如果项的第一个字符是 '.',跳过该项ii. 否则,将该项添加到 listsc. 返回 lists3. 定义函数 catch_features:a. 检查 imagePath 或 maskPath 是否为空:i. 如果为空,抛出异常b. 初始化 settings 字典并设置提取参数c. 创建 RadiomicsFeatureExtractor 实例 extractor,传入 settingsd. 禁用所有特征e. 启用所需的特征类别(shape2D, glcm, glszm, glrlm, ngtdm, gldm)f. 执行特征提取并获取结果 resultg. 初始化空列表 feature_names 和 feature_valuesh. 遍历 result 中的每个键值对:i. 如果键匹配特定的特征类别,打印键和值,将键和值添加到相应的列表i. 打印特征维度和特征名称j. 返回 feature_values 和 feature_names4. 在 main 函数中:a. 定义 image_dir 和 mask_dir 的路径b. 获取患者列表 patient_list 并使用 listdirInMac 函数过滤c. 对 patient_list 进行排序d. 初始化空列表 all_data 和 all_namee. 遍历 patient_list 中的每个患者:i. 打印患者名称ii. 遍历患者文件夹中的每个文件:- 如果文件名是 'data.nii.gz',设置 imagePath- 如果文件名是 'zw.nii.gz',设置 maskPathiii. 调用 catch_features 函数提取特征,并保存结果到 all_data,特征名称保存到 all_namef. 打印所有数据和特征名称g. 打开 CSV 文件进行写入:i. 写入列名(特征名称)ii. 写入每行特征数据

这段代码的目的是从医学图像中提取纹理特征。首先,代码导入了一些必要的库和模块,包括用于处理图像的SimpleITK和用于特征提取的pyradiomics。定义了一个函数listdirInMac来过滤掉隐藏文件。主函数catch_features接受图像和掩码的路径,使用特定的设置来初始化一个特征提取器,并提取2D形状特征、灰度共生矩阵(GLCM)、灰度大小区域矩阵(GLSZM)、灰度运行长度矩阵(GLRLM)、灰度依赖矩阵(GLDM)和邻域灰度差矩阵(NGTDM)的特征。这些特征被保存为名称和值,并返回给主程序。

主程序首先定义了图像目录和掩码目录的路径,并获取患者列表。对于每个患者,找到相应的图像和掩码文件路径,并调用catch_features函数提取特征。所有提取的特征被保存到一个CSV文件中,方便后续分析和处理。

这个过程通过一系列的步骤和函数调用,实现了从医学图像中自动提取纹理特征并保存到文件中,便于后续的分析和研究。

CNNextraction.py 文件——深度卷积特征提取

1. 导入必要的库和模块- urllib- torch- matplotlib.pyplot as plt- torch.nn as nn- torchvision.models- torchvision.transforms- numpy as np- cv2- os- ssl- PIL.Image- scipy.io as scio- urllib3.util.url2. 设置 HTTPS 上下文3. 定义函数 listdirInMac:a. 初始化空列表 listsb. 遍历输入列表 list:i. 如果项的第一个字符是 '.',跳过该项ii. 否则,将该项添加到 listsc. 返回 lists4. 定义类 FeatureExtractor (继承自 nn.Module):a. 初始化方法:i. 提取 VGG-16 特征层并将其设置为 nn.Sequentialii. 提取 VGG-16 的平均池化层iii. 转换图像为一维向量iv. 提取 VGG-16 全连接层的第一部分v. 添加新的全连接层(fc2)b. 前向传播方法:i. 通过特征层提取特征ii. 通过池化层提取特征iii. 打印特征的形状iv. 转换张量为 numpy 数组并重塑v. 使用 matplotlib 显示特征图vi. 返回提取的特征5. 定义类 FeaExtractor (继承自 nn.Module):a. 初始化方法:i. 提取模型的卷积层、批量归一化层、激活函数、最大池化层和自适应平均池化层ii. 提取模型的各个层iii. 转换图像为一维向量b. 前向传播方法:i. 通过各个层提取特征ii. 转换张量为 numpy 数组并重塑iii. 使用 matplotlib 显示特征图iv. 返回提取的特征6. 加载预训练的 EfficientNet 模型
7. 替换 EfficientNet 的第一个卷积层
8. 将模型移动到 GPU
9. 定义图像预处理步骤10. 定义函数 extract:a. 初始化空列表 featuresb. 获取并过滤路径中的文件列表c. 对文件列表进行排序d. 遍历文件列表:i. 加载并预处理每个图像ii. 将图像合并为一个批次并添加一个维度iii. 将图像移动到 GPUiv. 禁用梯度计算并提取特征v. 将提取的特征转换为 numpy 数组并保存到 features 列表e. 将特征转换为 numpy 数组并返回11. 如果是主程序:a. 设置训练数据路径

在这段代码中,我使用预训练的ResNet模型提取图像特征并保存到MAT文件中。首先,导入了必要的库,包括PyTorch、PIL、Matplotlib等,并设置了HTTPS上下文以跳过SSL验证。定义了辅助函数listdirInMac,用于过滤目录列表,去掉以’.'开头的隐藏文件或目录。定义了特征提取器类FeatureExtractor,继承自nn.Module,用于从ResNet模型中提取特征。初始化方法中提取了ResNet的特征层、平均池化层,并添加了一个新的全连接层。在前向传播方法中,通过特征层和池化层提取特征,并使用Matplotlib显示特征图。代码还定义了另一个特征提取器类FeaExtractor,未被使用,其作用类似于FeatureExtractor。

然后,代码使用torchvision.models加载预训练的ResNet模型,并将其移动到GPU,同时定义了一系列图像预处理步骤。接着,定义了特征提取函数extract,该函数初始化一个空列表用于存储特征,获取图像目录中的文件列表并进行排序,遍历文件列表,加载并预处理每张图像,将预处理后的图像合并为一个批次,移动到GPU,并使用新定义的模型提取特征,最后将提取到的特征保存到MAT文件中。

main.py——顶层文件

开始
|
|-- 函数: Texture_preparation()
|   |
|   |-- 从 "train_dataset_smote_84.mat" 加载 train_data
|   |-- 打印 train_data 的形状
|   |-- 从 "test_features.mat" 加载 test1_data
|   |-- 打印 test1_data 的形状
|   |-- 从 "train_dataset_smote_84.mat" 加载 train_label
|   |-- 打印 train_label 的形状
|   |-- 从 "test1_flag.mat" 加载 test1_label
|   |-- 删除 test1_label 中的特定行
|   |-- 打印 test1_label 的形状
|   |-- 返回 train_data, train_label, test1_data, test1_label
| 
|-- 主块||-- 定义参数: N1, N2, N3, L, M1, s, c, M2, M3||-- 调用 Texture_preparation() 并将返回值赋给 train_data, train_label, test1_data, test1_label||-- 打印 test1_data|-- 打印 test1_label||-- 调用 BLS_AddFeatureEnhanceNodes() 并将返回值赋给各个指标变量||-- 打印测试和训练的准确率及其他指标
|
结束

这个文件起到了一个集成的作用,用于将不同的特征数据加载到内存环境中,并输入到BLS分类器中进行对比实验,从而分析不同特征对医学影像信息的提取性能。

实验结果

在本次实验中,由于原论文的数据涉及病人隐私无法公开,因此我使用了同样类型的医学公开数据集进行实验,链接如下:https://data.mendeley.com/datasets/fxjm8fb6mw

在这里插入图片描述

如图所示,我们按照论文步骤,将三种不同类型的特征分别输入到BLS分类器中进行性能的对比实验,可以得到与论文中一致的结果。在到达相似的训练程度时,输入纹理特征的模型相比其他两种特征模型能够在各项指标上取得更好的结果。特别是在医疗领域最为关注的曲线下面积(AUC)这一项中,该模型拉开了比较大的差距。因此我们可以推测出,在基于纹理特征(RF)的BLS模型与基于深度卷积特征(DF)的BLS模型的对比中,前者的结果更容易解释。这是因为RF与BMD高度相关,使得理解输入特征与输出结果之间的关系更加直观。尽管DF可以捕捉高级语义信息,在某些数据类型中可能更有利,但在这个特定任务中,基于RF的BLS模型的分类性能优于基于DF的BLS模型,表明RF在此任务中更为适用。

论文中结果:
在这里插入图片描述
在这里插入图片描述

使用方式

下面我们来介绍一下如何使用附件代码来进行运行三种不同的特征模型。文件格式如下所示:

在这里插入图片描述

一键运行

前面已经为大家介绍了各个文件的功能,这里需要注意的,为了便于理解,我将main.py文件拆分成了三个文件BLS_ResnetFeatures.py、BLS_TextureFeatures.py和BLS_VGGFeatures.py,分别代表了三种不同的特征输入BLS分类器进行实验。在这里为了方便大家一键运行,我已经将原始数据进行处理好,三种类型的特征分别存入了CNNFeatures(Resnet特征)、TextureFeatures(纹理特征)和VGGFeatures(VGG特征)文件夹中。大家进入对应的主文件中就可以一键运行实验。

本地训练

如果大家还希望能使用自己的私人数据集进行训练,可以按照我前面所说的算法步骤进行一步步地处理。使用pyradioextraction.py文件可以直接对医学影像数据进行纹理特征的提取,使用CNNextraction.py可以对转换后的医学图像进行两种深度卷积特征的提取。

提取纹理特征时注意要在pyradioextraction.py文件中修改对应的文件路径
在这里插入图片描述

提取深度卷积特征时同样要注意文件保存路径问题
在这里插入图片描述

处理结束后就可以看到在目录下会生成相应的文件,接下来输入到BLS分类器中就可以进行训练了!

环境配置

  • python版本3.6及以上;
  • 预先安装第三方库:radiomics、SimpleITK、torch、torchvision和scipy

源码下载

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

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

相关文章

第8集《大佛顶首楞严经》

请大家打开《讲义》第十六页。 辛四、破转计见内。分二&#xff1a;壬一、转计。壬二、破斥。 古德说&#xff1a;不识本心&#xff0c;修法无益。我们的法门有很多选择&#xff0c;你可以去拜佛&#xff0c;你可以去念佛&#xff0c;你可以去持咒。但是从《楞严经》的角度来…

mac如何清理dns缓存 macbook清除dns缓存命令 苹果清理内存软件 为什么需要清除DNS缓存数据

在Mac操作系统中&#xff0c;清除DNS缓存可以帮助解决一些与域名解析有关的问题&#xff0c;例如访问速度慢、网站无法打开等。当遇到网络无法访问互联网等故障时有些用户不知道怎么清理DNS缓存&#xff0c;不清楚苹果mac清理内存怎么清理。接下来就给大家介绍一下Mac电脑清理d…

游泳耳机品牌哪个牌子好?四大高热度游泳耳机综合分析

近年来&#xff0c;游泳耳机的受欢迎程度呈指数级增长&#xff0c;市场热度不断攀升。但作为一名长期关注运动科技的专业人士&#xff0c;我必须提醒大家&#xff0c;在享受水下音乐的同时&#xff0c;也要注意选择专业可靠的产品。市面上许多所谓的“游泳耳机”其实缺乏必要的…

力扣 27移除元素

思路&#xff1a; 题目需要在原数组的基础上&#xff0c;移除等于val的元素&#xff0c;并返回数组移除后的元素数 用双指针遍历&#xff0c;for循环遍历&#xff0c;fast先行 如果当前元素等于val&#xff0c;fast自增是写在for循环中的,slow不变 如果不等&#xff0c;fas…

《Java初阶数据结构》----6.<优先级队列之PriorityQueue底层:堆>

前言 大家好&#xff0c;我目前在学习java。之前也学了一段时间&#xff0c;但是没有发布博客。时间过的真的很快。我会利用好这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…

08 capture软件新建原理图 09 原理图添加元器件 10 原理图信号连通 11 原理图电源和地连通

08 capture软件新建原理图 && 09 原理图添加元器件 && 10 原理图信号连通 && 11 原理图电源和地连通 第一部分 08 capture软件新建原理图第二部分 09 原理图添加元器件第三部分 10 原理图信号连通第四部分 11 原理图电源和地连通 第一部分 08 capture软…

C#---23:Virtual、abstract、Interface的区别 混合使用的案例

文章目录 1. virtual & abstract & interface 的区别(1)virtual 修饰的方法(2)abstract修饰的方法(3)interface修饰的方法 2. 一个class继承多个interface 的应用3. 一个class继承一个class和多个interface4. abstract作为中间介质&#xff08;将不同的人以及不同的坦克…

备份软件维护之NETBACKUP NBU知多少

一、基本介绍 NetBackup (NBU) 是一款企业级的数据备份和恢复软件&#xff0c;‌由Symantec公司开发&#xff0c;‌旨在为异构平台提供全面的数据保护。‌ 它支持从远程办公室到数据中心的各种环境&#xff0c;‌包括UNIX、‌Windows、‌Linux和NetWare等操作系统&#xff0c;…

算法-KMP字符串匹配

题目一 解题思路 KMP算法详解 详解next数组 next[i] 就是使子串 s[0…i] 有最长相等前后缀的前缀的最后一位的下标。 总体来说解next数组和模板串匹配的过程很相似&#xff0c;触类旁通 代码模板 #include<iostream> using namespace std; const int N1e510; char …

JavaScript中bind、apply、call的理解

bind、apply、call是什么&#xff1f; bind、apply、call是Function原型的方法&#xff0c;而在js中所有的函数都是Function的实例&#xff0c;所以&#xff0c;有所有函数都可以使用这三个方法。 bind、apply、call有什么作用&#xff1f; 改变this指向 &#xff0c;这是它们…

单元测试--Junit

Junit是Java的单元测试框架提供了一些注解方便我们进行单元测试 1. 常用注解 常用注解&#xff1a; TestBeforeAll&#xff0c;AfterAllBeforeEach&#xff0c;AfterEach 使用这些注解需要先引入依赖&#xff1a; <dependency><groupId>org.junit.jupiter<…

[IMX6ULL]移植NXP Linux Kernel 5.15

移植NXP Linux Kernel 5.15 2024-7-7 hongxi.zhu 1. 下载NXP Linux Kernel 5.15 仓库[nxp-imx/linux-imx] git clone -b lf-5.15.y https://github.com/nxp-imx/linux-imx.git 2. 编译NXP Linux Kernel 5.15 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distclean make…

C++树形结构(1 基础)

目录 一.基础&#xff1a; 1.概念&#xff1a; 2.定义&#xff1a; Ⅰ.树的相关基础术语&#xff1a; Ⅱ.树的层次&#xff1a; 3.树的性质&#xff1a; 二.存储思路&#xff1a; 1.结构体存储&#xff1a; 2.数组存储&#xff1a; 三.树的遍历模板&#xff1a; 四.信…

Mysql-索引结构

一.什么是索引&#xff1f; 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引 二.无索引的情况 找到…

SpringBoot集成Kaptcha验证码

Hi &#x1f44b;, Im shy 有人见尘埃&#xff0c;有人见星辰 1. 什么是Kaptcha验证码? Kaptcha是一个强大的开源Java验证码生成库,由Google开发。它能够生成高度可配置的图片验证码,主要用于防止自动化程序滥用web应用,提高应用的安全性。 2. Kaptcha的主要特性 Kaptch…

3.3-LSTM的改进

文章目录 1改进点1.1多层化1.2 dropout1.2.1具体概念1.2.2应该插入到LSTM模型的哪里 1.3权重共享 2改进之后的LSTMLM的代码实现2.1初始化2.2前向计算2.3反向传播 3相应的学习代码的实现4总结 1改进点 1.1多层化 加深神经网络的层数往往能够学习更复杂的模式&#xff1b;因此这…

AI学习记录 - 图像识别的基础入门

代码实现&#xff0c;图像识别入门其实非常简单&#xff0c;这里使用的是js&#xff0c;其实就是把二维数组进行公式化处理&#xff0c;处理方式如上图&#xff0c;不同的公式代表的不同的意义&#xff0c;这些意义网上其实非常多&#xff0c;这里就不细讲了。 const getSpecif…

vue-快速入门

Vue 前端体系、前后端分离 1、概述 1.1、简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;可以高效地开发用户界面。…

C语言 之 理解指针(4)

文章目录 1. 字符指针变量2. 数组指针变量2.1 对数组指针变量的理解2.2 数组指针变量的初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用 5. 函数指针数组 1. 字符指针变量 我们在前面使用的主要是整形指针变量&#xff0c;现在要学…

C++入门基础:C++中的循环语句

循环语句是编程语言中用来重复执行一段代码直到满足特定条件的一种控制结构。它们对于处理需要重复任务的场景非常有用&#xff0c;比如遍历数组、累加数值、重复执行某项操作直到满足条件等。 但是在使用循环语句的时候需要注意下哈&#xff0c;有时候一不小心会构成死循环或者…