栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

2021SC@SDUSC-山东大学软件工程与实践-Senta(七)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021SC@SDUSC-山东大学软件工程与实践-Senta(七)

本期分析Senta中的评估标准Metric

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import time
import numpy as np

from scipy.stats import pearsonr, spearmanr
from six.moves import xrange
import paddle.fluid as fluid
from functools import partial

def scale_l2(x, norm_length):
    """
    # copy lines from here https://github.com/tensorflow/models/blob/master/research/adversarial_text/adversarial_losses.py#L190
    # shape(x) = (batch, num_timesteps, d)
    # Divide x by max(abs(x)) for a numerically stable L2 norm.
    # 2norm(x) = a * 2norm(x/a)
    # Scale over the full sequence, dims (1, 2)
    """

    alpha = fluid.layers.reduce_max(fluid.layers.abs(x), dim=1, keep_dim=True) + 1e-12
    l2_norm = alpha * fluid.layers.sqrt(
            fluid.layers.reduce_sum(fluid.layers.pow(x / alpha), dim=1, keep_dim=True) + 1e-6)
    x_unit = x / l2_norm
    return norm_length * x_unit

paddle.fluid.layers.reduce_max(input, dim=None, keep_dim=False, name=None) :对指定维度上的Tensor元素求最大值运算,并输出相应的计算结果。
input (Variable)- 输入变量为多维Tensor或LoDTensor,支持数据类型为float32,float64,int32,int64。

dim (list | int ,可选)- 求最大值运算的维度。如果为None,则计算所有元素的最大值并返回包含单个元素的Tensor变量,否则必须在 [−rank(input),rank(input)] 范围内。如果 dim[i]<0 ,则维度将变为 rank+dim[i] ,默认值为None。

keep_dim (bool)- 是否在输出Tensor中保留减小的维度。如 keep_dim 为true,否则结果张量的维度将比输入张量小,默认值为False。

paddle.fluid.layers.abs(x, name=None)
:绝对值激活函数。

x (Variable)- 多维Tenosr,数据类型为float32或float64。

paddle.fluid.layers.reduce_sum(input, dim=None, keep_dim=False, name=None) :
对指定维度上的Tensor元素进行求和运算,并输出相应的计算结果。

input (Variable)- 输入变量为多维Tensor或LoDTensor,支持数据类型为float32,float64,int32,int64。

dim (list | int ,可选)- 求和运算的维度。如果为None,则计算所有元素的和并返回包含单个元素的Tensor变量,否则必须在[−rank(input),rank(input)] 范围内。如果 dim[i]<0 ,则维度将变为 rank+dim[i]
,默认值为None。

keep_dim (bool)- 是否在输出Tensor中保留减小的维度。如 keep_dim
为true,否则结果张量的维度将比输入张量小,默认值为False。

def pgd_loss(ernie, labels, loss, task_fc_fn, epsilon=0.25):
    """ refer code from
    https://github.com/tensorflow/models/blob/master/research/adversarial_text/adversarial_losses.py#L145
    but we didn't use the vat loss for now
    """

    #TODO any difference with fleet_main_program or ParallelProgram or TrainProgram?
    program = fluid.default_main_program()

    param_grads = fluid.backward.append_backward(loss, parameter_list=[ernie._word_emb_name])

    # in the VAT paper code, the d is draw from a norm distribution, what's the advantage? why not use the
    # gradient of the emb directly?
    # d = fluid.layers.random_normal(shape=emb.shape)
    d = filter(lambda p: p[0].name == ernie._word_emb_name, param_grads)[0][1]
    emb = program.block(0).var(ernie._word_emb_name)

    #for _ in range(args.K_iteration):
    K_iteration = 8
    small_constant_for_finite_diff = 1e-5
    emb_hat = emb

    d = fluid.layers.gaussian_random(emb.shape)

    # it seems it can be implemented by the while loop
    for _ in range(K_iteration):
        #d = xi * utils_tf.l2_batch_normalize(d)
        d = scale_l2(d, small_constant_for_finite_diff)
        #logits_d = model.get_logits(x + d)
        #kl = utils_tf.kl_with_logits(logits, logits_d)

        emb_hat = emb_hat + d
        ernie._build_model(emb=emb_hat)
        graph_vars = task_fc_fn(ernie, labels)

        gradient = filter(lambda p: p[0].name == ernie._word_emb_name, param_grads)[0][1]
        gradient.stop_gradient = True
        d = gradient
        #Hd = tf.gradients(kl, d)[0]
        #d = tf.stop_gradient(Hd)

    d = scale_l2(d, small_constant_for_finite_diff)
    emb_hat = emb_hat + d
    ernie._build_model(emb=emb_hat)
    graph_vars = task_fc_fn(ernie, labels)

    return graph_vars['loss']

paddle.fluid.default_main_program() :
获取当前用于存储op和variable描述信息的 default main program

paddle.fluid.backward.append_backward(loss, parameter_list=None, no_grad_set=None, callbacks=None)
该接口将向主程序(main_program)追加反向部分。 完整的神经网络训练由前向和反向传播组成。但是当我们配置网络时,我们只需要指定其前向部分。
该接口使用链式法则,能够根据前向部分自动生成反向部分。

参数: loss ( Variable ) - 网络的损失变量。 parameter_list (list [str],可选)-指定优化器需要更新的参数名称列表。如果为 None ,则将更新所有参数。默认值为 None。

no_grad_set (set [str],可选)- 在 block0 ( Block ) 中要忽略梯度的 Variable 的名字的集合。所有的 Block 中带stop_gradient = True 的所有 Variable 的名字都会被自动添加到此集合中。如果该参数不为None,则会将该参数集合的内容添加到默认的集合中。默认值为 None。

callbacks (list [callable object],可选)- 回调函数列表。用于在反向传播构建中执行一些自定义作业。每次将新的梯度OP添加到程序中时,将调用其中的所有可调用对象。可调用对象必须有两个输入参数:
Block 和 context 。 Block 是将被添加到新梯度算子的块。 context 是一个映射,其键是梯度 Variable名,值是对应的原始 Variable 。除此之外, context 还有另一个特殊的键值对:键是字符串 __ current_op_desc__ ,值是刚刚触发可调用对象的梯度OP的 op_desc 。默认值为 None。

本篇到此结束,下篇将续接本篇继续分析评估标准Metric。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/650324.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号