媒介
学习多模态的话题可以从深度学习的分类使命出发,因为分类使命是最直观的可以观察到差异模态的数据,通过输入数据到模型中,我们可以看到模型是怎样学习到数据的特性向量的,同时分类使命的模型也是实现更复杂使命模型的底子。从分类使命中可以了解到图像、文本、语音在模型的特性向量是什么。
以飞浆的多模态视频分类模型为例,这个模型基于真实的短视频业务数据,融合文本、视频图像、音频三种模态举行视频多模标签分类,相比只使用视频图像特性,明显提升了高层语义标签的效果。模型架构图如下:
,
在该模型中,差异模态的数据通过差异的处置惩罚方式举行特性提取和融合。比如,文本数据可以通过词嵌入的方式转换为特性向量,视频和音频数据可以通过卷积神经网络和循环神经网络提取特性。这些特性向量颠末融合层举行特性融合,终极输入到分类层举行分类。通过这个例子,我们可以看到怎样将差异模态的数据转换为特性向量,以及怎样通过特性融合提高模型的分类性能。
从上述段落中可以看出,该模型架构包含了三种数据类型的输入(图像、文本、语音),而且根据差异的数据类型拆分成差异的模型举行学习。为了能够将这些数据输入到深度学习模型中举行学习,必要先将它们转换成数字类型的向量。这个过程称为特性工程,其目标是将原始数据转换成能够被深度学习模型所明白的特性向量。具体来说,对于图像数据,可以使用卷积神经网络(CNN)来提取特性;对于文本数据,可以使用词嵌入(Word Embedding)等技术将单词转换成向量表现;对于语音数据,可以使用声学特性提取技术,如Mel频率倒谱系数(MFCC)等来提取特性。颠末特性工程处置惩罚后,这些数据就可以被送入相应的模型举行学习。
在模型的输出层,必要将三种模型所学习到的特性向量举行归并,以获得终极的分类效果。归并方法通常使用简朴的向量拼接(Concatenation)大概加权匀称(Weighted Average)等方式举行。具体的归并方法可以根据现实情况举行选择,以获得最佳的性能。
输入层,数据集转为特性向量
图像
在计算机视觉中,图像通常以矩阵情势表现。
这个矩阵由多个向量组成,可以通过卷积、激活函数和池化等操纵提取出图像的特性。在这个过程中,每个向量都代表着图像中的某些信息,如边沿、纹理等。最后,在全连接层中,全部的特性向量被展平成一个向量,用来表现整个图像的特性。可以将这个向量看做是将图像从左到右、从上到下拆分成多少块,按照顺序分列得到的。通过这种方式,我们可以将复杂的图像信息转换成一个向量表现,方便后续的呆板学习模型举行处置惩罚。
语音

