• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

deja-s

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

神经网络训练不确定性

基于MC Dropout(蒙特卡罗丢弃法)获取神经网络Uncertainty(不确定性)

作用:

一般的神经网络可以有很多输出,但是无法确定网络的输出是否可靠,即无法确定有多大的把握可以相信网络的输出。如果网络输出结果的同时能够得出不确定性,那么在处理一些问题的时候能够更加灵活。

原理:

基于贝叶斯公式

实现

可使用蒙特卡罗方法实现,如MC Dropout。

主要步骤:
  1. 在网络输出之前给某些层加上dropout
  2. 网络训练的时候使用特定的损失函数进行优化
  3. 在测试网络时,需要将dropout打开,将网络运行N次,得到N个输出
  4. 统计N个输出的均值和方差,均值可作为输出结果,方差可作为不确定性

补充:获取不确定性不一定要用方差,也可以直接是神经网络的输出

损失函数(回归)

一般为:
\(L=\frac{1}{D}\sum_i\frac{1}{2}\hat{\sigma}^2{\bigg\lVert y_i-\hat{y}_i\bigg\lVert}^2+\frac{1}{2}log\hat{\sigma}^2\)

代码:

    '''
    使用RDN网络预测根据图像上下文像素预测完整图像的一个例子
    '''
    # 开启dropout
    def enable_dropout(model):
    for m in model.modules():
        if type(m) == nn.Dropout:
            m.train()

    # 定义模型
    model = RDN(
                num_channels=3,
                num_features=args.num_features,
                growth_rate=args.growth_rate,
                num_blocks=args.num_blocks,
                num_layers=args.num_layers
            ).to(device)
    #加载权重
    state_dict = model.state_dict()
    for n, p in torch.load(args.weights_file, map_location=lambda storage, loc: storage).items():
        if n in state_dict.keys():
            state_dict[n].copy_(p)
        else:
            raise KeyError(n)
    # eval模式默认不启用dropout,这里将其开启
    model.eval()
    enable_dropout(model)

    # 处理模型输入参数
    t = Image.open(args.image_file).convert('RGB')
    p, t = get_p(t, t.height, t.width, 3)
    p = np.expand_dims(np.array(p).astype(np.float32).transpose([2, 0, 1]), 0) / 255.0
    t = np.expand_dims(np.array(t).astype(np.float32).transpose([2, 0, 1]), 0) / 255.0
    p = torch.from_numpy(p).to(device)
    t = torch.from_numpy(t).to(device)

    # 回归模型预测结果集合,因为将模型运行args.num_DS次以获取方差,所以需要记录每一次预测结果
    preds = []

    # 将模型运行args.num_DS次以获取方差
    for i in range(args.num_DS):
        with torch.no_grad():
            log_sigma_2 = model(p)
        preds.append(pred)

    # 计算方差作为不确定性
    uncertain_e = torch.var(torch.cat(preds), dim=0).permute(1, 2, 0)
    # 计算均值作为预测结果
    preds_mean = torch.mean(torch.cat(preds), dim=0).permute(1, 2, 0)
    p = p.squeeze(0).permute(1, 2, 0)
    t = t.squeeze(0).permute(1, 2, 0)

posted on 2022-05-10 20:19  DJVQ  阅读(558)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3