东方耀AI技术分享
标题:
ArcFace loss(加性角度间隔损失)解惑:特征向量按行归一...
[打印本页]
作者:
东方耀
时间:
2020-6-5 17:01
标题:
ArcFace loss(加性角度间隔损失)解惑:特征向量按行归一...
# ArcFace loss(加性角度间隔损失)解惑:特征向量按行归一化,权重按列归一化
# ArcFace loss:Additive Angular Margin Loss(加性角度间隔损失函数),
# 对特征向量和权重归一化,对θ加上角度间隔m,角度间隔比余弦间隔在对角度的影响更加直接。
# 几何上有恒定的线性角度margin
# torch.nn.Parameter是继承自torch.Tensor的子类,其主要作用是作为nn.Module中的可训练参数使用。
# 它与torch.Tensor的区别就是nn.Parameter会自动被认为是module的可训练参数,
# 即加入到parameter()这个迭代器中去;
# 而module中非nn.Parameter()的普通tensor是不在parameter中的。
# 注意到,nn.Parameter的对象的requires_grad属性的默认值是True,即是可被训练的,
# 这与torh.Tensor对象的默认值相反
# -*- coding: utf-8 -*-
__author__ = u'东方耀 微信:dfy_88888'
__date__ = '2020/6/5 上午8:41'
__product__ = 'PyCharm'
__filename__ = 'dfy_demo01'
import torch
import torch.nn.functional as F
from torch.nn.parameter import Parameter
import numpy as np
import math
import torch.nn as nn
class dfy_model(nn.Module):
def __init__(self, in_feature, out_feature):
super(dfy_model, self).__init__()
print("自定义的模型:就一个简单的二维矩阵!")
# self.fc = nn.Linear(in_feature, out_feature, bias=False)
self.kernel = Parameter(torch.Tensor(in_feature, out_feature))
# initial kernel 初始化时就已经l2归一化了 这里是按列的
# self.kernel.data.uniform_(-1, 1).renorm_(p=2, dim=1, maxnorm=1e-5).mul_(1e5)
self.kernel.data.uniform_(-1, 1)
# pytorch在torch.nn.init中提供了常用的初始化方法函数
# torch.nn.init.eye_(self.kernel) # 单位矩阵
def forward(self, x):
# for W in self.fc.parameters():
# # 权重归一化 这样好像fc层的参数没有被归一化啊
# # pytorch归一化fc层的参数
# # 带out参数 不支持可微分的 differentiable
# # F.normalize(W, p=2, dim=1, out=W)
# W = F.normalize(W, p=2, dim=1)
kernel_norm = F.normalize(self.kernel, p=2, dim=0)
# 发现了:特征向量x的归一化(按行 dim=1) 权重矩阵的归一化(按列 dim=0)
x = F.normalize(x, p=2, dim=1)
# out2 = self.fc(x)
# out1:没有归一化weight
out1 = torch.mm(x, self.kernel)
# out2: 归一化weight
out2 = torch.mm(x, kernel_norm)
return out1, out2
my_model = dfy_model(3, 10)
embed = torch.from_numpy(np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
print(embed.size(), embed)
with torch.no_grad():
result1, result2 = my_model(embed)
print("没有归一化weight=", result1, result1.size())
print("归一化weight=", result2, result2.size())
复制代码
from torch.nn.parameter import Parameter
import torch
kernel = Parameter(torch.Tensor(2, 3))
kernel.data.uniform_(-1, 1).renorm_(p=2, dim=1, maxnorm=1e-5).mul_(1e5)
print(kernel)
kernel = torch.nn.functional.normalize(kernel, p=2, dim=0)
print(kernel)
# 输出的值是一样的
# tensor([[-0.7415, -0.2698, 0.9620],
# [ 0.6709, 0.9629, 0.2729]], requires_grad=True)
# tensor([[-0.7415, -0.2698, 0.9620],
# [ 0.6709, 0.9629, 0.2729]], grad_fn=<DivBackward0>)
复制代码
欢迎光临 东方耀AI技术分享 (http://www.ai111.vip/)
Powered by Discuz! X3.4