对于语音信号的处置惩罚,通常必要举行预处置惩罚和特性提取,以便为后续的语音辨认模型提供高质量的输入语音预处置惩罚通常包罗以下步调:
- 语音信号的采集:通过麦克风或其他灌音装备网络语音信号。
- 信号增益调整:根据录制情况和麦克风特性等因素,对信号举行增益调整,以包管信号的质量。
- 降噪处置惩罚:对信号举行降噪处置惩罚,去除灌音中的噪声、杂音等干扰信号。
- 分帧处置惩罚:将信号划分成多少小段,每一小段称为一帧,通常每帧的长度在10ms-30ms之间。
- 加窗:对每帧信号应用窗函数(比方汉明窗),以淘汰频谱走漏的影响。
- 傅里叶变更:对每帧信号举行快速傅里叶变更(FFT),以将时域信号转换为频域信号。
- Mel滤波器组:将频域信号通过一组Mel滤波器,得到每个滤波器的输出能量。
- 对数变更:对每个滤波器的输出能量取对数,以提高计算精度并将能量值范围缩小。
- 倒谱变更:对每个滤波器的对数能量值举行离散余弦变更(DCT),以提取频率特性,得到MFCC系数。 8. 特性归一化:对提取出的特性举行归一化处置惩罚,以消除差异语言人、差异录制装备等因素对特性的影响。
- 特性拼接:将相邻帧的特性举行拼接,以提高特性的时序信息。
- 数据增强:通过对语音信号举行变更、扰动等操纵,增长数据量和多样性,提高模型的泛化本领。
从上面步调来看语音转换主要涉及到的技术是时域信号转频域信号,和mel滤波器转换,这里增补这二个部分的内容。
什么是时域信号,什么是频域信号
时域分析是指将信号看作是时间的函数,通过对信号在时间轴上的厘革举行分析
频域分析则是将信号看作是频率的函数,通过对信号在频率轴上的分解和重修来分析信号的特性
图像
信号就是我们的数据,以图像来说信号就是差异的像素级,也可以说差异值的像素,图像在时域上看表现的是信号的空间位置关系,也就是我们人眼看到一张图片,就是图像的时域信号,
图像的频域,就雷同于图像直方图一样,将差异的像素级结合像素级在图像中的数目,绘制出的图。
对应到语音同理
语音跟图像像素级一样也有区分,语音按差异的声音频率区分差异的语音数据,
在时域上抽象看,就是我们听到的一段声音,假如把它放到2维图像中,就一段语音(差异频率的语音信号叠加到一起),在时间维度上的振幅巨细和变更。语音信号在时域上是一个一连的波形,由多个频率身分叠加而成
语音频域,将语音信号分解为差异频率的正弦波身分,并计算每个频率身分的幅度、相位等特性
将一个语音信号转换为频域表现通常必要举行傅立叶变更。
语音信号转换 - 1.傅立叶变更
傅立叶变更是一种将时域信号转换为频域信号的数学方法。
下面是一个简朴的例子,用于阐明怎样将一个简朴的声音信号举行傅立叶变更。假设我们有一个长度为1000个采样点的声音信号,此中每个采样点的值在-1到1之间。我们可以将这个信号看作一个在时间上一连的函数,用 f ( t ) f(t) f(t)表现。
为了将 f ( t ) f(t) f(t)转换为频域表现,我们必要计算它的傅立叶变更。傅立叶变更将 f ( t ) f(t) f(t)分解为差异频率的正弦波的和。
具体来说,它将 f ( t ) f(t) f(t)表现为以下情势: f ( t ) = ∑ k = − ∞ ∞ c k e 2 π k t / T f(t)=\sum_{k=-\infty}^\infty c_ke^{2\pi kt/T} f(t)=∑k=−∞∞cke2πkt/T此中, c k c_k ck是一个复数系数, k k k是频率, T T T是信号的周期。这个公式意味着,原始信号可以表现为很多频率为 k k k的正弦波的加权和,此中权重由 c k c_k ck给出。我们可以使用离散傅立叶变更(Discrete Fourier Transform, DFT)将 f ( t ) f(t) f(t)转换为频域表现,得到一个包含1000个复数值的向量 F k F_k Fk,此中每个值对应于一个频率。具体来说, F k F_k Fk表现信号中频率为 k k k的正弦波的复数系数。
在实践中,我们可以使用现有的计算库来执行傅立叶变更,而无需手动计算每个系数。在Python中,可以使用NumPy库的fft函数来计算DFT。以下是一个示例代码
- import numpy as np
- # 生成一个简单的声音信号
- t = np.linspace(0, 1, 1000)
- f = 440 # 频率为440Hz
- signal = np.sin(2 * np.pi * f * t)
- # 计算DFT
- dft = np.fft.fft(signal)
复制代码 在这个例子中,我们天生了一个频率为440Hz的正弦波,并使用NumPy的fft函数计算了它的DFT。dft变量包含了信号的频域表现,此中每个值对应于一个频率
将傅立叶转换的信息用梅尔频率倒谱系数(Mel Frequency Cepstral Coefficients,MFCC)转换为语谱图。
语音信号转换 - 2.梅尔频率倒谱系数
在MFCC中,通常使用LogFBank来代替Mel滤波器组的输出。LogFBank计算公式如下:
L o g F B a n k t , n = log ∑ k = 1 K H n , k S t , k LogFBank_{t,n}=\log\sum_{k=1}^{K} H_{n,k} S_{t,k} LogFBankt,n=log∑k=1KHn,kSt,k
此中, t t t表现帧数, n n n表现Mel滤波器组的序号, k k k表现FFT输出的频率索引。
H n , k H_{n,k} Hn,k表现第 n n n个Mel滤波器在第 k k k个频率处的响应, S t , k S_{t,k} St,k表现第 t t t帧在第 k k k个频率处的能量。LogFBank的效果是一个向量,此中每个元素代表一个Mel滤波器的输出能量取对数后的值。通常在MFCC中,还会进一步应用离散余弦变更(DCT)对LogFBank举行压缩,得到MFCC系数。

