首页 > 编程语言 >机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization

机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization

时间:2023-06-14 20:36:19浏览次数:60  
标签:Regularization grad sum 正则 libFM 参数 Adaptive data fm


本节主要介绍的是libFM源码分析的第五部分之二——libFM的训练过程之Adaptive Regularization的方法。

5.3、Adaptive Regularization的训练方法

5.3.1、SGD的优劣

在“机器学习算法实现解析——libFM之libFM的训练过程之SGD的方法”中已经介绍了基于SGD的FM模型的训练方法,SGD的方法的最大优点是其训练过程很简单,只需在计算的过程中求解损失函数对每一个参数的偏导数,从而实现对模型参数的修改。

我们都知道,FM模型对正则化参数的选择比较敏感,在SGD的训练方法中,正则化参数是通过事先指定的,选择的优劣直接影响到训练的最终效果,那么,是否存在一种方法,能够自动选择正则化参数呢?此时,可以使用Adaptive Regularization的参数训练方法。

5.3.2、Adaptive Regularization方法的理论

对于SGD的方法,在学习的过程中,将损失函数l分别对常数项的参数w0,一次项的参数wi以及交叉项的参数wi求偏导,并利用梯度下降法更新模型中的对应参数,值得注意的是,这里的正则化参数是事先指定的,如常数项的正则化参数为λ0,一次项的正则化参数为λw以及交叉项的正则化参数为λf。基于SGD的训练过程如下所示:



机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization_权重



Adaptive Regularization方法提出将正则化参数的选择过程融入到模型参数的修改过程中,达到同时修正模型的参数和正则化参数的过程。为了能够做到这点,首先需要将训练数据集S区分为用于训练模型的训练集ST和验证集SV,且S=ST∪SV。

已知FM模型可以表示为:



y^(x∣Θt+1):=wt+10+∑i=1nwt+1ixi+∑i=1n−1∑j=i+1n⟨vt+1i,vt+1j⟩xixj

其中,Θt+1表示的是第t+1代时所有模型参数的集合,包括:wt+10,wt+1i以及vt+1f。然而每一个参数都是由第t代时的参数经过SGD更新生成的,即:


wt+10=wt0−η⋅(∂l∂wt0+λ0wt0)



wt+1i=wti−η⋅(∂l∂wti+λwwti)



vt+1i,f=vti,f−η⋅(∂l∂vti,f+λfvti,f)

将上述的更新公式代入FM模型的计算公式中,得到:



y^(x∣Θt+1)=wt0−η⋅(∂l∂wt0+λ0wt0)+∑i=1nxi(wti−η⋅(∂l∂wti+λwwti))+∑i=1n−1∑j=i+1n∑f=1k[xi(vti,f−η⋅(∂l∂vti,f+λfvti,f))xj(vtj,f−η⋅(∂l∂vtj,f+λfvtj,f))]

当固定正则化参数λ0,λi以及λf时,与“机器学习算法实现解析——libFM之libFM的训练过程之SGD的方法”中所述的SGD方法一致,此时,当更新完一遍模型的参数,此时,固定模型中的参数,并利用验证集SV和SGD方法更新正则化参数:



λt+1=λt−η⋅∂l∂λ

对于回归问题:



∂l∂λ=(y^(i)−y(i))⋅∂y^(i)∂λ

对于分类问题:



∂l∂λ=(σ(y^(i)y(i))−1)⋅y(i)⋅∂y^(i)∂λ

而∂y^(i)∂λ对于不同的λ,其值为:



∂y^(i)∂λ0=−ηwt0



∂y^(i)∂λi=−η∑i=1nwtixi



∂y^(i)∂λf=−η⎡⎣∑i=1nxivt+1i,f∑j=1nxjvtj,f−∑i=1nx2ivt+1i,fvti,f⎤⎦

那么,对于Adaptive Regularization的具体过程如下所示:



机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization_机器学习_02



