焦点损失实施

2023-11-30

In the paper引入焦点损失后,他们指出损失函数的公式如下:

enter image description here

Where

enter image description here

我在另一位作者的 Github 页面上找到了它的实现,他在自己的项目中使用了它paper。我在我拥有的分割问题数据集上尝试了该函数,它似乎工作得很好。

下面是实现:

def binary_focal_loss(pred, truth, gamma=2., alpha=.25):
    eps = 1e-8
    pred = nn.Softmax(1)(pred)
    truth = F.one_hot(truth, num_classes = pred.shape[1]).permute(0,3,1,2).contiguous()

    pt_1 = torch.where(truth == 1, pred, torch.ones_like(pred))
    pt_0 = torch.where(truth == 0, pred, torch.zeros_like(pred))

    pt_1 = torch.clamp(pt_1, eps, 1. - eps)
    pt_0 = torch.clamp(pt_0, eps, 1. - eps)

    out1 = -torch.mean(alpha * torch.pow(1. - pt_1, gamma) * torch.log(pt_1)) 
    out0 = -torch.mean((1 - alpha) * torch.pow(pt_0, gamma) * torch.log(1. - pt_0))

    return out1 + out0

我不明白的部分是pt_0和pt_1的计算。我为自己创建了一个小例子来尝试弄清楚它,但它仍然让我有点困惑。

# one hot encoded prediction tensor
pred = torch.tensor([
                     [
                      [.2, .7, .8], # probability
                      [.3, .5, .7], # of
                      [.2, .6, .5]  # background class
                     ], 
                     [
                      [.8, .3, .2], # probability
                      [.7, .5, .3], # of
                      [.8, .4, .5]  # class 1
                     ]
                    ])

# one-hot encoded ground truth labels
truth = torch.tensor([
                      [1, 0, 0], 
                      [1, 1, 0], 
                      [1, 0, 0]
                     ])
truth = F.one_hot(truth, num_classes = 2).permute(2,0,1).contiguous()

print(truth)
# gives me:
# tensor([
#         [
#          [0, 1, 1],
#          [0, 0, 1],
#          [0, 1, 1]
#         ],
#         [
#          [1, 0, 0],
#          [1, 1, 0],
#          [1, 0, 0]
#         ]
#       ])

pt_0 = torch.where(truth == 0, pred, torch.zeros_like(pred))
pt_1 = torch.where(truth == 1, pred, torch.ones_like(pred))

print(pt_0)
# gives me:
# tensor([[
#         [0.2000, 0.0000, 0.0000],
#         [0.3000, 0.5000, 0.0000],
#         [0.2000, 0.0000, 0.0000]
#         ],
#        [
#         [0.0000, 0.3000, 0.2000],
#         [0.0000, 0.0000, 0.3000],
#         [0.0000, 0.4000, 0.5000]
#        ]
#      ])

print(pt_1)
# gives me:
# tensor([[
#          [1.0000, 0.7000, 0.8000],
#          [1.0000, 1.0000, 0.7000],
#          [1.0000, 0.6000, 0.5000]
#         ],
#         [
#          [0.8000, 1.0000, 1.0000],
#          [0.7000, 0.5000, 1.0000],
#          [0.8000, 1.0000, 1.0000]
#         ]
#       ])

我不明白的是为什么在 pt_0 中我们在 torch.where 语句为 false 的地方放置零,而在 pt_1 中我们放置 1。根据我对这篇论文的理解,我本以为你应该放置 1-p,而不是放置零或一。

谁能帮我解释一下吗?


因此,您尝试理解的部分是人们通常在想要将不需要的额外计算清零时执行的过程。

再看一下公式pt:

enter image description here

下面的代码正是通过分离两个条件来实现这一点:

# if y=1
pt_1 = torch.where(truth == 1, pred, torch.ones_like(pred))
# otherwise
pt_0 = torch.where(truth == 0, pred, torch.zeros_like(pred)) 

它设置为零的地方pt_0和一在pt_1将导致输出为零,因此对贡献损失值没有影响,即:

# Because pow(0., gamma) == 0. and log(1.) == 0.
# out1 == 0. if pt_1 == 1.
out1 = -torch.mean(alpha * torch.pow(1. - pt_1, gamma) * torch.log(pt_1))
# out0 == 0. if pt_0 == 0.
out0 = -torch.mean((1 - alpha) * torch.pow(pt_0, gamma) * torch.log(1. - pt_0))

以及原因pt_0使用价值p代替1-p与你上一个问题的原因相同,即:

1 - (1 - p) == 1 - 1 + p == p

所以它可以稍后计算FL(pt) by:

# -a * pow(1 - (1 - p), gamma )* log(1 - p) == -a * pow(p, gamma )* log(1 - p)
out0 = -torch.mean((1 - alpha) * torch.pow(pt_0, gamma) * torch.log(1. - pt_0))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

焦点损失实施 的相关文章

