在这之前,我已经通过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

首要了解它就可以 后边的几个都是基于其作的改进和优化,基本上便是三角函数的改换

参阅链接:

    1. zhuanlan.zhihu.com/p/105722023
    1. www.jianshu.com/p/06cc3f84a…
    1. blog.csdn.net/u014380165/… 感官上来说:把不是0-1的数,转为0-1的概率值输出 N = 192 (声纹编码维度) T = 5994 (Mumber of speaker & class)–T代表类别数,此处表示有5994类,最终的全联接层是5994 相当所以5994选1 Ground Truth:[T * 1] (one hot)

声纹识别模型- ECAPA从0到1 -4
其间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… 首要意图便是为了让方针类型的视点变小

声纹识别模型- ECAPA从0到1 -4
最终运用函数为:

声纹识别模型- ECAPA从0到1 -4
便是将本来softmax的过程中,将本来正确的分类概率中核算公式的cos()改成了cos(m)

1.4.4 SphereFace — A-softmax

声纹识别模型- ECAPA从0到1 -4
参阅链接:blog.csdn.net/s000da/arti…

1.4.5 Center Loss

声纹识别模型- ECAPA从0到1 -4
用softmax + 数据到该类中心的距离

1.5 Feature Normalization(特征归一化)

声纹识别模型- ECAPA从0到1 -4

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

声纹识别模型- ECAPA从0到1 -4
代码步骤简述:

... #调用之前需求先自定义丢失函数类,此处运用的是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