5.3.3、Adaptive Regularization方法的实现

Adaptive Regularization方法也是一种基于梯度的方法,因此其实现类fm_learn_sgd_element_adapt_reg类也继承自fm_learn_sgd类,其类之间的关系如下图所示:



机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization_正则化_03



Adaptive Regularization方法的实现在文件fm_learn_sgd_element_adapt_reg.h中,文件fm_learn_sgd_element_adapt_reg.h中实现了fm_learn_sgd_element_adapt_reg类,该类继承自fm_learn_sgd类,在fm_learn_sgd_element_adapt_reg类中,最重要的函数为learn函数,用于训练FM模型。函数的具体代码如下所示:

// self-adaptive-regularization 的训练
virtual void learn(Data& train, Data& test) {
    fm_learn_sgd::learn(train, test);// 输出一些训练信息,继承自fm_learn_sgd类中的方法

    std::cout << "Training using self-adaptive-regularization SGD."<< std::endl << "DON'T FORGET TO SHUFFLE THE ROWS IN TRAINING AND VALIDATION DATA TO GET THE BEST RESULTS." << std::endl; 

    // make sure that fm-parameters are initialized correctly (no other side effects)
    // 确保初始化的过程
    fm->w.init(0);
    fm->reg0 = 0;
    fm->regw = 0; 
    fm->regv = 0; 

    // start with no regularization
    // 正则化参数的初始化,全部初始化为0
    reg_w.init(0.0);
    reg_v.init(0.0);

    // 打印输出信息,包括训练样本点的条数和验证样本的条数
    std::cout << "Using " << train.data->getNumRows() << " rows for training model parameters and " << validation->data->getNumRows() << " for training shrinkage." << std::endl;

    // 基于梯度的训练过程
    for (int i = 0; i < num_iter; i++) {// 开始每一轮的迭代
        double iteration_time = getusertime();
        // SGD-based learning: both lambda and theta are learned
        // 分为lambda step和theta step
        update_means();// 计算均值和方差
        validation->data->begin();// 将验证集的指针指向开始位置
        for (train.data->begin(); !train.data->end(); train.data->next()) {
            // 计算theta相关,更新theta中的参数
            // 利用训练集训练和更新模型的参数,此时模型中的正则化参数是固定的
            sgd_theta_step(train.data->getRow(), train.target(train.data->getRowIndex()));

            // 当i=0时,不需要更新lambda
            if (i > 0) { // make no lambda steps in the first iteration, because some of the gradients (grad_theta) might not be initialized. 
                // 每次只使用validation中的一条样本
                if (validation->data->end()) {
                    update_means();// 计算均值和方差
                    validation->data->begin();// 将验证集的指针指向开始位置                  
                }
                // 计算lambda相关,更新lambda中的参数
                // 利用验证集更新正则化参数,此时模型中的参数是固定的
                sgd_lambda_step(validation->data->getRow(), validation->target(validation->data->getRowIndex()));
                validation->data->next();// 将验证集的指针指向下一条样本
            }
        }                               

        // (3) Evaluation                   
        iteration_time = (getusertime() - iteration_time);
        // 评价函数
        double rmse_val = evaluate(*validation);// 对验证集进行评测
        double rmse_train = evaluate(train);// 对训练集进行评测
        double rmse_test = evaluate(test);// 对测试集进行评测
        // 打印输出模型的评估结果
        std::cout << "#Iter=" << std::setw(3) << i << "\tTrain=" << rmse_train << "\tTest=" << rmse_test << std::endl;
        // 日志输出
        if (log != NULL) {
            // log 输出均值和方差
            log->log("wmean", mean_w);                      
            log->log("wvar", var_w);                    
            for (int f = 0; f < fm->num_factor; f++) {
                {
                    std::ostringstream ss;
                    ss << "vmean" << f;
                    log->log(ss.str(), mean_v(f));
                }
                {
                    std::ostringstream ss;
                    ss << "vvar" << f;
                    log->log(ss.str(), var_v(f));
                }
            }
            // log 输出正则化参数
            for (uint g = 0; g < meta->num_attr_groups; g++) {
                {
                    std::ostringstream ss;
                    ss << "regw[" << g << "]";
                    log->log(ss.str(), reg_w(g));
                }
                for (int f = 0; f < fm->num_factor; f++) {
                    {
                        std::ostringstream ss;
                        ss << "regv[" << g << "," << f << "]";
                        log->log(ss.str(), reg_v(g,f));
                    }
                }
            }
            // log输出训练时间和评估效果
            log->log("time_learn", iteration_time);
            log->log("rmse_train", rmse_train);
            log->log("rmse_val", rmse_val);
            log->newLine(); 
        }
    }       
}

