深度学习:正则化-多任务学习

摘要:首先简单介绍多任务学习的方法,然后结合【1】给出权重自适应变化代价函数的原理与论文源码进行实现。使用Keras框架,参考论文链接。

目录

  1. 多任务学习简介
  2. 不确定性加权的多任务学习

主要参考文献

【1】“Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics”。

【2】“Deep learning”,花书。

1. 多任务学习简介

多任务学习通过合并几个任务重的样例提高模型的泛化能力,因此可作为一种正则化的手段。

多任务学习的模型通常包括:1. 具体任务独立的参数;2. 所有任务共享的参数。训练过程中两部分参数同时更新。

底层参数通常为共享参数,学习不同任务共有的底层表示。利用相同数据集的不同任务,底层表示可能存在某些统计关系,因此能缓解过拟合,提高泛化能力。

多任务学习常见的代价函数是不同任务的加权和
L ( W ) = ∑ I = 1 n α i L i ( W ) L({\bf{W}})=\sum_{I=1}^n\alpha_iL_i({\bf{W}}) L(W)=I=1nαiLi(W)
其中 α i \alpha_i αi是每个任务的权重,通常是手工选择或者用网格搜索的方式确定,属于额外的超参数。

2. 不确定性加权的多任务学习

文章应用在场景理解的CityScapes数据集,用不确定性加权的方式实现自适应权重的多任务学习代价函数,结论为**方法性能优于手工权重及单任务学习。 **

  1. 研究背景

多任务学习性能受权重影响较大,但手工加权的代价太大。如下图所示:在这里插入图片描述

  1. 研究问题

有效的多任务损失加权方式。

  1. 研究思路

在贝叶斯模型中,有两类可以建模的不确定性,即认知不确定性(缺少训练数据)、偶然不确定性(数据不能解释信息),认知不确定性可以通过增加训练数据缓解,偶然不确定性可以通过增加观察所有可解释变量的能力缓解。

偶然不确定性又可以分为两类,即数据依赖的异方差不确定性任务依赖的同方差不确定性,异方差不确定性取决于模型输入并作为模型输出被预测,同方差不确定性对所有输入数据保持不变而在不同任务之间变化,因此可以描述为任务依赖的不确定性。

基于最大化同方差不确定性的高斯似然,可以推导得到多任务代价函数。

具有同方差任务不确定性的多任务代价函数最终为:
L ( W , σ 1 , σ 2 , … , σ n ) = ∑ I = 1 n 1 2 σ i 2 L i ( W ) + log ⁡ σ i 2 L({\bf{W}},\sigma_1,\sigma_2,\dots,\sigma_n)=\sum_{I=1}^n\frac{1}{2\sigma_i^2}L_i({\bf{W}})+\log\sigma_i^2 L(W,σ1,σ2,,σn)=I=1n2σi21Li(W)+logσi2
其中 σ i \sigma_i σi为可学习参数,作为每个任务的权重。最后一项作为正则项防止权重 σ \sigma σ无限制增大。

  1. 方法成果

在场景理解任务中,对语义分割,实例分割,深度回归三个任务进行多任务学习,并与单任务,两个任务,之间进行对比,得到优于已有方法的结果,对比统计结果如下表所示:
在这里插入图片描述

同时在附录中说明该方法对权重的初始化值不敏感。

  1. 创新点

提出一种能根据任务同方差不确定性自适应变化的多任务代价函数,并用统一的网络结构实现三种不同的任务。

  1. 源码链接

给出论文作者提供的源码,使用Keras框架,在实验中使用了相关的方法,可以直接调用类CustomMultiLossLayer

import sys
import numpy as np
np.random.seed(0)

from keras import backend as K
from keras.layers import Input, Dense, Lambda, Layer
from keras.models import Model
from keras.initializers import Constant

class CustomMultiLossLayer(Layer):
    """Multi-task losses. Paper: https://arxiv.org/pdf/1705.07115v3.pdf. """
    def __init__(self, n_tasks=2, **kwargs):
        self.n_tasks = n_tasks
        self.is_placeholder = True
        super(CustomMultiLossLayer, self).__init__(**kwargs)
        
    def build(self, input_shape=None):
        """initialize log_var value for each task."""
        self.log_vars = []
        for i in range(self.n_tasks):
            self.log_vars += [self.add_weight(name='log_var' + str(i), shape=(1,), 
                                              initializer=Constant(0.), trainable=True)]
        super(CustomMultiLossLayer, self).build(input_shape)
        
    def multi_loss(self, ys_true, ys_pred):
        """Def multi-task loss as shown in paper."""
        assert len(ys_true) == self.n_tasks and len(ys_pred) == self.n_tasks
        loss = 0
        for y_true, y_pred, log_val in zip(ys_true, ys_pred, self.log_vars):
            precision = K.exp(-log_val[0])
            loss += K.sum(precision * (y_true - y_pred) ** 2. + log_val[0], -1)
        return K.mean(loss)
    
    def call(self, inputs):
        ys_true = inputs[:self.n_tasks]
        ys_pred = inputs[self.n_tasks:]
        loss = self.multi_loss(ys_true, ys_pred)
        self.add_loss(loss, inputs=inputs)
        return K.concatenate(inputs, -1)
    
