在进行深度图像处理时最重要的一步往往是图像特征提取检测,尤其是样本特征较少时,接下来我们以人脸识别之舌头识别为例,来讲解一下少数据样本时常用的五种图像数据特征提取的方法。
在构建舌头识别模型时,当样本数据量较少的情况下,实现舌象/面象特征提取检测是关键的第一步。接下来,我们将详细介绍各种实用的方法。
一、传统图像处理方法
(一)适用场景
适用于数据量少且暂时不需要深度学习技术的场景。其原理是直接运用图像处理技术,提取那些肉眼可直观看到的显性特征。例如,在初步探索舌象特征时,利用这种方法能快速获取一些基本信息。
(二)常用方法
- 颜色空间转换
- 原理:将基于RGB(红绿蓝)颜色空间的图片,转换到HSV(色调、饱和度、明度)或Lab颜色空间。这是因为在提取舌象颜色特征时,HSV或Lab颜色空间更具优势,能更方便地判断诸如舌苔发黄、发白等颜色特征。
- 代码示例:
python
import cv2
image = cv2.imread("tongue.jpg")
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
在这段代码中,我们使用Python的OpenCV库,读取名为"tongue.jpg"的舌头图片,并将其从BGR(OpenCV中读取的RGB顺序是BGR)颜色空间转换为HSV颜色空间。
-
名词解释:
-
RGB颜色空间:是生活中极为常见的颜色表示方式,通过红(R)、绿(G)、蓝(B)三种颜色通道的数值变化以及相互叠加,从而呈现出各种各样的颜色。我们日常使用的电子屏幕,如电脑、手机屏幕,就是基于RGB原理来显示丰富多彩的画面。
-
HSV颜色空间:这种颜色表示方式更贴合人类的视觉感知。其中,色调(Hue)决定了颜色的类别,像常见的红色、绿色、蓝色等;饱和度(Saturation)体现颜色的鲜艳程度,饱和度越高,颜色越鲜艳夺目,越低则越趋近于灰色;明度(Value)反映颜色的明亮程度,数值越大,颜色越亮,数值越小,颜色越暗。在分析舌象颜色时,HSV空间能够让我们更直观地把握舌苔颜色的变化情况。
-
- 边缘检测与形状分析
- 原理:借助Canny边缘检测算法或者轮廓提取算法,能够识别出舌头的形状,进而判断是胖大舌、齿痕舌等不同类型。
- 代码示例:
python
edges = cv2.Canny(image, threshold1=50, threshold2=150)
此代码运用Canny算法提取图像边缘,threshold1
和threshold2
是两个阈值,用于精准控制边缘检测的精度。
- 名词解释 :
- Canny边缘检测算法:这是一种经典的边缘检测算法,其工作过程较为复杂。首先,使用高斯滤波对图像进行平滑处理,有效去除图像中的噪声干扰;接着,计算图像的梯度强度和方向,以确定可能的边缘位置;然后,进行非极大值抑制操作,将边缘进行细化,使检测出的边缘更加精准;最后,通过双阈值检测和边缘连接,确定最终的清晰边缘。在舌象分析中,Canny算法能够清晰地勾勒出舌头的轮廓,为我们判断舌头的形状提供有力依据。
- 轮廓提取算法:主要用于从图像中准确提取物体的轮廓。它能够找到图像中连续的边界点,这些点依次连接起来就构成了物体的轮廓线。在舌诊领域,通过轮廓提取,我们可以获取舌头的形状信息,从而进一步分析舌头是否存在胖大、齿痕等特征。
- 纹理分析
- 原理:利用灰度共生矩阵(GLCM)或者局部二值模式(LBP)来计算舌苔的粗糙度、是否存在裂纹等纹理特征。
- 代码示例:
python
from skimage.feature import local_binary_pattern
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
lbp = local_binary_pattern(image_gray, P=8, R=1)
这段代码首先使用OpenCV将彩色图像转换为灰度图像,然后借助scikit - image库中的local_binary_pattern
函数计算LBP纹理。其中,P
表示邻域采样点数,R
表示邻域半径。
-
名词解释:
-
灰度共生矩阵(GLCM):是一种用于统计图像中灰度值空间相关性的方法。它通过计算在特定距离和方向上,两个灰度值同时出现的频率,以此来精确描述图像的纹理特征。例如,在分析舌苔时,如果GLCM中的某些参数值较大,这很可能意味着舌苔纹理比较粗糙,存在较多裂纹;而参数值较小,则可能表示舌苔纹理细腻,状态良好。
-
局部二值模式(LBP):是一种专门用于描述图像局部纹理特征的算子。它通过对比中心像素与邻域像素的灰度值,将图像中的每个像素点巧妙地转换为一个二进制数,进而得到图像的LBP特征。在舌诊中,LBP能够有效地提取舌苔表面的细微纹理细节,为判断舌苔的健康状况提供重要参考。
-
(三)优缺点
- 优点:该方法对数据量的需求不大,计算速度较快,并且提取出来的特征具有很强的可解释性,即我们能够很容易理解这些特征所代表的实际意义。
- 缺点:比较依赖人工设计的特征,对于一些复杂的、难以直接观察到的信息,可能会出现遗漏的情况。
二、预训练深度学习模型(迁移学习)
(一)原理
我们借助那些在大规模数据集(如著名的ImageNet,这个数据集中包含了海量的各种图像)上已经训练好的模型,像ResNet、VGG等。这些模型在大量数据的训练过程中,已经学习到了非常丰富的图像深层特征。我们的操作是去掉原模型最后的分类层,保留前面的特征提取层,然后使用我们自己的舌象数据对模型进行微调,使其能够适应舌诊任务的需求。
(二)步骤
-
加载预训练模型:从网络上下载预训练好的模型,并将原模型的最后一层分类层去除。
-
冻结部分层:为了防止在使用我们少量的舌象数据重新训练时出现过拟合的问题,我们将前面几层的参数固定住,使其在训练过程中不发生改变。过拟合是指模型在训练数据上表现得极为出色,能够准确地预测训练数据中的样本,但在新的、未见过的测试数据上却表现很差,这是因为模型过度学习了训练数据中的细节和噪声,而没有真正捕捉到数据的通用规律。
-
提取特征:将舌头图片输入到经过处理的模型中,模型会输出一个高维的特征向量。例如,ResNet模型输出的可能是2048维向量。这里的向量是一种数学概念,在图像处理中,它可以理解为对图像特征的一种数字化、量化的表示方式,向量的每一个维度都代表了图像的某一种特定特征信息。
(三)代码示例(用PyTorch实现)
python
import torch
from torchvision import models
# 加载预训练的ResNet模型
model = models.resnet18(pretrained=True)
model = torch.nn.Sequential(*list(model.children())[:-1])
# 提取特征
image = load_tongue_image()
features = model(image)
在这段代码中,首先加载了预训练的ResNet18模型,然后通过巧妙的操作去掉了最后一层,仅保留前面的特征提取层。接着,假设我们有一个自定义的load_tongue_image
函数,用于加载舌头图片,将加载后的图片输入模型,最终得到图像的特征向量。
(四)名词解释
-
迁移学习:是机器学习领域中的一种重要技术,它的核心思想是将从一个任务中学习到的知识或模型,应用到另一个与之相关的任务中。在构建AI舌诊模型时,我们充分利用在大规模图像数据集上训练好的模型(如ResNet、VGG),这些模型在识别各种图像特征方面已经积累了丰富的经验和良好的基础,我们将其迁移到舌诊任务中,大大减少了从头开始训练模型所需的时间和数据量。
-
预训练模型:是在大规模数据集上经过长时间、大量数据训练得到的模型。例如在ImageNet数据集上训练的ResNet和VGG模型,它们在训练过程中已经学习到了大量通用的图像特征,如边缘、纹理、形状等。我们在实际应用中,可以直接使用这些预训练模型的部分结构,而无需重新训练整个模型,从而节省大量的时间和计算资源。
-
过拟合:是模型训练过程中常见的问题,表现为模型在训练数据上能够完美地拟合,甚至可以记住训练数据中的每一个细节,但在面对新的、未参与训练的测试数据时,却无法准确预测,泛化能力极弱。这是因为模型过度学习了训练数据中的噪声和特殊情况,而没有掌握数据的真正内在规律。在迁移学习中,由于我们使用的是少量的舌象数据进行微调,模型很容易陷入过拟合状态,因此需要冻结部分层来避免这种情况的发生。
(五)优缺点
-
优点:能够自动提取非常复杂的图像特征,对于舌象中颜色、纹理等方面的细微差异都能够敏锐地捕捉到,为后续的分析和诊断提供更丰富、准确的信息。
-
缺点:需要对模型结构进行合理调整,否则在使用少量数据进行训练时,极易出现过拟合情况,导致模型在实际应用中的性能不佳。
三、数据增强
(一)原理
数据增强的核心操作是对现有的图片进行多种变换,包括旋转、翻转、调整颜色等。通过这些变换,生成看似"新"的数据样本。虽然这些新数据本质上还是基于原始数据,但它们从不同角度、不同特性上丰富了数据的多样性,使模型能够学习到更全面的数据特征。
(二)常用增强方法
- 几何变换:包括对图片进行旋转(例如旋转±15° )、水平翻转、裁剪等操作。旋转是按照一定的角度将图像进行转动,改变图像中物体的方向;水平翻转是将图像沿着水平方向进行镜像翻转,类似于照镜子的效果;裁剪则是从图像中选取一部分特定区域,去除其他部分。
- 颜色扰动:主要是调整图片的亮度、对比度、饱和度。亮度是指图像整体的明亮程度,亮度的变化会影响我们对图像细节的观察;对比度是指图像中不同颜色之间的差异程度,对比度高的图像,颜色之间的区分更明显;饱和度是指颜色的鲜艳程度,饱和度高的颜色更加鲜艳夺目,饱和度低则颜色更暗淡。
- 噪声注入:向图片中添加高斯噪声或者进行模糊处理。高斯噪声是一种服从高斯分布的随机噪声,在图像采集过程中,由于各种因素的干扰,经常会出现类似的噪声。添加高斯噪声可以模拟这种实际情况,使模型对噪声更具鲁棒性;模糊处理是通过卷积操作使图像变得模糊,也能够增加数据的多样性,让模型学习到不同清晰度下的图像特征。
(三)代码示例(用PyTorch实现)
python
from torchvision import transforms
augmentation = transforms.Compose([
transforms.RandomRotation(15),
transforms.ColorJitter(brightness=0.2),
transforms.RandomHorizontalFlip(),
])
augmented_image = augmentation(original_image)
这段代码使用torchvision
库中的transforms
模块,定义了一个数据增强的操作序列。首先对原始图片进行随机旋转15°,然后调整亮度0.2,最后进行随机水平翻转,经过这一系列操作后,得到增强后的图片augmented_image
。
(四)名词解释
-
数据增强:是一种在深度学习中广泛应用的技术,其目的是通过对原始数据进行各种变换,生成新的数据样本,从而扩充数据集的规模和多样性。在数据量有限的情况下,数据增强能够有效地提高模型的泛化能力,减少模型对特定数据的过拟合风险,使模型在面对各种不同的数据时都能表现出较好的性能。
-
几何变换:在数学和计算机图形学领域,几何变换是指对几何对象(如图像、形状)进行位置、方向、大小等方面的改变。在数据增强中,常用的几何变换包括旋转、翻转、平移、缩放等。这些变换可以改变图像中物体的位置、方向和大小,从而增加数据的多样性,让模型学习到不同角度和尺度下的图像特征。
-
颜色扰动:是对图像的颜色属性进行调整的操作,主要包括亮度、对比度、饱和度和色调等方面的改变。颜色扰动可以模拟不同光照条件、拍摄设备差异等因素对图像颜色的影响,使模型能够学习到更鲁棒的颜色特征,提高模型在不同环境下的适应性。
-
噪声注入:是指向图像中添加随机噪声的操作,其目的是模拟真实世界中图像采集过程中可能出现的噪声干扰。常见的噪声类型包括高斯噪声、椒盐噪声等。通过噪声注入,可以增加数据的复杂性,使模型对噪声具有更强的鲁棒性,即在有噪声干扰的情况下,模型依然能够准确地识别和分析图像特征。
(五)优缺点
- 优点:实施成本较低,只需要对现有数据进行简单的变换操作,就能显著提升数据的多样性,进而增强模型的泛化能力,使模型在遇到新数据时能够表现得更加稳定和准确。
- 缺点:虽然能够生成新的数据样本,但这些样本本质上并没有产生全新的特征,例如一些严重病变的特征,无法通过这些简单的变换操作生成。
四、混合方法(传统+深度学习)
(一)原理
这种方法巧妙地将传统方法提取的特征(如颜色直方图,它能够清晰地表示图像中不同颜色的分布情况)和深度学习特征(像ResNet输出的特征向量)拼接在一起,形成一个更加全面、丰富的特征向量。然后,将这个综合特征向量输入到分类器中进行分类,充分发挥两种方法的优势,提高分类的准确性。
(二)代码示例
python
# 传统特征:颜色直方图
hist = cv2.calcHist([hsv_image], channels=[0,1], mask=None, histSize=[180,256], ranges=[0,180,0,256])
# 深度学习特征
deep_features = model(image).flatten()
# 合并特征
combined_features = np.concatenate([hist.flatten(), deep_features.numpy()])
在这段代码中,首先使用OpenCV计算HSV图像的颜色直方图,作为传统方法提取的特征。然后,通过深度学习模型model
得到图像的深度学习特征,并将其展平。最后,使用numpy
的concatenate
函数,将颜色直方图和深度学习特征拼接在一起,形成综合特征向量。
(三)名词解释
-
颜色直方图:是一种统计图像中不同颜色出现频率的有效方法。它将图像的颜色空间划分为若干个区间(bin),然后仔细统计每个区间内像素的数量,从而得到图像的颜色分布信息。在舌诊应用中,颜色直方图可以直观地反映舌象的整体颜色特征,例如舌苔的颜色分布情况,是偏黄、偏白还是其他颜色,以及不同颜色在舌象中的占比等。
-
特征拼接:是将不同来源或不同类型的特征组合在一起的操作,目的是形成一个更全面、更具代表性的特征向量。在混合方法中,我们将传统方法提取的特征(如颜色直方图)和深度学习方法提取的特征(如ResNet输出的特征向量)进行拼接,这样可以充分利用两种方法的优势,将传统方法对直观特征的提取能力和深度学习方法对复杂特征的挖掘能力相结合,为后续的分类任务提供更丰富、更准确的特征信息。
-
分类器:是一种机器学习模型,其主要功能是将输入数据分类到不同的类别中。常见的分类器包括支持向量机(SVM)、决策树、神经网络等。在AI舌诊模型中,分类器根据提取的特征向量,判断舌象所属的类别,例如判断是正常舌象,还是某种疾病对应的舌象,从而为诊断提供依据。
(四)优缺点
-
优点:既考虑了那些直观、容易理解的显性特征,又结合了深度学习自动提取的复杂隐性特征,特别适用于小数据场景,能够在有限的数据条件下,尽可能地提高模型的性能和准确性。
-
缺点:合并后的特征维度可能会比较高,这会增加计算的复杂度和模型训练的难度。因此,通常需要进行降维处理,例如使用PCA(主成分分析)方法。PCA是一种常用的降维技术,它通过线性变换将高维数据转换为低维数据,同时尽可能地保留数据的主要特征信息,使数据在低维空间中仍然能够保持较好的可分性。
五、少样本学习(Few - Shot Learning)
(一)原理
少样本学习主要通过对比学习的方式,让模型学会"区分差异",而不是像传统的分类方法那样直接对样本进行分类。例如,使用Siamese网络,在训练时,输入两张舌头图片,网络会根据学习到的特征,输出这两张图片的相似度,以此来判断它们之间的差异程度。
(二)步骤
-
训练网络:训练一个专门的网络,使其能够接收两张舌头图片作为输入,并通过内部的计算和学习,准确计算并输出它们的相似度。这里的相似度是衡量两个对象之间相似程度的指标,在图像领域,通常通过计算特征向量之间的距离或相似度函数来得到。例如,常用的余弦相似度,它通过计算两个特征向量之间夹角的余弦值来衡量它们的相似度,余弦值越接近1,表示两张图片的特征越相似;越接近 - 1,则差异越大。
-
测试分类:在测试阶段,将新的图片与已知类别的图片进行逐一对比。网络会根据之前训练学习到的特征差异判断方式,计算新图片与各个已知类别图片的相似度。然后找到相似度最高的已知类别图片,将新图片归到与之对应的类别中。比如,已知有正常舌象图片库和几种疾病舌象图片库,新的舌象图片经过网络计算后,与正常舌象图片的相似度最高,就判定该新图片为正常舌象。
(三)代码示例(Siamese网络结构)
python
# 定义双胞胎网络
import torch
import torch.nn as nn
from torchvision.models import resnet18
class SiameseNetwork(nn.Module):
def __init__(self):
super(SiameseNetwork, self).__init__()
self.base_model = resnet18(pretrained=True)
num_ftrs = self.base_model.fc.in_features
self.base_model.fc = nn.Identity()
def forward(self, x1, x2):
output1 = self.base_model(x1)
output2 = self.base_model(x2)
return output1, output2
# 初始化网络
siamese_net = SiameseNetwork()
# 生成两个随机输入
input1 = torch.randn(1, 3, 224, 224)
input2 = torch.randn(1, 3, 224, 224)
# 前向传播
features1, features2 = siamese_net(input1, input2)
# 计算相似度
similarity = torch.cosine_similarity(features1, features2)
在这段代码中,首先定义了一个继承自nn.Module
的SiameseNetwork
类。在类的初始化中,使用预训练的ResNet18作为基础模型,并去掉其最后的全连接层,替换为恒等映射,以便只提取特征。forward
方法接收两个输入,分别通过基础模型得到对应的特征输出。最后生成两个随机的输入图像input1
和input2
,经过网络得到特征向量features1
和features2
,再使用余弦相似度计算它们的相似度。
(四)名词解释
-
少样本学习:是机器学习领域中一种特殊的学习范式,旨在解决训练数据极少情况下的模型训练与分类问题。在传统机器学习中,通常需要大量的标注数据来训练模型,以保证模型能够学习到足够的特征和规律。而少样本学习则致力于让模型在只有少量样本的情况下,也能快速学习到有效的特征表示和分类规则,从而对新的样本进行准确分类。例如,在医疗领域,某些罕见疾病的样本数量非常有限,少样本学习就可以帮助我们利用这些少量样本训练模型,实现对疾病的诊断。
-
对比学习:是一种机器学习方法,它通过比较不同样本之间的相似性和差异性来学习有效的特征表示。在少样本学习中,对比学习尤为重要。它让模型不再局限于传统的基于类别标签的分类学习方式,而是通过对比不同样本之间的特征差异,学习到更具判别性的特征。例如,在舌诊少样本学习中,通过对比正常舌象和疾病舌象的特征差异,模型可以更好地理解不同舌象的特点,从而在面对新的舌象样本时,能够准确判断其所属类别。
-
Siamese网络:是一种特殊的神经网络结构,它由两个或多个共享权重的子网络组成。每个子网络接收不同的输入,然后通过计算它们输出的特征向量之间的相似度来进行学习。在舌诊应用中,Siamese网络可以同时接收两张舌象图片,通过共享权重的子网络对两张图片进行特征提取,再比较提取出的特征向量的相似度,以此来判断两张舌象图片是否属于同一类别,或者它们之间的相似程度。
(五)优缺点
-
优点:在数据量极少的极端情况下表现出色,例如每类只有5张图这种情况,少样本学习方法能够利用有限的数据进行有效的模型训练和分类。这对于那些难以获取大量数据的领域,如一些罕见病的医学图像分析、珍稀物种的识别等,具有重要的应用价值。
-
缺点:实现过程相对复杂,不仅需要精心设计网络结构,还需要专门设计对比损失函数来指导模型的训练过程。对比损失函数用于衡量两个样本之间的相似度或差异性,并根据这个衡量结果来调整模型的参数,使模型能够学习到有效的特征表示。设计合适的对比损失函数需要对问题有深入的理解和丰富的经验,增加了模型开发的难度。
六、推荐流程
- 预处理:把所有的图片大小统一,还要把背景去除掉,比如说可以用U - Net这种分割模型来分割出舌头区域。
- 特征提取 :
- 一开始数据量少的时候,可以先用传统方法(颜色特征提取+纹理特征提取)快速验证一下效果。
- 等数据量允许了,就可以用预训练模型(像ResNet)进行迁移学习,提取更复杂的特征。
- 数据增强:对数据进行各种变换,生成更多的训练样本,让模型学习到更多不同的数据特征。
- 分类器:把提取到的特征输入到简单的模型里,比如SVM(支持向量机)或者浅层神经网络,进行分类。
代码框架示例
python
# 数据增强 + 预训练模型
train_transform = transforms.Compose([
transforms.Resize(256),
transforms.RandomCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
])
# 加载预训练模型
model = models.resnet18(pretrained=True)
model.fc = nn.Identity()
# 提取特征并训练分类器
features = model(images)
这段代码先定义了数据增强的操作,包括调整图像大小、随机裁剪、随机水平翻转以及转为张量。然后加载预训练的ResNet18模型,并将最后一层全连接层替换为恒等映射,只保留特征提取部分。最后将图像输入模型提取特征,准备输入到分类器进行训练。
这些方法都各有千秋,在实际操作中,还是要根据我们手头的数据情况和任务需求,灵活选择合适的方法,或者把几种方法结合起来使用。如果在学习过程中有任何问题,随时在评论区讨论。