根据上面的理论分析,Adaptive Regularization方法的学习过程分为两步:

  • 固定正则化参数,利用训练集学习更新FM模型中的参数;
  • 固定FM模型的参数,利用验证集学习更新正则化参数。

这两个过程可由下图表示:



机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization_FM_04



在代码的实现过程中,sgd_theta_step函数负责对FM模型中的参数进行学习和更新;sgd_lambda_step函数负责对正则化参数进行学习和更新。sgd_theta_step函数的具体代码如下所示:

// 计算theta相关,更新theta中的参数
void sgd_theta_step(sparse_row<FM_FLOAT>& x, const DATA_FLOAT target) {
    double p = fm->predict(x, sum, sum_sqr);// 得到样本的预测值,在fm_model中
    double mult = 0;
    // 区分分类问题还是回归问题
    if (task == 0) {
        p = std::min(max_target, p);
        p = std::max(min_target, p);
        mult = 2 * (p - target);// 梯度值的一部分
    } else if (task == 1) {
        mult = target * (  (1.0/(1.0+exp(-target*p))) - 1.0 );// 梯度值的一部分
    }

    // make the update with my regularization constants:
    // 更新每一部分的参数
    // 1、更新常数项的权重
    if (fm->k0) {
        double& w0 = fm->w0;// 常数项的权重
        double grad_0 = mult;// 梯度值
        w0 -= learn_rate * (grad_0 + 2 * reg_0 * w0);// 更新常数项的权重
    }
    // 2、更新一次项的权重
    if (fm->k1) {
        for (uint i = 0; i < x.size; i++) {
            uint g = meta->attr_group(x.data[i].id);// 取得参数对应的分组的编号
            double& w = fm->w(x.data[i].id);// 得到模型的对应一次项的参数
            grad_w(x.data[i].id) = mult * x.data[i].value;// 一次项的梯度值
            w -= learn_rate * (grad_w(x.data[i].id) + 2 * reg_w(g) * w);// 更新一次项的权重值
        }
    }
    // 3、更新交叉项的权重
    for (int f = 0; f < fm->num_factor; f++) {
        for (uint i = 0; i < x.size; i++) {
            uint g = meta->attr_group(x.data[i].id);// 取得参数对应的分组的编号
            double& v = fm->v(f,x.data[i].id);// 取得模型的对应交叉项的参数
            grad_v(f,x.data[i].id) = mult * (x.data[i].value * (sum(f) - v * x.data[i].value)); // grad_v_if = (y(x)-y) * [ x_i*(\sum_j x_j v_jf) - v_if*x^2 ]  // 交叉项的梯度值      
            v -= learn_rate * (grad_v(f,x.data[i].id) + 2 * reg_v(g,f) * v);// 更新交叉项的权重值
        }
    }   
}

在计算的过程中,利用fm_model类中的predict函数计算当前的预测值,根据回归问题或者分类问题,计算其损失函数的梯度值,如回归时为:



∂l∂θ=2(y^(i)−y(i))⋅∂y^(i)∂θ

并将2(y^(i)−y(i))作为变量mult的值。分类时为:



