声纹识别损失函数及优化方法详解

释放双眼,带上耳机,听听看~!
本文详细介绍了声纹识别中常用的损失函数,包括Triple Loss、L-Softmax、SphereFace、Center Loss,以及特征归一化的作用和优化方法,为声纹识别技术的优化提供了深入的探讨。

在这之前,我已经通过speaker Model训练获取得到声纹编码。这时,我希望这个声纹编码可以反映speaker之间的分布,如果去做?需要使用损失函数去比较prediction 和ground Truth
本次主要任务:将声纹编码经过一个分类层,得到该声音属于某一类的概率,通过训练,让概率变得更准

损失函数

1.1什么是损失函数

Prediction vs Ground Truth
每个样本经过模型之后得到一个预测值,预测值和真实值之间的差值就是损失,而计算预测值和真实值差距的一类函数就称为损失函数

1.2损失函数在声纹识别的作用

实际上是一个分类任务损失

1.3 如何将声纹编码与分类损失关联?

使用classifier 或者 classification layer
本次研究的损失函数有以下几种:

1.4 几种损失函数

1.4.1 softmax with cross-entropy

主要理解它就可以 后面的几个都是基于其作的改善和优化,基本上就是三角函数的变换

参考链接:

声纹识别损失函数及优化方法详解
其中Z是 W * x的值(两个向量相乘)
softmax的输出向量就是该样本属于各个类的概率。

softmax的问题

分类完成之后有可能出现 同一类型的差距反而比不同类型的差距大,所以我希望,改进成相同类型的差距变小,不同类型的差距变大,由此,使用一个更好的损失函数

1.4.2 Triple Loss (2015年的model)-缺点-效率低

参考链接:zhuanlan.zhihu.com/p/462539667

1.4.3 L-Softmax

其实就是将softmax 公式中的cos函数改成了ψ函数

参考链接:blog.csdn.net/s000da/arti…
主要目的就是为了让目标类型的角度变小

声纹识别损失函数及优化方法详解
最终使用函数为:

声纹识别损失函数及优化方法详解
就是将原本softmax的过程中,将原本正确的分类概率中计算公式的cos(θ)改成了cos(mθ)

1.4.4 SphereFace — A-softmax

声纹识别损失函数及优化方法详解
参考链接:blog.csdn.net/s000da/arti…

1.4.5 Center Loss

声纹识别损失函数及优化方法详解
用softmax + 数据到该类中心的距离

1.5 Feature Normalization(特征归一化)

声纹识别损失函数及优化方法详解

1.5.1 作用

前提结论:若A向量和B向量都做了归一化,则L2 dis = cos dis
公式转换之后,决定一个数据在每一类的概率只取决于cos(θ)(角度),从而使系统聚焦于角度

1.5.2 为什么要乘以一个系数

这个系数一般很大 取30 50之类的数字
  • 1。若不乘系数,则因为所有向量的模都是1,则所有的feature分布在一个以半径为1的球面中(不确定)无法分的很清楚,半径扩大,则表示更清晰
  • 2.feature normal之后有问题 -cos(θ)《=1,但是softmax中需要取指数,乘系数后分的更清楚

1.6AMSoftmax & Cosface

这两个文章做的是同一件事情

1.7 AAM Softmax

声纹识别损失函数及优化方法详解
代码步骤简述:

... #调用之前需要先自定义损失函数类,此处使用的是AAMsoftmax
#实例化自己的损失函数
self.speaker_loss    = AAMsoftmax(n_class = n_class, m = m, s = s).cuda()
...
#获取到声纹编码之后
speaker_embedding = self.speaker_encoder.forward(data.cuda(), aug = True)#获取speaker_embedding
#将speaker_embedding 和 labels放入loss函数中 nloss-》loss的值 prec:训练后 预测的准确度
nloss, prec       = self.speaker_loss.forward(speaker_embedding, labels)
nloss, prec       = self.speaker_loss.forward(speaker_embedding, labels)		
nloss.backward()#将loss回传给整个的network
self.optim.step()#更新network -本次训练已完成
#下面是打印准确度等
index += len(labels) 
top1 += prec #循环完成后所有的准确度 --Acc = 所有准确度/训练总数据
loss += nloss.detach().cpu().numpy()#Loss = 所有的loss/mimibatch总数
sys.stderr.write(time.strftime("%m-%d %H:%M:%S") + 
" [%2d] Lr: %5f, Training: %.2f%%, "    %(epoch, lr, 100 * (num / loader.__len__())) + 
" Loss: %.5f, ACC: %2.2f%% r"        %(loss/(num), top1/index*len(labels)))

其中损失函数类AASoftmax如下

import torch, math
import torch.nn as nn
import torch.nn.functional as F
from tools import *

class AAMsoftmax(nn.Module): #基本就是按照公式进行三角函数的变换
    def __init__(self, n_class, m, s):# n_class 多少类的label,m:cosa+m中m的值,s:scalfaster
        
        super(AAMsoftmax, self).__init__()
        self.m = m
        self.s = s
        self.weight = torch.nn.Parameter(torch.FloatTensor(n_class, 192), requires_grad=True)
        self.ce = nn.CrossEntropyLoss()
        nn.init.xavier_normal_(self.weight, gain=1)
        self.cos_m = math.cos(self.m)
        self.sin_m = math.sin(self.m)
        self.th = math.cos(math.pi - self.m)
        self.mm = math.sin(math.pi - self.m) * self.m

    def forward(self, x, label=None):
        # 将speaker embedding 和 weight 都normalize之后相乘获取的就是cos的值
        cosine = F.linear(F.normalize(x), F.normalize(self.weight))
        sine = torch.sqrt((1.0 - torch.mul(cosine, cosine)).clamp(0, 1))#sin
        #以下就是三角函数的变换
        phi = cosine * self.cos_m - sine * self.sin_m
        phi = torch.where((cosine - self.th) > 0, phi, cosine - self.mm)
        one_hot = torch.zeros_like(cosine)
        one_hot.scatter_(1, label.view(-1, 1), 1)
        output = (one_hot * phi) + ((1.0 - one_hot) * cosine)
        output = output * self.s
        
        loss = self.ce(output, label)#获得损失(output 预测 )
        prec1 = accuracy(output.detach(), label.detach(), topk=(1,))[0]

        return loss, prec1
本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

人流量统计与人脸检测功能详解

2023-12-14 12:24:14

AI教程

构建中文段落排序数据集T2Ranking

2023-12-14 12:41:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索