【文献总结+代码复现+寻找创行点】语音驱动的个性化手势合成:利用自动模糊特征推理 语音驱动的个性化手势合成利用自动模糊特征推理主要总结复现前置学习复现前提环境学习Persona-Gestor 的架构Fuzzy Extractor模糊提取器归一化 AdaLN 转换器总结主要总结1. 目标介绍 Persona-Gestor一种新颖的端到端生成模型这是一种从****原始语音音频生成高度个性化的 3D 全身手势。2. 方法利用模糊特征提取器和模糊特征提取器和非自回归自适应层归一化AdaLN transformer 扩散架构来推断隐式特征并增强手势-语音同步。3. 结果在多个数据集Trinity、ZEGGS、BEAT的主观和客观评估中优于现有方法在确保高水平的手势-语音同步同时保持自然性。4. 优点无需明确的样式标签提高了可用性并在各种音频条件下表现出稳健性。5. 现有技术的不足和本文更改方法1.以前的研究中需要大量的显式特征输入特征声学语义情感个性未知和复杂的多模态处理缺少适用性。更改方法引入了模糊特征推理策略无需样式标签或额外输入。2.手势和语音之间相关性不足或过度的挑战更改方法扩散模型中结合了 AdaLN transformer 架构增强手势-语音相互作用的建模。复现前置学习模糊特征提取器and非回归自适应归一化条件机制所有令牌上用统一函数Adulnand变压器扩散架构dts——based训练推断复现前提环境学习1Ubuntu:更加快速干净轻量的操作系统方便多人合作2PythonPyTorch这个没什么可说的就是作者的python3.11版本官网升级不可用了下3.12的就好3Pytorch-lightning学习可以参考这篇文章Pytorch Lightning 完全攻略并且这篇的作者总结出来的易用于大型项目、容易迁移、易于复用的模板Pytorch-Lightning 是一个很好的库或者说是pytorch的抽象和包装。它的好处是可复用性强易维护逻辑清晰Persona-Gestor 的架构Persona-Gestor 的架构如图 所示。它由四个主要组件组成1 模糊特征提取器2 AdaLN 转换器3 手势编码器和解码器以及 4 扩散网络。总体示意图输入1噪音手势序列 2原始的演讲音频 3时间步扩散模型使用1进入手势编码器Conv1D的实现可以通过torch.nn.Conv1d类来完成卷积2模糊特征器提取key值两个放入AdaLN变压器块条件机制所有令牌上用统一函数用研究院自然语言计算组在自然语言预训练的 Transformer 模型架构提出了全新的 Denoising Masked Speech Modeling 框架注意力机制并使用扩散网络去噪生成AdaLN架构WavLM模型是一种基于HuBERT框架构建的预训练模型专门用于处理语音任务。该模型的设计重点在于语音内容的建模和发言人身份的保持。WavLM采用了Denoising Masked Speech Modeling去噪掩蔽语音建模的预训练方案。这种方法通过掩盖部分语音数据并尝试预测这些被掩盖的部分来进行训练从而增强模型对语音内容的理解能力。此外WavLM还引入了双编码器结构这种结构使得模型能够更好地处理语音数据中的复杂信息并提高模型的鲁棒性。双编码器的使用也是为了优化模型在不同语音任务上的表现使其能够更加灵活地适应不同的应用场景。在技术实现上WavLM还采用了提示感知LoRA权重适配器这是一种通过两阶段课程学习方法进行优化的技术可以帮助模型更好地理解和生成语音内容。Fuzzy Extractor模糊提取器python-fuzzy-extractor:gitHub代码Key生成defgenerate(self,value):Takes a source value and produces a key and public helper This method should be used once at enrollment. Note that the public helper is actually a tuple. This whole tuple should be passed as the helpers argument to reproduce(). :param value: the value to generate a key and public helper for. :rtype: (key, helper) ifisinstance(value,(bytes,str)):valuenp.fromstring(value,dtypenp.uint8)keynp.fromstring(urandom(self.length),dtypenp.uint8)# 就是上面算法里面的key kkey_padnp.concatenate((key,np.zeros(self.sec_len,dtypenp.uint8)))noncesnp.zeros((self.num_helpers,self.nonce_len),dtypenp.uint8)# 一个随机数masksnp.zeros((self.num_helpers,self.length),dtypenp.uint8)# 另外一个随机数digestsnp.zeros((self.num_helpers,self.cipher_len),dtypenp.uint8)# 用来保存哈希之后的数据forhelperinrange(self.num_helpers):nonces[helper]np.fromstring(urandom(self.nonce_len),dtypenp.uint8)# 初始化随机masks[helper]np.fromstring(urandom(self.length),dtypenp.uint8)# 初始化随机# By masking the value with random masks, we adjust the probability that given# another noisy reading of the same source, enough bits will match for the new# reading mask to equal the old reading mask.vectorsnp.bitwise_and(masks,value)# mask 和输入 比特与。 这个地方其实很鸡贼这样与一下能否匹配的概率就提升了因为参杂了masks的信息而masks作为辅助数据保存起来了在恢复的时候就可以利用了。# The digital locker is a simple crypto primitive made by hashing a key# xor a value. The only efficient way to get the value back is to know# the key, which can then be hashed again xor the ciphertext. This is referred# to as locking and unlocking the digital locker, respectively.forhelperinrange(self.num_helpers):d_vectorvectors[helper].tobytes()d_noncenonces[helper].tobytes()digestpbkdf2_hmac(self.hash_func,d_vector,d_nonce,1,self.cipher_len)# 这里是输入的数据d_vector 和 随机数d_nonce 运行哈希加密计算哈希码digests[helper]np.fromstring(digest,dtypenp.uint8)# 保存哈希ciphersnp.bitwise_xor(digests,key_pad)# 哈希和key XOR (是先mask哈希再XOR此时的digests足够稳定)return(key.tobytes(),(ciphers,masks,nonces))# 返回Key恢复:defreproduce(self,value,helpers):Takes a source value and a public helper and produces a key Given a helper value that matches and a source value that is close to those produced by generate, the same key will be produced. :param value: the value to reproduce a key for. :param helpers: the previously generated public helper. :rtype: key or None ifisinstance(value,(bytes,str)):valuenp.fromstring(value,dtypenp.uint8)ifself.length!len(value):raiseValueError(Cannot reproduce key for value of different length)ciphershelpers[0]maskshelpers[1]nonceshelpers[2]vectorsnp.bitwise_and(masks,value)# 首先和mask 与操作别忘了mask是同一个哦其实能否重构mask关键作用。输入的value算是一个noise扰动digestsnp.zeros((self.num_helpers,self.cipher_len),dtypenp.uint8)forhelperinrange(self.num_helpers):d_vectorvectors[helper].tobytes()d_noncenonces[helper].tobytes()digestpbkdf2_hmac(self.hash_func,d_vector,d_nonce,1,self.cipher_len)# 和同样的d_nonce计算哈希digests[helper]np.fromstring(digest,dtypenp.uint8)plainsnp.bitwise_xor(digests,ciphers)# 然后XOR和之前的ciphers 计算拿到解锁的plains如果value和之前的value足够靠近那么应该plains就和之前的key一致。# When the key was stored in the digital lockers, extra null bytes were added# onto the end, which makes it each to detect if weve successfully unlocked# the locker.checksnp.sum(plains[:,-self.sec_len:],axis1)forcheckinrange(self.num_helpers):ifchecks[check]0:returnplains[check,:-self.sec_len].tobytes()returnNoneGen过程输入w输出辅助数据P公开和均匀随机值Rl比特。Rep过程给定P输入w’重新生成均匀随机值R 。正确性如果dis(w,w’)t可以重构出精确的R如果dis(w,w’)t对Rec的输出不提供任何保证安全性辅助数据P不会泄露R的太多信息R的分布接近均匀分布。Fuzzy Extractor模糊提取器是一种密码学工具用于将不完美的生物测量数据例如指纹、面部识别、语音识别转换为安全密钥以供后续的加密通信使用。 在生物测量学中每个个体的生物测量数据都有些微差异这是由于生理和环境因素的影响因此在不同时间测量同一人的生物测量数据会存在一定的差异。这些差异使得直接使用生物测量数据作为密码并不安全因为攻击者可能会使用相似但不完全相同的生物测量数据来伪造身份。 Fuzzy Extractor 通过使用一些随机字符串和错误校正代码来处理生物测量数据生成一个安全的密钥。具体来说它由以下两个部分组成 提取器Extractor提取器会将生物测量数据和一些随机字符串输入到一个函数中生成一个密钥和一个错误校正代码。这个密钥可以用于加密和解密消息而错误校正代码可以用于后续的修复。 恢复器Recoverer恢复器接受一个在相同环境下采集的生物测量数据和一个错误校正代码用于修复之前生成的密钥。如果生物测量数据足够相似那么恢复器会生成和之前生成的密钥相同的密钥否则会输出错误。 模糊提取器和错误校正代码通常一起使用以处理生物测量数据的不完美性。归一化 AdaLN 转换器自适应层归一化adaLN是对传统层归一化的改进通过引入自适应的归一化参数生成机制使模型能够更灵活地适应不同任务和数据分布提高模型的性能和稳定性。这种方法在处理复杂任务和变化多端的数据时具有显著的优势。代码importtorchimporttorch.nnasnnclassAdaptiveLayerNorm(nn.Module):def__init__(self,normalized_shape,eps1e-5):super(AdaptiveLayerNorm,self).__init__()self.epseps self.gamma_netnn.Sequential(nn.Linear(normalized_shape,normalized_shape),nn.ReLU(),nn.Linear(normalized_shape,normalized_shape))self.beta_netnn.Sequential(nn.Linear(normalized_shape,normalized_shape),nn.ReLU(),nn.Linear(normalized_shape,normalized_shape))defforward(self,x):meanx.mean(-1,keepdimTrue)stdx.std(-1,keepdimTrue)gammaself.gamma_net(x)betaself.beta_net(x)x_normalized(x-mean)/(stdself.eps)returngamma*x_normalizedbeta# 示例用法xtorch.randn(10,20)# 假设输入形状为 (batch_size, feature_dim)ada_lnAdaptiveLayerNorm(20)outputada_ln(x)print(output)总结