∂l∂θ=(σ(y^(i)y(i))−1)⋅y(i)⋅∂y^(i)∂θ

并将(σ(y^(i)y(i))−1)⋅y(i)作为变量mult的值。

在计算完变量mult的值后,分别对常数项,一次项以及交叉项的参数利用梯度下降的方法进行更新,对于上述∂y^∂θ为:



∂y^∂θ=⎧⎩⎨⎪⎪⎪⎪1xixi(∑j=1xjvj,f−xivi,f) if θ=w0 if θ=wi if θ=vi,f

利用梯度下降的方法更新的过程为:



θ=θ−η⋅(∂l∂θ+2λθ)

在libFM的实现过程中,对正则化参数进行了分组,分组的概念如下图所示:



机器学习算法实现解析——libFM之libFM的训练过程之Adaptive Regularization_正则化_05



假设有7个参数,标号分别为{0,1,2,3,4,5,6,7},假设将0和1划分到一个分组中,如下图中的2标号,同理,将2,6划分到一个分组,将3,4,5划分到一个分组中,对于同一个分组,其拥有一个单独的正则化参数。这样就能够减少正则化参数的个数。

第二个重要的部分是sgd_lambda_step函数,其具体的代码如下所示:

// 计算lambda相关,更新lambda中的参数
void sgd_lambda_step(sparse_row<FM_FLOAT>& x, const DATA_FLOAT target) {
    double p = predict_scaled(x);// 扩展后的预测值
    double grad_loss = 0;
    // 区分两类问题:回归问题和分类问题
    if (task == 0) {// 回归问题 
        p = std::min(max_target, p);
        p = std::max(min_target, p);
        grad_loss = 2 * (p - target);
    } else if (task == 1) {// 分类问题
        grad_loss = target * ( (1.0/(1.0+exp(-target*p))) -  1.0);
    }       

    // 1、更新一次项的正则化参数
    if (fm->k1) {
        lambda_w_grad.init(0.0);// 初始化
        // 将累加和分配到每一个分组中
        for (uint i = 0; i < x.size; i++) {
            uint g = meta->attr_group(x.data[i].id);// 取得当前特征对应的正则化参数的索引
            lambda_w_grad(g) += x.data[i].value * fm->w(x.data[i].id);// 在对应的分组中计算累加和 
        }
        // 修改每一个分组内的正则化参数
        for (uint g = 0; g < meta->num_attr_groups; g++) {
            lambda_w_grad(g) = -2 * learn_rate * lambda_w_grad(g); 
            reg_w(g) -= learn_rate * grad_loss * lambda_w_grad(g);
            reg_w(g) = std::max(0.0, reg_w(g));// 对修改后的正则化参数容错,防止其小于0
        }
    }

    // 2、更新交叉项的正则化参数
    for (int f = 0; f < fm->num_factor; f++) {
        // grad_lambdafg = (grad l(y(x),y)) * (-2 * alpha * (\sum_{l} x_l * v'_lf) * (\sum_{l \in group(g)} x_l * v_lf) - \sum_{l \in group(g)} x^2_l * v_lf * v'_lf)
        // sum_f_dash      := \sum_{l} x_l * v'_lf, this is independent of the groups
        // sum_f(g)        := \sum_{l \in group(g)} x_l * v_lf
        // sum_f_dash_f(g) := \sum_{l \in group(g)} x^2_l * v_lf * v'_lf
        double sum_f_dash = 0.0;
        sum_f.init(0.0);
        sum_f_dash_f.init(0.0);

        for (uint i = 0; i < x.size; i++) {
            // v_if' =  [ v_if * (1-alpha*lambda_v_f) - alpha * grad_v_if] 
            uint g = meta->attr_group(x.data[i].id);// 取得当前特征对应的正则化参数的索引
            double& v = fm->v(f,x.data[i].id);// 取得模型的对应交叉项的参数 
            double v_dash = v - learn_rate * (grad_v(f,x.data[i].id) + 2 * reg_v(g,f) * v);

            // 更新公式中的三项     
            sum_f_dash += v_dash * x.data[i].value;
            sum_f(g) += v * x.data[i].value; 
            sum_f_dash_f(g) += v_dash * x.data[i].value * v * x.data[i].value;
        }
        // 对每一个分组中的正则化参数更新
        for (uint g = 0; g < meta->num_attr_groups; g++) {
            double lambda_v_grad = -2 * learn_rate *  (sum_f_dash * sum_f(g) - sum_f_dash_f(g));  
            reg_v(g,f) -= learn_rate * grad_loss * lambda_v_grad;
            reg_v(g,f) = std::max(0.0, reg_v(g,f));// 对修改后的正则化参数容错,防止其小于0
        }
    }
}