def get_trainable_model(prediction_model):
    """ Trainable model
    # Arguments
        prediction_model: Model, standard multi-task model
    # Returns
        Model for training 
    """
    inp = Input(shape=(Q, ), name='inp')
    y1_pred, y2_pred = prediction_model(inp)
    y1_true = Input(shape=(1,), name='y1_true')
    y2_true = Input(shape=(1,), name='y2_true')
    out = CustomMultiLossLayer(n_tasks=2)([y1_true, y2_true, y1_pred, y2_pred])
    return Model([inp, y1_true, y2_true], out)
    
def get_prediction_model():
    inp = Input(shape=(Q,), name='inp')
    x = Dense(nb_features, activation='relu', name='x')(inp)
    y1_pred = Dense(D1, name='y1_pred')(x)
    y2_pred = Dense(D2, name='y2_pred')(x)
    return Model(inp, [y1_pred, y2_pred])
    
    
N = 100
nb_epoch = 2000
batch_size = 20
nb_features = 1024
Q = 1
D1 = 1  # first output
D2 = 1  # second outpu

prediction_model = get_prediction_model()
trainable_model = get_trainable_model(prediction_model)
trainable_model.compile(optimizer='adam', loss=None)
assert len(trainable_model.layers[-1].trainable_weights) == 2 
assert len(trainable_model.losses) == 1

def gen_data(N):
    X = np.random.randn(N, Q)
    w1 = 2.
    b1 = 8.
    sigma1 = 1e1  # ground truth
    Y1 = X.dot(w1) + b1 + sigma1 * np.random.randn(N, D1)
    w2 = 3
    b2 = 3.
    sigma2 = 1e0  # ground truth
    Y2 = X.dot(w2) + b2 + sigma2 * np.random.randn(N, D2)
    return X, Y1, Y2

import pylab
%matplotlib inline

X, Y1, Y2 = gen_data(N)
pylab.figure(figsize=(3, 2))
pylab.scatter(X[:, 0], Y1[:, 0])
pylab.scatter(X[:, 0], Y2[:, 0])
pylab.show()

hist = trainable_model.fit([X, Y1, Y2], nb_epoch=nb_epoch, batch_size=batch_size, verbose=0)
# Found standard deviations (ground truth is 10 and 1):
[np.exp(K.get_value(log_var[0]))**0.5 for log_var in trainable_model.layers[-1].log_vars]
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多层感知机的可变正则化是指在多层感知机中使用不同的正则化方法来控制模型的复杂度,以防止过拟合。正则化是一种常用的技术,用于在训练神经网络时对损失函数进行惩罚,以减少模型的复杂度。常见的正则化方法包括L1正则化和L2正则化。 L1正则化通过在损失函数中添加权重的绝对值之和来惩罚模型的复杂度。这可以促使模型学习到稀疏的权重,即某些权重变为0,从而减少模型的复杂度。L1正则化可以用于特征选择和模型压缩等任务。 L2正则化通过在损失函数中添加权重的平方和来惩罚模型的复杂度。这可以使模型的权重趋向于较小的值,从而减少模型的过拟合风险。L2正则化深度学习中广泛使用,可以提高模型的泛化能力。 除了L1和L2正则化,还有其他一些可变正则化方法,如弹性网络正则化和Dropout正则化。弹性网络正则化是L1和L2正则化的组合,可以在模型中引入稀疏性和权重衰减的效果。Dropout正则化是一种随机丢弃神经元的方法,可以减少模型的过拟合风险。 总之,多层感知机的可变正则化是通过使用不同的正则化方法来控制模型的复杂度,以提高模型的泛化能力和防止过拟合。 #### 引用[.reference_title] - *1* *2* *3* [多层感知机与深度学习算法概述](https://blog.csdn.net/weixin_42923076/article/details/131239167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值