随机推荐

  • 负面展望未按预期发挥作用

    我有一个奇怪的情况积极的前瞻按预期工作 但是负前瞻没有 请看一下下面的代码
  • 如何创建 3 路 ManyToMany 关系 django

    需要在 django admin 中对服务器 应用程序和服务器角色之间的关系进行建模 服务器可以有one or 许多应用 应用程序可以托管在one or many服务器 A Server has one or many roles for
  • 为什么在 TypeScript 中,接口中可能的数值可以转换为类实现中不可能的数值?

    今天我遇到了一个意想不到的 TypeScript 编译器行为 我想知道这是一个错误还是一个功能 可能这将是最后一个 但我想知道其背后的理由 如果我声明一个接口方法 其参数可以是string number 并创建一个实现该接口的类 那么该类方
  • 从 firebase 获取特定类别的数据

    我想对 Firebase 实时数据库中的数据进行分类 然后按类别选择它们以显示在我的 android 视图的不同部分中 但我不知道从哪里开始 我是 Firebase 的新手 我所知道的就是如何提取数据 推送到 Firebase 数据库并显示
  • 告诉转义的十六进制在字符串中结束的位置[重复]

    这个问题在这里已经有答案了 我想打印 10 Celsiusprintffunction 通常我会这样做 printf 10 xF8Celsius 其中 xF8 是度数符号的 ANSI 代码 问题是编译器获取 x 之后的所有十六进制字符并尝试
  • Android Studio:新项目与新模块

    Android Studio 使用的概念modules 而其他 IDE 例如 Eclipse 则使用projects 然而ASFile菜单可以选择创建一个New Module以及ASAnew Project 如果有的话 这两者之间有什么区别
  • 在 Big Sur 上使用 perlbrew 安装 perl 时出错

    我正在尝试使用 perlbrew 在 macOS 环境中安装 perl 版本 5 33 4 我无法理解为什么它在安装过程中失败 我开始使用安装 perlbrew curl L https install perlbrew pl bash 然
  • MVC4 中表的 Foreach 循环

    我正在使用 C 在 MVC4 中完成我的项目 我的模型中有一个 IEnumerable 列表 我使用以下循环来列出我的观点 table tbody foreach var item in Model tr td Rtn item Mem N
  • 替换单个换行符,保留多个[重复]

    这个问题在这里已经有答案了 我正在解析一个文本文件 并希望删除所有段落内换行符 同时实际上保留形成新段落的双换行符 例如 这是我的第一首诗 n没有意义 n它应该走多远 没有人知道 n n这里是一秒钟 n那并不长 再见 n n 打印出来后 应
  • 如何修复:类文件 com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator 中的未知常量标记 32

    今天早些时候我遇到了以下异常 Unknown constant tag 32 in class file com sun org apache xerces internal impl xs XMLSchemaValidator 我没有做任
  • 有没有办法从堆栈溢出下载所有问题和答案?

    我有兴趣查看网站使用情况 问题类型和堆栈溢出的答案 有没有办法下载全部内容 我考虑过使用 beautiful soup 或类似的网页抓取作为一种选择 但我认为有如此多的专家用户 可以通过 API 轻松获得信息 是的 正如你猜的那样 有一个
  • Quartz.NET 运行作业自行重新安排?

    我完全以编程方式创建了一个 Quartz NET 作业 没有配置文件等 它按计划运行良好 该作业使用 cron 字符串初始化 每 5 分钟运行一次 我想让作业根据环境更改其自身的计划 例如 随着时间的推移会发生错误 因此 cron 应该更改
  • PublishJMS 处理器无法将消息写入 IBM Websphere MQ

    我在通过 PublishJMS 处理器将消息发布到 IBM Websphere MQ 队列时遇到问题 配置PublishJMS处理器和JMS控制器服务 我已经验证MQ连接没有问题 我相信我需要在 PublishJMS 或控制器服务中设置一些
  • 当我选择 UITableViewCell 时,我的视图控制器标签是后面的操作

    我有一个带有表视图的视图控制器 我还有一种方法 当选择表视图的单元格之一时 该方法应该推送到新的视图控制器 新的视图控制器包含一个标签 我希望该标签显示所选单元格内容的全文 目前 当选择单元格时 先前选择的单元格的内容会显示在标签上 这是我
  • 如何在 Haskell 中向 Functor 实例声明添加类约束?

    我定义了以下数据类型 data Probability a PD mass a Ratio Int 现在我想写它是一个实例Functor collect Eq a Num b gt a b gt a b collect al map col
  • 短文本,PHP

    我得到了这个功能 function shorter text chars limit if strlen text gt chars limit return substr text 0 strrpos substr text 0 char
  • Firebase:添加新子项

    当我的应用程序启动时 我会对 Firebase 进行初始提取以提取所有数据 当我稍后将数据添加到 Firebase 时 我只希望它获取已添加的新子项 我目前正在实现这样的目标 有没有更好的方法或内置方法可以在 Firebase 中执行此操作
  • 相对源绑定 Xamarin

    我的问题是视单元 由于它属于 IssueModel 类 所以找不到 OnDelete 命令 我尝试更改 Listview 的绑定上下文 但这不会改变除上述绑定之外的任何内容 有什么方法可以更改视单元的绑定上下文 这样我就不必将命令放入 Is
  • 更新语句:错误:目标表必须是等值连接谓词的一部分

    当我尝试更新表 1 中与表 2 中的列类似的列时 出现此错误 目标表必须是等值连接谓词的一部分 update test set category t1 category from category type t1 test t2 where
  • 焦点损失实施

    In the paper引入焦点损失后 他们指出损失函数的公式如下 Where 我在另一位作者的 Github 页面上找到了它的实现 他在自己的项目中使用了它paper 我在我拥有的分割问题数据集上尝试了该函数 它似乎工作得很好 下面是实现