sgd_lambda_step函数是在固定FM模型参数的前提下,利用验证数据集对每个分组中的正则化参数进行学习和更新。在这个过程中,首先是需要计算扩展后的预测值,即在利用更新后的FM模型的参数进行预测:



y^(x∣Θt+1)=wt0−η⋅(∂l∂wt0+λ0wt0)+∑i=1nxi(wti−η⋅(∂l∂wti+λwwti))+∑i=1n−1∑j=i+1n∑f=1k[xi(vti,f−η⋅(∂l∂vti,f+λfvti,f))xj(vtj,f−η⋅(∂l∂vtj,f+λfvtj,f))]

其具体的计算过程如predict_scaled函数所示:

// 扩展后的预测值,是指在模型的预测值中增加了正则项
double predict_scaled(sparse_row<FM_FLOAT>& x) {
    double p = 0.0;// 最终的预测值
    // 1、常数项
    if (fm->k0) {   
        p += fm->w0;// 常数项,注意这边并没有对常数项增加正则
    }
    // 2、一次项
    if (fm->k1) {
        // 累加每一维特征项
        for (uint i = 0; i < x.size; i++) {
            assert(x.data[i].id < fm->num_attribute);// 特征的维度的容错
            uint g = meta->attr_group(x.data[i].id);// 取得当前特征对应的正则化参数的索引
            double& w = fm->w(x.data[i].id);// 取得当前的权重 
            double w_dash = w - learn_rate * (grad_w(x.data[i].id) + 2 * reg_w(g) * w);// 更新权重
            p += w_dash * x.data[i].value; // 累加计算
        }
    }
    // 3、交叉项
    for (int f = 0; f < fm->num_factor; f++) {
        // sum和sum_sqr分别对应着交叉项计算中的两项
        sum(f) = 0.0;
        sum_sqr(f) = 0.0;
        for (uint i = 0; i < x.size; i++) {
            uint g = meta->attr_group(x.data[i].id);// 取得当前特征对应的正则化参数的索引
            double& v = fm->v(f,x.data[i].id);// 取得模型的对应交叉项的参数 
            double v_dash = v - learn_rate * (grad_v(f,x.data[i].id) + 2 * reg_v(g,f) * v);// 更新交叉项的参数
            double d = v_dash * x.data[i].value;
            sum(f) += d;
            sum_sqr(f) += d*d;
        }
        p += 0.5 * (sum(f)*sum(f) - sum_sqr(f));
    }
    return p;
}

注意:在libFM的实现中,并没有对模型的常数项增加正则项,因此在更新正则项参数时也不需要更新常数项的正则化参数。

对预测值的计算,可以参见“机器学习算法实现解析——libFM之libFM的模型处理部分”。

计算完扩展的预测值后,便开始计算损失函数对正则化参数的梯度,并对其进行更新,更新的详细步骤参见“5.3.2、Adaptive Regularization方法的理论”中的讲解。

除了上述的重要的过程外,在fm_learn_sgd_element_adapt_reg类中还提供了如下的几个函数:

  • 初始化init函数