可以将语谱图视为一张图像,因为它具有图像的根本特性,比方宽度、高度、像素值等。
语谱图是由频谱分析的效果得到的,它将音频信号在时间和频率维度上分解,并用颜色来表现差异频率的能量强度,因此雷同于图像中的像素。在语音辨认中,将语谱图转换为特性向量是一种常见的方法,称为Mel频率倒谱系数(Mel Frequency Cepstral Coefficients, MFCCs)。
MFCCs是一种将语音信号的频率特性举行提取的方法,其根本头脑是将语谱图转换为一组特性向量,这些特性向量可以用来练习分类器或举行其他的呆板学习使命。因此,可以将语谱图看作是一种图像,并使用MFCCs将其转换为特性向量。这种方法已被广泛应用于语音辨认和相关范畴中。
文本

将文本转化为特性向量的原理是将文本中的词语映射为向量空间中的点,然后根据这些点的位置和距离来表现文本特性。常用的方法有词袋模型和词嵌入模型,下面分别先容它们的原理和公式。
词袋模型
词袋模型将每个文本看作是一个词语的聚集,忽略其词语出现的顺序和语法结构,只思量文本中每个词语的出现次数。词袋模型可以用一个向量来表现文本,此中向量的每个元素对应一个词语,其取值表现该词语在文本中出现的次数。词袋模型的公式可以表现为:
B O W ( w ) i = ∑ j = 1 n ∣ w j = v i ∣ BOW(w)_i=\sum_{j=1}^{n}|w_j=v_i| BOW(w)i=j=1∑n∣wj=vi∣
此中,BOW(w)_i表现向量w中第i个元素的值,v_i表现第i个词语,n表现文本中词语的总数,[w_j=v_i]表现假如w中第j个词语等于v_i,则该项取值为1,否则取值为0。
词嵌入模型
词嵌入模型是一种将文本中的词语映射为向量空间中的向量的方法,它能够在生存词语语义信息的同时,还思量了词语之间的相关性。常用的词嵌入模型有Word2Vec和GloVe,它们都是基于共现矩阵的方法。
以Word2Vec为例,其原理是通过神经网络将每个词语映射为一个固定长度的向量,使得在向量空间中相似的词语距离较近。Word2Vec包含两个模型:CBOW和Skip-gram,此中CBOW通过上下文推测目标词语,Skip-gram通过目标词语推测上下文。这里以Skip-gram为例,其公式可以表现为:
s o f t m a x ( v c T , v w ) = e x p ( v c T v w ) ∑ i = 1 V e x p ( v c T v i ) softmax(v^T_c,v_w)=\frac{exp(v^T_cv_w)}{\sum_{i=1}^{V}exp(v^T_cv_i)} softmax(vcT,vw)=∑i=1Vexp(vcTvi)exp(vcTvw)
此中,v_c表现上下文词语的向量,v_w表现目标词语的向量,V表现词汇表中的总词语数。公式的意义是计算给定上下文情况下,目标词语为某个词语的概率,通过最大化全部目标词语的条件概率之和,练习出每个词语对应的向量。除了Word2Vec之外,还有一些其他的词嵌入模型,比如GloVe,其公式可以表现为:
F ( p i j ) = ( w i ⋅ w j + b i + b j − l o g p i j ) 2 2 σ 2 F(p_{ij})=\frac{(w_i·w_j+b_i+b_j-logp_{ij})^2}{2\sigma^2} F(pij)=2σ2(wi⋅wj+bi+bj−logpij)2
此中,p_ij表现词语i和词语j在上下文中共现的次数占全部共现次数的比例,w_i和w_j表现词语i和词语j对应的向量,b_i和b_j表现词语i和词语j对应的偏置项,σ表现GloVe模型的超参数。下面是一个简朴的Python代码实现,演示怎样将文本转化为特性向量
- from sklearn.feature_extraction.text import CountVectorizer
- corpus = ['this is a test', 'this is another test']
- vectorizer = CountVectorizer()
- X = vectorizer.fit_transform(corpus)
- print(X.toarray())
- #run result
- [[1 1 1 0]
- [1 1 0 1]]
复制代码 可以看到,文本被转化为了一个二维矩阵,此中每行表现一个文本,每列表现一个词语,矩阵中的每个元素表现对应的词语在文本中出现的次数。这个矩阵就可以作为深度学习模型的输入特性。
输出层,多模态模型归并

