文章目录
- 多模数据与智能模型
- 1. 数字图像处理与计算机视觉
- 1.1 数字图像的表示与处理
- 1.1.1 认识OpenCV
- 1.1.2 色彩学
- 1.1.3 常见图像操作
- 1.2 数字图像的特征点
- 1.2.1 Sobel算子
- 1.2.2 Canny算子
- 1.2.3 Harris角点检测
- 1.2.4 ORB特征点检测
- 1.3 计算机视觉
- 1.3.1 卷积神经网络
- 1.3.2 YOLO模型
- 1.3.3 U-Net模型
- 1.3.4 GAN模型
- 2. 计算语言学与自然语言处理
- 2.1 文本的嵌入表示
- 2.1.1 词袋模型(Bag of Words, BoW)
- 2.1.2 TF-IDF(Term Frequency-Inverse Document Frequency)
- 2.1.2 TF-IDF(Term Frequency-Inverse Document Frequency)
- 1. 词频(Term Frequency, TF)
- 2. 逆文档频率(Inverse Document Frequency, IDF)
- 3. TF-IDF
- 2.1.3 Word2Vec
- 2.1.4 GloVe(Global Vectors for Word Representation)
- 2.1.5 BERT(Bidirectional Encoder Representations from Transformers)
- 2.2 文本的分类与话题模型
- 2.2.1 文本分类
- TextCNN
- RNN(循环神经网络)
- 2.2.2 话题模型(Topic Modeling)
- 3. 数字信号处理与智能感知
- 3.1 数字信号的傅里叶变换
- 3.2 数字信号的统计指标
- 3.3 数字信号的滤波与分解
- 3.3.1 滤波器
- 低通滤波器
- 巴特沃斯滤波器
- 切比雪夫滤波器
- 椭圆滤波器
- 贝塞尔滤波器
- FIR滤波器
- 3.3.2 信号分解
- EMD(经验模态分解)
- 4. 多模态数据与人工智能
- 学习心得
多模数据与智能模型
1. 数字图像处理与计算机视觉
1.1 数字图像的表示与处理
1.1.1 认识OpenCV
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它提供了多种工具和算法,帮助开发者进行图像处理、视频分析、机器学习等任务。
import cv2
# 读取图像
image = cv2.imread('image.jpg')
# 显示图像
cv2.imshow('Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.1.2 色彩学
色彩学在数字图像处理中非常重要。常见的色彩空间包括RGB、HSV和灰度图。
- RGB色彩空间:由红(Red)、绿(Green)、蓝(Blue)三种颜色组成,每种颜色的取值范围为0-255。
- 灰度图:单通道图像,取值范围为0-255。
- HSV色彩空间:由色相(Hue)、饱和度(Saturation)、明度(Value)组成,适合于颜色分割和对象检测。
HSV表示法是一种描述颜色的方式,其中H代表色调(Hue),S代表饱和度(Saturation),V代表明度(Value)。这种颜色空间与人类对颜色的感知方式更为接近,因此,在图像处理中,HSV空间经常用于颜色分割、颜色识别等任务。
色调是颜色的一种属性,它表示的是纯色的类型,比如红色、蓝色或黄色等。在HSV颜色空间中,色调以角度来表示,从0到360度。比如0(或360)度表示红色,120度表示绿色,240度表示蓝色。饱和度表示颜色的纯度或强度。一个颜色的饱和度越高,它就越鲜艳;饱和度越低,颜色就越接近灰色。在HSV中,饱和度是一个百分比值,从0%(灰色)到100%(完全饱和)。明度表示颜色的亮度或明暗程度。它与颜色的强度或发光量有关。在HSV中,明度也是一个百分比值,从0%(黑色)到100%(白色)。
RGB是一种加色模型,它是通过红、绿、蓝三种颜色的组合来表示颜色的。每种颜色的强度都通过一个0-255的数值来表示。RGB模型在显示设备上使用得很广泛,但它不太直观地表示人类对颜色的感知,尤其是色调。而HSV则是一种更接近人类感知的颜色空间,更适合用于颜色分割等任务。
# RGB到灰度图
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# RGB到HSV
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
1.1.3 常见图像操作
- 图像缩放:改变图像的大小。
- 图像旋转:将图像按一定角度旋转。
- 图像裁剪:从图像中截取特定区域。
# 图像缩放
resized_image = cv2.resize(image, (300, 300))
# 图像旋转
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
matrix = cv2.getRotationMatrix2D(center, 45, 1.0)
rotated_image = cv2.warpAffine(image, matrix, (w, h))
# 图像裁剪
cropped_image = image[50:200, 50:200]
4.图像粘贴
图像粘贴操作可以将一幅图像粘贴到另一幅图像的指定位置。
# 读取两幅图像
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
# 定义粘贴位置
x_offset, y_offset = 50, 50
y1, y2 = y_offset, y_offset + image2.shape[0]
x1, x2 = x_offset, x_offset + image2.shape[1]
# 将image2粘贴到image1
image1[y1:y2, x1:x2] = image2
# 显示结果
cv2.imshow('Pasted Image', image1)
cv2.waitKey(0)
cv2.destroyAllWindows()
5.高斯平滑
高斯平滑(高斯模糊)通过使用高斯核函数来平滑图像,减少图像中的噪声。
G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} G(x,y)=2πσ21e−2σ2x2+y2
# 高斯平滑
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
# 显示结果
cv2.imshow('Gaussian Blur', blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
6.腐蚀操作
腐蚀操作通过缩小图像中的白色区域(前景),去除噪声。它用一个结构元素扫描图像,并将该区域的像素值替换为局部最小值。
# 定义结构元素
kernel = np.ones((5, 5), np.uint8)
# 腐蚀操作
eroded_image = cv2.erode(image, kernel, iterations=1)
# 显示结果
cv2.imshow('Eroded Image', eroded_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
7.锐化操作
锐化操作通过增强图像中的边缘来提高图像的清晰度。通常使用拉普拉斯算子进行锐化。
L = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] L = \begin{bmatrix} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \end{bmatrix} L= 0−10−14−10−10
# 锐化操作
laplacian = cv2.Laplacian(image, cv2.CV_64F)
sharpened_image = cv2.convertScaleAbs(laplacian)
# 显示结果
cv2.imshow('Sharpened Image', sharpened_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些常见的图像操作为各种图像处理任务提供了基本工具。通过这些操作,可以对图像进行预处理,为后续的高级处理和分析提供良好的基础。
1.2 数字图像的特征点
1.2.1 Sobel算子
Sobel算子用于边缘检测,通过计算图像灰度的梯度来检测边缘。
G
x
=
∂
I
∂
x
=
[
−
1
0
+
1
−
2
0
+
2
−
1
0
+
1
]
∗
I
G_x = \frac{\partial I}{\partial x} = \begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{bmatrix} * I
Gx=∂x∂I=
−1−2−1000+1+2+1
∗I
G
y
=
∂
I
∂
y
=
[
−
1
−
2
−
1
0
0
0
+
1
+
2
+
1
]
∗
I
G_y = \frac{\partial I}{\partial y} = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ +1 & +2 & +1 \end{bmatrix} * I
Gy=∂y∂I=
−10+1−20+2−10+1
∗I
# Sobel算子
sobel_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3)
sobel = cv2.magnitude(sobel_x, sobel_y)
1.2.2 Canny算子
Canny边缘检测是一种多级边缘检测算法,步骤包括高斯滤波、计算梯度、非极大值抑制和双阈值检测。
# Canny边缘检测
edges = cv2.Canny(gray_image, 100, 200)
1.2.3 Harris角点检测
Harris角点检测用于识别图像中的角点。角点在图像灰度发生剧烈变化的地方。
R
=
d
e
t
(
M
)
−
k
(
t
r
a
c
e
(
M
)
)
2
R = det(M) - k(trace(M))^2
R=det(M)−k(trace(M))2
其中,( M )是图像梯度的自相关矩阵,( det )和( trace )分别是矩阵的行列式和迹。
# Harris角点检测
gray = np.float32(gray_image)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
image[dst > 0.01 * dst.max()] = [0, 0, 255]
1.2.4 ORB特征点检测
ORB(Oriented FAST and Rotated BRIEF)是一个快速且有效的特征点检测和描述算法。
# ORB特征点检测
orb = cv2.ORB_create()
keypoints, descriptors = orb.detectAndCompute(gray_image, None)
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0))
这些操作和算法为图像处理和计算机视觉任务提供了基础工具。通过这些基础操作,我们可以实现更复杂的视觉系统,如对象检测、图像分割和图像识别等。
1.3 计算机视觉
生物的视觉能够让它们看到现实世界并感知,那么计算机如果想要感受这个世界首先就需要看到这个世界。计算机视觉就是让计算机看到世界的一门学科,它主要聚焦的就是图像信息如何在计算机中存储、表示、处理、分析、理解并应用。在传统的计算机视觉研究中,大家主要是利用一些数学方法实现对计算机图像的计算与处理,还远远达不到真正的理解信息。但随着神经网络的发展,计算机视觉终于迎来了一场革命。
1.3.1 卷积神经网络
图像分类任务是计算机视觉领域中的一项基本任务,其目标是将输入的图像自动分配到预先定义的类别中。例如,一个图像分类系统可能将输入的图片识别为动物、植物、建筑或其他类别。这种分类依赖于从图像中提取的特征,这些特征可能包括颜色、纹理、形状等信息。研究者们一直在试图寻找不需要手工设计特征的分类模型。
卷积神经网络(CNN)是深度学习中最常用的模型之一,特别适用于图像处理和计算机视觉任务。CNN通过卷积层、池化层和全连接层对输入图像进行特征提取和分类。
以卷积神经网络和注意力机制为代表的深度学习方法在图像分类、目标检测、语义分割、图像超分辨率、图像生成等领域有着重要作用。如果不知道什么是卷积,可以理解为一个小矩阵在图片上扫描,每一次扫描小矩阵(也叫卷积核)会对扫描到的区域执行按位乘并求和,然后生成一个新的图像,过程如图所示:
在图像上执行卷积操作如图所示,卷积核扫描后按照按位乘求和的方式组织了新的图像。这一方法能够降低计算量,但保留图像的有效特征,也是特征提取的一种方法。卷积神经网络把这个卷积核中每一项的值看作一个待学习的权重从而构建神经网络。
卷积操作:
卷积层通过卷积核(滤波器)对图像进行卷积操作,提取图像的局部特征。
( I ∗ K ) ( i , j ) = ∑ m = − k k ∑ n = − k k I ( i + m , j + n ) K ( m , n ) (I * K)(i,j) = \sum_{m=-k}^{k} \sum_{n=-k}^{k} I(i+m, j+n) K(m, n) (I∗K)(i,j)=m=−k∑kn=−k∑kI(i+m,j+n)K(m,n)
池化操作:
池化层通常使用最大池化或平均池化,减少图像的尺寸,同时保留重要特征。
import tensorflow as tf
from tensorflow.keras import layers, models
# 创建卷积神经网络模型
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
# 编译模型
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
注意:卷积神经网络是图像处理的经典方法。它的常见模型包括LeNet-5、ResNet、VGG、GoogleNet、GhostNet等多种结构,也是后继很多网络的Backbone例如Faster RCNN、YOLO、FCN等也都有卷积的影子在里面
1.3.2 YOLO模型
随着技术的不断发展,目标检测方法也在不断演进。经典的目标检测方法如YOLO、SSD、Faster R-CNN、DETR等,通过引入深度学习技术,实现了对目标的高效检测。YOLO系列算法通过改进网络结构和损失函数,逐渐提高了检测速度和精度。
YOLO(You Only Look Once)是一种实时目标检测系统。它将目标检测问题转化为回归问题,通过单次前向传播实现目标定位和分类。
# YOLO模型的简单使用示例
from yolov5 import YOLOv5
# 加载预训练的YOLO模型
model = YOLOv5('yolov5s')
# 进行目标检测
results = model.predict('image.jpg')
# 显示检测结果
results.show()
1.3.3 U-Net模型
图像分割任务是指将图像划分为若干个互不相交的区域,每个区域都代表图像中的一个物体或场景的一部分。这一任务在计算机视觉中至关重要,因为它有助于从复杂的图像中提取出有意义的信息。然而,图像分割面临着诸多难点。首先,图像中的物体可能具有复杂的形状、纹理和颜色,使得准确区分不同物体变得困难。其次,光照条件、噪声、遮挡等因素也可能对分割结果产生负面影响。此外,处理不同尺度和分辨率的图像也是一大挑战。
在图像分割模型的技术演化与迭代方面,经典的模型如FCN(全卷积网络)为后续的研究奠定了基础。FCN通过引入全卷积层来替代传统卷积神经网络中的全连接层,从而实现了端到端的像素级预测。随后,U-Net模型进一步推动了图像分割技术的发展。U-Net采用编码器-解码器结构,通过跳跃连接将低层特征与高层特征相结合,提高了分割的准确性和细节保留能力。
1.3.4 GAN模型
图像生成任务是计算机视觉领域的一个重要分支,它涉及到生成具有特定属性的图像。这个任务的目标是根据给定的输入信息,生成一张新的图像。生成对抗网络(GAN)则是这一领域出色的模型。GAN网络,即生成对抗网络,是一种在图像生成任务中表现尤为出色的深度学习模型。GAN网络由两个主要部分构成:生成器和判别器。生成器的任务是生成新的数据样本,如图像,而判别器则负责判断这些生成的样本与真实数据之间的差异。这两个部分通过对抗学习的方式相互竞争,使生成器不断提高其生成逼真样本的能力,同时判别器也持续提高其辨别真伪样本的能力。它的核心思想正是我们在第3章中讲到的博弈论。由于GAN网络具有出色的表现,它已被广泛应用于计算机视觉、自然语言处理和创意艺术等多个领域。
生成对抗网络(Generative Adversarial Networks, GANs)由生成器和判别器组成。生成器尝试生成逼真的图像,而判别器则尝试区分真实图像和生成图像。
from tensorflow.keras import layers, models
# 生成器
def build_generator():
model = models.Sequential()
model.add(layers.Dense(128 * 7 * 7, activation='relu', input_dim=100))
model.add(layers.Reshape((7, 7, 128)))
model.add(layers.UpSampling2D())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.UpSampling2D())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(1, (3, 3), activation='tanh', padding='same'))
return model
# 判别器
def build_discriminator():
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), strides=(2, 2), input_shape=(28, 28, 1), padding='same'))
model.add(layers.LeakyReLU(alpha=0.2))
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(128, (3, 3), strides=(2, 2), padding='same'))
model.add(layers.LeakyReLU(alpha=0.2))
model.add(layers.Dropout(0.3))
model.add(layers.Flatten())
model.add(layers.Dense(1, activation='sigmoid'))
return model
现在,随着人工智能的发展,我们也有了很多面向计算机视觉的大模型。比如midjourney和stable diffusion,SORA……如今,随着人工智能技术的飞速进步,计算机视觉领域也迎来了前所未有的发展机遇。在这一浪潮中,我们见证了众多面向计算机视觉的大模型的涌现,它们如同璀璨的明星,点亮了科技创新的天空。展望未来,随着人工智能技术的不断发展,我们相信会有更多面向计算机视觉的大模型涌现出来,为我们带来更多的惊喜和突破。这些模型将在图像识别、目标检测、图像生成等多个方面发挥越来越重要的作用,推动计算机视觉领域不断向前发展。
2. 计算语言学与自然语言处理
2.1 文本的嵌入表示
文本嵌入表示是将文本转换为向量形式,使得计算机能够处理和理解自然语言。常见的嵌入方法包括词袋模型、TF-IDF、Word2Vec、GloVe、BERT等。
2.1.1 词袋模型(Bag of Words, BoW)
词袋模型是最简单的文本表示方法之一,它将文本表示为词频向量,但忽略了词的顺序。
from sklearn.feature_extraction.text import CountVectorizer
# 示例文本
texts = ["I love natural language processing", "Text embeddings are essential"]
# 词袋模型
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)
print(vectorizer.get_feature_names_out())
print(X.toarray())
2.1.2 TF-IDF(Term Frequency-Inverse Document Frequency)
TF-IDF在词频的基础上引入了逆文档频率,衡量词在整个语料库中的重要性。
TF的意思是词频,IDF的意思是逆文本频率指数,它基于这样一个事实:某个单词在某一篇文章中出现频次越高,同时在其他文章中出现频次越低,则这个单词就越可能是该文章的一个关键词。
2.1.2 TF-IDF(Term Frequency-Inverse Document Frequency)
TF-IDF是一种常用的文本表示方法,通过结合词频(Term Frequency, TF)和逆文档频率(Inverse Document Frequency, IDF)来衡量词的重要性。以下是TF-IDF的相关公式:
1. 词频(Term Frequency, TF)
词频表示词 t t t 在文档 d d d 中出现的频率。常见的计算方式是:
TF ( t , d ) = f t , d ∑ k f k , d \text{TF}(t, d) = \frac{f_{t,d}}{\sum_{k} f_{k,d}} TF(t,d)=∑kfk,dft,d
其中, f t , d f_{t,d} ft,d 是词 t t t 在文档 d d d 中出现的次数,分母是文档 d d d 中所有词的总出现次数。
2. 逆文档频率(Inverse Document Frequency, IDF)
逆文档频率衡量词 t t t 在整个语料库中的重要性。其计算公式为:
IDF ( t ) = log N 1 + DF ( t ) \text{IDF}(t) = \log \frac{N}{1 + \text{DF}(t)} IDF(t)=log1+DF(t)N
其中, N N N 是语料库中的总文档数, DF ( t ) \text{DF}(t) DF(t) 是包含词 t t t 的文档数。加1是为了防止分母为零。
3. TF-IDF
TF-IDF是词频和逆文档频率的乘积:
TF-IDF ( t , d ) = TF ( t , d ) × IDF ( t ) \text{TF-IDF}(t, d) = \text{TF}(t, d) \times \text{IDF}(t) TF-IDF(t,d)=TF(t,d)×IDF(t)
from sklearn.feature_extraction.text import TfidfVectorizer
# 示例文本
texts = ["I love natural language processing", "Text embeddings are essential"]
# 初始化TF-IDF向量化器
vectorizer = TfidfVectorizer()
# 拟合并转换文本数据
X = vectorizer.fit_transform(texts)
# 获取特征名称(词汇表)
feature_names = vectorizer.get_feature_names_out()
# 转换为数组形式
tfidf_matrix = X.toarray()
# 输出结果
print("Feature Names: ", feature_names)
print("TF-IDF Matrix:\n", tfidf_matrix)
2.1.3 Word2Vec
Word2Vec是基于神经网络的词嵌入模型,它通过上下文预测词的向量表示。
Word2vec是基于神经网络的模型,引入了机器学习因素,它有两类典型的模型,即:用一个词语作为输入,来预测它周围的上下文的skip-gram模型,和拿一个词语的上下文作为输入,来预测这个词语本身的CBOW模型。CBOW对小型语料比较合适,而Skip-Gram在大型语料中表现更好。下图为两种典型的word2vec架构:
from gensim.models import Word2Vec
# 示例文本
sentences = [["I", "love", "natural", "language", "processing"],
["Text", "embeddings", "are", "essential"]]
# 训练Word2Vec模型
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
# 获取词向量
vector = model.wv['love']
print(vector)
2.1.4 GloVe(Global Vectors for Word Representation)
GloVe是通过全局共现矩阵构建的词嵌入模型,能够捕捉全局语义信息。
# 安装GloVe模型需要下载预训练词向量,这里简要展示如何加载
import numpy as np
# 加载预训练的GloVe向量
def load_glove_model(file_path):
glove_model = {}
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
split_line = line.split()
word = split_line[0]
embedding = np.array([float(val) for val in split_line[1:]])
glove_model[word] = embedding
return glove_model
# 示例加载路径(需下载预训练模型)
glove_file_path = 'glove.6B.100d.txt'
glove_model = load_glove_model(glove_file_path)
# 获取词向量
vector = glove_model['love']
print(vector)
2.1.5 BERT(Bidirectional Encoder Representations from Transformers)
BERT是基于Transformer的预训练语言模型,能够生成上下文敏感的词嵌入。
2018年底微软提出的BERT(Bidirectional Encoder Representation from Transformers)相较于Elmo和GPT-2取得了更好的表现,目前也是应用最广泛的文本向量化方法之一,因为在 BERT 中,特征提取器也是使用的Transformer,且 BERT 模型是真正在双向上深度融合特征的语言模型[[[] Devlin J, Chang M W, Lee K, et al. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding[J]. 2018.]]。
BERT架构如下图所示,与GPT、ELMo模型的区别如图所示。BERT与GPT的区别就在于BERT采用的是Transformer Encoder,也就是说每个时刻的Attention计算都能够得到全部时刻的输入,而OpenAI GPT采用了Transformer Decoder,每个时刻的Attention计算只能依赖于该时刻前的所有时刻的输入,因为OpenAI GPT是采用了单向语言模型。
from transformers import BertTokenizer, BertModel
import torch
# 加载预训练的BERT模型和分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
# 示例文本
text = "I love natural language processing"
inputs = tokenizer(text, return_tensors='pt')
# 获取BERT嵌入
with torch.no_grad():
outputs = model(**inputs)
# 提取嵌入向量
embedding = outputs.last_hidden_state
print(embedding)
2.2 文本的分类与话题模型
文本分类和话题模型是自然语言处理中的重要任务,用于对文本进行分类和主题分析。
2.2.1 文本分类
TextCNN
TextCNN网络是2014年提出的用来做文本分类的卷积神经网络,由于其结构简单、效果好,在文本分类、推荐等NLP领域应用广泛。
TextCNN是一种基于卷积神经网络(CNN)的文本分类模型。它通过卷积操作提取文本中的局部特征,进而进行分类。
TextCNN的模型图如下:
模型结构:
- 嵌入层:将输入文本转换为词嵌入矩阵。
- 卷积层:应用多个不同大小的卷积核,提取文本中的特征。
- 池化层:对卷积结果进行最大池化,保留最重要的特征。
- 全连接层:将池化结果连接并通过全连接层进行分类。
import tensorflow as tf
from tensorflow.keras import layers, models
# 定义TextCNN模型
def create_textcnn_model(vocab_size, embedding_dim, max_length):
model = models.Sequential()
model.add(layers.Embedding(vocab_size, embedding_dim, input_length=max_length))
model.add(layers.Conv1D(128, 5, activation='relu'))
model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(10, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
# 示例用法
vocab_size = 10000 # 词汇表大小
embedding_dim = 100 # 词嵌入维度
max_length = 500 # 文本最大长度
model = create_textcnn_model(vocab_size, embedding_dim, max_length)
model.summary()
RNN(循环神经网络)
RNN是一种适用于处理序列数据的神经网络,能够捕捉文本中的上下文信息。其常见变种包括LSTM和GRU。
RNN进行文本分类时将问题抽象为序列,最后使用softmax进行分类预判。RNN网络不可避免地带来问题就是最后的输出结果受最近的输入较大,而之前较远的输入可能无法影响结果,这就是信息瓶颈问题。可以使用双向LSTM,不仅增加了反向信息传播,而且每一轮的都会有一个输出,将这些输出进行组合之后再传给全连接层。
模型结构:
- 嵌入层:将输入文本转换为词嵌入矩阵。
- RNN层:应用RNN单元(如LSTM或GRU),捕捉序列信息。
- 全连接层:将RNN层输出通过全连接层进行分类。
# 定义RNN模型
def create_rnn_model(vocab_size, embedding_dim, max_length):
model = models.Sequential()
model.add(layers.Embedding(vocab_size, embedding_dim, input_length=max_length))
model.add(layers.SimpleRNN(128, return_sequences=False))
model.add(layers.Dense(10, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
# 示例用法
model = create_rnn_model(vocab_size, embedding_dim, max_length)
model.summary()
2.2.2 话题模型(Topic Modeling)
话题模型用于发现文档集合中的主题。常见的方法是LDA(Latent Dirichlet Allocation)。LDA(隐狄利克雷分布)在文本话题模型中的应用原理,其实可以理解为一种帮助我们自动找出文本中隐藏话题的“魔法”。想象一下,你有一堆文章,但是你不知道它们主要讲了哪些话题。LDA就能帮你把这些话题找出来。LDA是怎么做到的呢?首先,它认为每篇文章都是由几个不同的话题混合而成的。比如说,一篇文章可能同时讨论了“旅游”和“美食”这两个话题,但可能“旅游”的话题更多一些,“美食”的话题稍微少一些。然后,LDA又认为每个话题都是由一堆特定的词语组成的。比如“旅游”这个话题,就可能会有“风景”、“旅行”、“酒店”等词语;而“美食”这个话题,则可能会有“菜肴”、“口感”、“餐厅”等词语。LDA的工作就是找出每篇文章中各个话题的比例,以及每个话题中各个词语的比例。它会反复地学习、尝试,直到找到一个最合理的解释,即这些文章是如何由这些话题和词语组成的。这样,当我们再次看到一篇新的文章时,LDA就能告诉我们这篇文章主要讨论了哪些话题,以及每个话题在文章中的重要程度。注意, LDA在分析文本的话题模型的时候词汇的语序对话题模型并没有什么显著影响。
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import TfidfVectorizer
# 示例文本
texts = ["I love natural language processing", "Text embeddings are essential",
"Python is great for data science", "Machine learning is fascinating"]
# TF-IDF向量化
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(texts)
# 训练LDA模型
lda = LatentDirichletAllocation(n_components=2, random_state=0)
lda.fit(X)
# 显示每个主题的词语
def display_topics(model, feature_names, no_top_words):
for topic_idx, topic in enumerate(model.components_):
print("Topic %d:" % (topic_idx))
print(" ".join([feature_names[i] for i in topic.argsort()[:-no_top_words - 1:-1]]))
display_topics(lda, vectorizer.get_feature_names_out(), 5)
3. 数字信号处理与智能感知
3.1 数字信号的傅里叶变换
傅里叶变换是将时间域信号转换为频域信号的工具,能够分析信号的频率成分。常见的傅里叶变换形式包括离散傅里叶变换(DFT)和快速傅里叶变换(FFT)。
离散傅里叶变换(DFT)公式:
X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j 2 π N k n X[k] = \sum_{n=0}^{N-1} x[n] e^{-j \frac{2\pi}{N} kn} X[k]=n=0∑N−1x[n]e−jN2πkn
其中, x [ n ] x[n] x[n] 是时间域信号, X [ k ] X[k] X[k] 是频域信号, N N N 是信号的长度。
import numpy as np
import matplotlib.pyplot as plt
# 示例信号
fs = 500 # 采样频率
t = np.arange(0, 1, 1/fs)
x = np.sin(2 * np.pi * 50 * t) + 0.5 * np.sin(2 * np.pi * 120 * t)
# 计算傅里叶变换
X = np.fft.fft(x)
frequencies = np.fft.fftfreq(len(X), 1/fs)
# 画出频谱
plt.plot(frequencies, np.abs(X))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude')
plt.title('Frequency Spectrum')
plt.show()
3.2 数字信号的统计指标
以下是一些常见的数字信号统计指标的定义和公式:
-
最大值(Max): 信号中的最大值。信号在观测期间的最高点,表示信号能够达到的最大幅度。
Max = max ( x [ n ] ) \text{Max} = \max(x[n]) Max=max(x[n])
-
最小值(Min): 信号中的最小值。与最大值相对,表示信号在观测期间的最低点。
Min = min ( x [ n ] ) \text{Min} = \min(x[n]) Min=min(x[n])
-
峰值(Peak): 信号的最大幅值。信号最大值和最小值的差值,常用于描述信号的振幅。
Peak = max ( ∣ x [ n ] ∣ ) \text{Peak} = \max(|x[n]|) Peak=max(∣x[n]∣)
-
偏度(Skewness): 衡量信号分布的对称性。度量信号分布的对称性。正偏度意味着信号的尾部向右延伸较长,负偏度则表示尾部向左延伸较长。
Skewness = 1 N ∑ n = 0 N − 1 ( x [ n ] − μ σ ) 3 \text{Skewness} = \frac{1}{N} \sum_{n=0}^{N-1} \left(\frac{x[n] - \mu}{\sigma}\right)^3 Skewness=N1n=0∑N−1(σx[n]−μ)3
其中 Skewness \text{Skewness} Skewness表示偏度,用于表示统计数据分布偏斜方向和程度。 -
整流平均值(Rectified Mean): 信号绝对值的平均。
Rectified Mean = 1 N ∑ n = 0 N − 1 ∣ x [ n ] ∣ \text{Rectified Mean} = \frac{1}{N} \sum_{n=0}^{N-1} |x[n]| Rectified Mean=N1n=0∑N−1∣x[n]∣
-
均值(Mean): 信号的平均值。即为信号中心值,随机信号在均值附近波动。
μ = 1 N ∑ n = 0 N − 1 x [ n ] \mu = \frac{1}{N} \sum_{n=0}^{N-1} x[n] μ=N1n=0∑N−1x[n]
-
标准差(Standard Deviation): 信号的标准差。反映出信号的波动程度,其大小与波动程度正相关。
σ = 1 N ∑ n = 0 N − 1 ( x [ n ] − μ ) 2 \sigma = \sqrt{\frac{1}{N} \sum_{n=0}^{N-1} (x[n] - \mu)^2} σ=N1n=0∑N−1(x[n]−μ)2
-
均方根值(RMS): 信号的均方根值。即有效值,能作为振动信号振动幅度大小的一个量度,也可以度量故障的严重程度。
RMS = 1 N ∑ n = 0 N − 1 x [ n ] 2 \text{RMS} = \sqrt{\frac{1}{N} \sum_{n=0}^{N-1} x[n]^2} RMS=N1n=0∑N−1x[n]2
-
峰值指标(Crest Factor): 峰值与均方根值的比值。用于表示信号中是否存在冲击。
Crest Factor = Peak RMS \text{Crest Factor} = \frac{\text{Peak}}{\text{RMS}} Crest Factor=RMSPeak
-
峭度指标(Kurtosis): 衡量信号分布的尖锐度。用于反映信号中冲击的特征。
Kurtosis = 1 N ∑ n = 0 N − 1 ( x [ n ] − μ σ ) 4 \text{Kurtosis} = \frac{1}{N} \sum_{n=0}^{N-1} \left(\frac{x[n] - \mu}{\sigma}\right)^4 Kurtosis=N1n=0∑N−1(σx[n]−μ)4
-
波形指标(Waveform Factor): 均方根值与整流平均值的比值。用于检测信号中是否有冲击。
Waveform Factor = RMS Rectified Mean \text{Waveform Factor} = \frac{\text{RMS}}{\text{Rectified Mean}} Waveform Factor=Rectified MeanRMS
-
裕度指标(Margin Index): 峰值与整流平均值的比值。用于检测设备的磨损情况。
Margin Index = Peak Rectified Mean \text{Margin Index} = \frac{\text{Peak}}{\text{Rectified Mean}} Margin Index=Rectified MeanPeak
-
脉冲指标(Impulse Factor): 峰值与均值的比值。用于检测信号中是否存在冲击。
Impulse Factor = Peak μ \text{Impulse Factor} = \frac{\text{Peak}}{\mu} Impulse Factor=μPeak
-
重心频率(Center Frequency): 频率加权功率谱的平均值。当设备发生故障时,可推知某一处频率的振动幅值会发生变化,进而导致功率谱的重心位置发生变化,而重心频率可以反映功率谱的重心位置,故可用重心频率来判断故障状态。
f c = ∑ k = 0 N − 1 f [ k ] ∣ X [ k ] ∣ 2 ∑ k = 0 N − 1 ∣ X [ k ] ∣ 2 f_c = \frac{\sum_{k=0}^{N-1} f[k] |X[k]|^2}{\sum_{k=0}^{N-1} |X[k]|^2} fc=∑k=0N−1∣X[k]∣2∑k=0N−1f[k]∣X[k]∣2
-
均方频率(Root Mean Square Frequency): 频率平方加权功率谱的均方根值。这是一个评估功率谱重心稳定性的指标,可用于追踪功率谱中心的动态变化。其计算方法通常涉及到功率谱的二阶矩。
f r m s = ∑ k = 0 N − 1 f [ k ] 2 ∣ X [ k ] ∣ 2 ∑ k = 0 N − 1 ∣ X [ k ] ∣ 2 f_{rms} = \sqrt{\frac{\sum_{k=0}^{N-1} f[k]^2 |X[k]|^2}{\sum_{k=0}^{N-1} |X[k]|^2}} frms=∑k=0N−1∣X[k]∣2∑k=0N−1f[k]2∣X[k]∣2
-
频率方差(Frequency Variance): 重心频率的方差。此参数反映了频率谱能量的分散程度,是评价信号频率分布稳定性的一个关键指标。频率方差越大,表明信号的能量分布越分散。
σ f 2 = ∑ k = 0 N − 1 ( f [ k ] − f c ) 2 ∣ X [ k ] ∣ 2 ∑ k = 0 N − 1 ∣ X [ k ] ∣ 2 \sigma_f^2 = \frac{\sum_{k=0}^{N-1} (f[k] - f_c)^2 |X[k]|^2}{\sum_{k=0}^{N-1} |X[k]|^2} σf2=∑k=0N−1∣X[k]∣2∑k=0N−1(f[k]−fc)2∣X[k]∣2
时频域分析提供了一种同时观察信号在时间和频率两个维度变化的方法,适合分析那些在短时间内频率特性快速变化的信号:
-
频带能量(Band Energy): 在特定频带内的能量。通过计算特定频带内的总能量,可以帮助我们理解信号在特定频段的能量分布情况。
E B = ∑ f 1 ≤ f [ k ] ≤ f 2 ∣ X [ k ] ∣ 2 E_B = \sum_{f_1 \leq f[k] \leq f_2} |X[k]|^2 EB=f1≤f[k]≤f2∑∣X[k]∣2
-
相对功率谱熵(Relative Power Spectral Entropy): 频谱能量的归一化熵。这是度量功率谱分布均匀性的指标。高的功率谱熵意味着信号的能量较为均匀地分布在不同的频率上,而低的功率谱熵则表明信号的能量集中在少数几个频率上。这一指标对于分析信号的复杂性和预测其行为模式非常有用。
H r = − ∑ k = 0 N − 1 P [ k ] log P [ k ] H_r = -\sum_{k=0}^{N-1} P[k] \log P[k] Hr=−k=0∑N−1P[k]logP[k]
其中, P [ k ] P[k] P[k] 表示归一化的功率谱。
import numpy as np
# 示例信号
x = np.random.randn(1000)
# 计算统计指标
max_value = np.max(x)
min_value = np.min(x)
peak_value = np.max(np.abs(x))
mean_value = np.mean(x)
std_value = np.std(x)
rms_value = np.sqrt(np.mean(x**2))
rectified_mean = np.mean(np.abs(x))
skewness = np.mean(((x - mean_value) / std_value)**3)
kurtosis = np.mean(((x - mean_value) / std_value)**4)
crest_factor = peak_value / rms_value
waveform_factor = rms_value / rectified_mean
margin_index = peak_value / rectified_mean
impulse_factor = peak_value / mean_value
print("Max:", max_value)
print("Min:", min_value)
print("Peak:", peak_value)
print("Mean:", mean_value)
print("Standard Deviation:", std_value)
print("RMS:", rms_value)
print("Rectified Mean:", rectified_mean)
print("Skewness:", skewness)
print("Kurtosis:", kurtosis)
print("Crest Factor:", crest_factor)
print("Waveform Factor:", waveform_factor)
print("Margin Index:", margin_index)
print("Impulse Factor:", impulse_factor)
3.3 数字信号的滤波与分解
3.3.1 滤波器
滤波器用于移除信号中的噪声或特定频率成分。常见的滤波器包括低通滤波器、巴特沃斯滤波器、切比雪夫滤波器、椭圆滤波器、贝塞尔滤波器和FIR滤波器。
scipy.signal模块为我们提供了一系列强大的工具,可以用来设计不同类型的滤波器,从基本的低通和高通滤波器到更复杂的带通和带阻滤波器。你可以通过调整滤波器的类型和参数来满足你的需求。在这里举出一些所支持的高级滤波。
低通滤波器
低通滤波器允许低频信号通过,阻止高频信号。
from scipy.signal import butter, lfilter
# 设计巴特沃斯低通滤波器
def butter_lowpass(cutoff, fs, order=5):
nyquist = 0.5 * fs
normal_cutoff = cutoff / nyquist
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
# 应用滤波器
def lowpass_filter(data, cutoff, fs, order=5):
b, a = butter_lowpass(cutoff, fs, order=order)
y = lfilter(b, a, data)
return y
# 示例应用
cutoff = 50 # 截止频率
order = 6 # 滤波器阶数
filtered_signal = lowpass_filter(x, cutoff, fs, order)
巴特沃斯滤波器
巴特沃斯滤波器具有平滑的频率响应。通过scipy.signal.butter函数设计。这种滤波器以其平坦的通带特性而闻名,能够在通带内保持较一致的幅度响应,非常适合需要避免频率失真的应用场合。
from scipy.signal import butter, filtfilt
# 设计巴特沃斯滤波器
b, a = butter(4, 0.2)
# 应用滤波器
filtered_signal = filtfilt(b, a, x)
切比雪夫滤波器
切比雪夫滤波器具有较陡的截止频率响应。通过scipy.signal.cheby1(类型I)和scipy.signal.cheby2(类型II)函数设计。这些滤波器在通带或阻带中具有等波纹性能,使得它们在特定的频率范围内可以实现更快的衰减速率,适用于对滤波器性能要求较高的情况。
from
scipy.signal import cheby1
# 设计切比雪夫滤波器
b, a = cheby1(4, 0.5, 0.2)
# 应用滤波器
filtered_signal = filtfilt(b, a, x)
椭圆滤波器
椭圆滤波器具有最陡的截止频率响应,但带有波纹。通过scipy.signal.ellip设计,这类滤波器在通带和阻带都具有等波纹特性,并且能够在较低的滤波器阶数下实现非常陡峭的截止特性,非常适合对过渡带有严格要求的应用。
from scipy.signal import ellip
# 设计椭圆滤波器
b, a = ellip(4, 0.5, 40, 0.2)
# 应用滤波器
filtered_signal = filtfilt(b, a, x)
贝塞尔滤波器
贝塞尔滤波器保持信号的相位特性。通过scipy.signal.bessel设计,这种滤波器在所有滤波器中最注重相位特性的线性,使之成为处理音频和其他需要精确相位信息的信号的理想选择。
from scipy.signal import bessel
# 设计贝塞尔滤波器
b, a = bessel(4, 0.2)
# 应用滤波器
filtered_signal = filtfilt(b, a, x)
FIR滤波器
FIR滤波器具有线性相位特性。scipy.signal还提供了firwin和firwin2函数,用于设计具有指定频率响应的有限脉冲响应(FIR)滤波器。这类滤波器通常更易于设计并且能够完全实现线性相位特性。
from scipy.signal import firwin, lfilter
# 设计FIR滤波器
numtaps = 29
cutoff = 0.2
fir_coeff = firwin(numtaps, cutoff)
# 应用滤波器
filtered_signal = lfilter(fir_coeff, 1.0, x)
除了基本的滤波器设计,scipy.signal还支持更高级的功能,如使用窗函数法设计滤波器、优化滤波器系数等。这些高级技术允许用户在保证滤波性能的同时,优化滤波器的结构和效率。使用这些滤波方法时,你可以通过调整滤波器的阶数、截止频率、类型等参数来优化滤波器的性能。此外,scipy.signal
还提供了其他功能强大的信号处理函数,如卷积、相关、频谱分析等,以支持更复杂的信号处理任务。
3.3.2 信号分解
EMD(经验模态分解)
EMD是一种自适应信号分解方法,可以将复杂信号分解为一组本征模态函数(IMF)。
需要先下载安装 PyEMD 库:
pip install EMD-signal
以下为使用EMD分解信号的示例:
import numpy as np
import PyEMD
# 示例信号
x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 10 * t)
# 进行EMD分解
emd = PyEMD.EMD()
IMFs = emd.emd(x)
# 绘制IMFs
plt.figure(figsize=(12, 9))
for i, imf in enumerate(IMFs):
plt.subplot(len(IMFs), 1, i + 1)
plt.plot(t, imf)
plt.title(f'IMF {i+1}')
plt.tight_layout()
plt.show()
4. 多模态数据与人工智能
该部分内容在之前参加LLM专题组队学习做了笔记,在此不再赘述。详细笔记可以参考一下LLM专题~
https://blog.csdn.net/weixin_42914989/category_12646043.html
学习心得
本章学习为数学建模导论的最后一章,接下来就要进入真题演示了~
本章主要介绍了图像、文本、数字信号、多模态数据四个大方向。
图像从最基本的像素入手,介绍了数字图像的基本概念和如何使用OpenCV库操作图片(读取、旋转、叠加、腐蚀、锐化等)。有效的特征点检测是很多计算机视觉任务的基础,包括图像匹配、物体识别和追踪等,学习了以下几种算子:Sobel算子、Canny算子、Harris角点检测、ORB特征点检测。其中ORB(Oriented FAST and Rotated BRIEF)特征点是一种快速且高效的局部特征点提取和描述方法,它结合了FAST特征点检测算法和BRIEF描述子算法,并通过一系列改进和融合实现了更高的效率和鲁棒性。
计算机视觉中卷积神经网络和YOLO常用于图片分类,U-Net模型用于图像分割,GAN模型根据给定的输入信息,生成一张新的图像。
在NLP领域,文本嵌入表示是将文本转换为向量形式,使得计算机能够处理和理解自然语言。常见的嵌入方法包括词袋模型、TF-IDF、Word2Vec、GloVe、BERT等。
文中介绍了TextCNN和RNN用于文本分类,LDA(隐狄利克雷分布)话题模型用于发现文档集合中的主题。
数字信号处理中介绍了傅里叶变换的应用,列举了一些常见的数字信号统计指标的定义。介绍了常用滤波器(低通滤波器、巴特沃斯滤波器、切比雪夫滤波器等),同时使用PyEMD库展示将复杂信号分解为一组本征模态函数。