// 初始化函数,比SGD中初始化更多的参数
virtual void init() {
    fm_learn_sgd::init();

    reg_0 = 0;// 常数项的正则化参数的初始化
    reg_w.setSize(meta->num_attr_groups);// 一次项的正则化参数
    reg_v.setSize(meta->num_attr_groups, fm->num_factor);// 交叉项的正则化参数

    // 交叉项的均值和方差
    mean_v.setSize(fm->num_factor);
    var_v.setSize(fm->num_factor);

    // 一次项的梯度的初始化
    grad_w.setSize(fm->num_attribute);
    // 交叉项的梯度的初始化
    grad_v.setSize(fm->num_factor, fm->num_attribute);
    grad_w.init(0.0);
    grad_v.init(0.0);

    lambda_w_grad.setSize(meta->num_attr_groups);// 正则化参数的梯度
    // 更新lambda时使用到的变量
    sum_f.setSize(meta->num_attr_groups);
    sum_f_dash_f.setSize(meta->num_attr_groups);

    // 日志文件
    if (log != NULL) {
        log->addField("rmse_train", std::numeric_limits<double>::quiet_NaN());
        log->addField("rmse_val", std::numeric_limits<double>::quiet_NaN());    

        log->addField("wmean", std::numeric_limits<double>::quiet_NaN());
        log->addField("wvar", std::numeric_limits<double>::quiet_NaN());
        for (int f = 0; f < fm->num_factor; f++) {
            {
                std::ostringstream ss;
                ss << "vmean" << f;
                log->addField(ss.str(), std::numeric_limits<double>::quiet_NaN());
            }
            {
                std::ostringstream ss;
                ss << "vvar" << f;
                log->addField(ss.str(), std::numeric_limits<double>::quiet_NaN());
            }
        }
        for (uint g = 0; g < meta->num_attr_groups; g++) {
            {
                std::ostringstream ss;
                ss << "regw[" << g << "]";
                log->addField(ss.str(), std::numeric_limits<double>::quiet_NaN());
            }
            for (int f = 0; f < fm->num_factor; f++) {
                {
                    std::ostringstream ss;
                    ss << "regv[" << g << "," << f << "]";
                    log->addField(ss.str(), std::numeric_limits<double>::quiet_NaN());
                }
            }
        }
    }
}

init函数主要用于对一些变量的初始化。

  • update_means函数
// 初始化相关
void update_means() {
    // 均值和方差
    mean_w = 0;
    mean_v.init(0);
    var_w = 0;
    var_v.init(0);
    // 1、计算w的均值和方差
    for (uint j = 0; j < fm->num_attribute; j++) {
        mean_w += fm->w(j);

        var_w += fm->w(j)*fm->w(j);

        for (int f = 0; f < fm->num_factor; f++) {
            mean_v(f) += fm->v(f,j);
            var_v(f) += fm->v(f,j)*fm->v(f,j);
        }
    }
    mean_w /= (double) fm->num_attribute;// 计算均值
    var_w = var_w/fm->num_attribute - mean_w*mean_w;// 计算方差

    // 2、计算v的均值和方差
    for (int f = 0; f < fm->num_factor; f++) {
        mean_v(f) /= fm->num_attribute;
        var_v(f) = var_v(f)/fm->num_attribute - mean_v(f)*mean_v(f);
    }

    // 3、重新置均值为0
    mean_w = 0;
    for (int f = 0; f < fm->num_factor; f++) {
        mean_v(f) = 0;
    }           
}

update_means函数用于对模型的参数求方差,这整个训练过程中并不起作用,只是为了log输出作为参考。

  • debug函数
// debug打印输出
void debug() {
    std::cout << "method=sgda" << std::endl;
    fm_learn_sgd::debug();          
}

参考文献

  • Rendle S. Factorization Machines[C]// IEEE International Conference on Data Mining. IEEE Computer Society, 2010:995-1000.
  • Rendle S. Factorization Machines with libFM[M]. ACM, 2012.
  • Rendle S. Learning recommender systems with adaptive regularization[C]// ACM International Conference on Web Search and Data Mining. ACM, 2012:133-142.


标签:Regularization,grad,sum,正则,libFM,参数,Adaptive,data,fm
From: https://blog.51cto.com/u_16161414/6480414

相关文章

  • 机器学习算法实现解析——libFM之libFM的训练过程概述
    本节主要介绍的是libFM源码分析的第四部分——libFM的训练。FM模型的训练是FM模型的核心的部分。4.1、libFM中训练过程的实现在FM模型的训练过程中,libFM源码中共提供了四种训练的方法,分别为:StochasticGradientDescent(SGD),AdaptiveSGD(ASGD),AlternatingLeastSquares(ALS)和MarkovCh......
  • 正则化(regularization)和归一化(normalization)
    正则化:批量归一化和dropout批量归一化和dropout作为正则化器来克服深度学习模型中的过度拟合问题。 来源您遇到过导致过拟合的大型数据集吗?过度拟合的原因之一是网络中的权重很大。具有较大网络权重的网络可能是网络不稳定的标志,其中输入的微小变化可能导致输......
  • Paper Reading: Adaptive Neural Trees
    目录研究动机文章贡献自适应神经树模型拓扑与操作概率模型与推理优化实验结果模型性能消融实验可解释性细化阶段的影响自适应模型复杂度优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位的地方。具体的细节还需要以原文......
  • 【统计数据分析专论】02-Regularization 正则化
    Regularization正则化课件翻译ModelingNonlinearRelation非线性关系建模上节课学了线性模型但是非线性模型也很重要考虑一个由基函数的线性组合定义的模型在数学中,基函数是函数空间中特定基底的元素。函数空间中的每个连续函数可以表示为基函数的线性组合,就像向量......
  • 论文解读(VAT)《Virtual Adversarial Training: A Regularization Method for Supervise
    论文信息论文标题:VirtualAdversarialTraining:ARegularizationMethodforSupervisedandSemi-SupervisedLearning论文作者:TakeruMiyato,S.Maeda,MasanoriKoyama,S.Ishii论文来源:2020ECCV论文地址:download 论文代码:download视屏讲解:click1前言提出问题:在......
  • Adaptive ship-radiated noise recognition with learnable fine-grained wavelet tra
    摘要分析海洋声环境是一项棘手的任务。背景噪声和可变信道传输环境使舰船辐射噪声的准确识别变得复杂。现有的识别系统在处理多变的水下环境方面能力较弱,在实际应用中表现......
  • 基于CANoe和Visual Studio实现Classic 和Adaptive AUTOSAR应用层调试
    “转载自维克多汽车技术(上海)有限公司,作者VectorChina”伴随“软件化”和“敏捷化”的推进,从基于域(Domain)架构到基于区域(Zonal)架构的发展,亦或OEM成立软件中心参与软件开发......
  • RA-Depth: Resolution Adaptive Self-Supervised Monocular Depth Estimation
    注:刚入门depthestimation,这也是以后的主要研究方向,欢迎同一个方向的加入QQ群(602708168)交流。1.论文简介论文题目:RA-Depth:ResolutionAdaptiveSelf-SupervisedM......
  • [20221227]Adaptive Cursor Sharing & 直方图.txt
    [20221227]AdaptiveCursorSharing&直方图.txt--//前一阵子在做优化时我想当然以为重新分析取消某个日期字段的直方图信息,就不会出现大量子光标问题,结果发现我错了.--......
  • [20221228]Adaptive Cursor Sharing & 直方图2.txt
    [20221228]AdaptiveCursorSharing&直方图2.txt--//前一阵子在做优化时我想当然以为重新分析取消某个日期字段的直方图信息,就不会出现大量子光标问题,结果发现我错了.-......