输出层怎样实现多模型归并的这里用代码演示一下,
- 首先,我们天生三个全连接层,分别为1024、768和256,并对它们分别举行sigmoid激活函数操纵,得到它们的输出效果。
- 然后,我们将这三个输出效果归并为一个向量 S 1 S_1 S1。
- 接着,我们将这三个全连接层归并起来,即将它们的输出效果在特性维度上拼接起来,并对拼接后的效果举行sigmoid激活函数操纵,得到 S 2 S_2 S2。
- 最后,我们比较 S 1 S_1 S1和 S 2 S_2 S2的值是否相称。
我将使用PaddlePaddle框架来实现这个过程。
- import paddle
- import numpy as np
- # 创建三个全连接层,分别为1024、768和256
- fc1 = paddle.nn.Linear(2048, 1024)
- fc2 = paddle.nn.Linear(1024, 768)
- fc3 = paddle.nn.Linear(768, 256)
- # 创建输入数据
- x = np.random.randn(1, 2048).astype('float32')
- # 分别对三个全连接层进行sigmoid激活函数操作,并将它们的输出拼接起来
- y1 = paddle.concat([paddle.to_tensor(fc1(x)), paddle.to_tensor(fc2(fc1(x))), paddle.to_tensor(fc3(fc2(fc1(x))))], axis=1)
- s1 = paddle.nn.functional.sigmoid(y1)
- # 将三个全连接层的输出拼接起来,并对拼接后的结果进行sigmoid激活函数操作
- y2 = paddle.to_tensor(fc3(paddle.concat([fc2(paddle.concat([fc1(x), fc1(x)], axis=1)), fc1(x)], axis=1)))
- s2 = paddle.nn.functional.sigmoid(y2)
- # 比较两种方法得到的输出结果是否相等
- print("s1:", s1.numpy())
- print("s2:", s2.numpy())
- print("s1 == s2:", np.allclose(s1.numpy(), s2.numpy(), rtol=1e-6))
复制代码 在运行上述代码时,我们可以看到, S 1 S_1 S1和 S 2 S_2 S2的值非常接近,几乎相称,证实这两种方法得到的输出效果雷同,而且从代码的逻辑来看,可以看到几乎一样的,只是修改了to_tensor和concat的顺序。
来源:https://blog.csdn.net/weixin_42010722/article/details/129529163
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |