在这之前,我已经通过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
首要了解它就可以 后边的几个都是基于其作的改进和优化,基本上便是三角函数的改换
参阅链接:
-
- zhuanlan.zhihu.com/p/105722023
-
- www.jianshu.com/p/06cc3f84a…
-
- 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)
其间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