迁移学习:DAN深度适配网络在风控冷启动中的应用_dan 神经网络

DAN原理简介

DAN(Deep Adaptation Netowrk)深度领域适配是迁移学习中基于特征变换迁移的一种实现,它期望通过深度神经网络为载体,训练一个网络对源域数据和目标域数据做变换使得变换后的两域分布差异(MMD)最小,同时变换后的特征能在源域上完成不错的分类效果,实现即能充分利用源域的数据和标签进行训练,也能不断弥合源域和目标领数据分布差异大的问题。直接看公式

基于特征变换的迁移学习一般范式

基于特征变换的迁移优化源域的分类器预测损失和特征变换后源域和目标域的差异损失,而DAN在此基础上将传统仅对最后一层变换的输出计算差异损失改为了最后6-8层,把MMD差异度量方式改为了MK-MMD

DAN网络结构

【一一AGI大模型学习 所有资源获取处一一】

①人工智能/大模型学习路线

②AI产品经理入门指南

③大模型方向必读书籍PDF版

④超详细海量大模型实战项目

⑤LLM大模型系统学习教程

⑥640套-AI大模型报告合集

⑦从0-1入门大模型教程视频

⑧AGI大模型技术公开课名额


MMD和MK-MMD
MMD的基本定义

迁移学习中采用MMD距离度量源域和目标域的分布差异,即两样本被映射到可再生核希尔伯特空间后的均值之差,公式如下

MMD公式

其中f(x)表示对原始特征向量做一个函数变换,对于x,y两个分布数据经过同一个函数变换之后期望之差的最大值,如果x,y数据分布完全一致,mmd等于0。
sup表示上确界,sup下面f属于函数域F表示MMD是所有可能的变换函数f得到每一个期望之差的集合里面,期望之差最大的那个结果值。MMD的基本思想就是,如果两个随机变量的任意阶都相同的话,那么两个分布就是一致的。而当两个分布不相同的话,那么使得两个分布之间差距最大的那个矩应该被用来作为度量两个分布的标准
一个任意函数f由于样本采样问题也会把完全相同分布的两个数据x,y的MMD距离计算地不限大,因此函数域F限制为再生希尔伯特空间中单位球内的一个任意向量,进一步f(x)表示再生希尔伯特空间中的向量特征向量经过核函数映射到再生希尔伯特空间中的向量的点积。
MMD经过一系列的推导,最终计算方式如下

MMD的计算

tr表示矩阵的迹,是矩阵主对角线上元素之和,在式子中是核矩阵K和M矩阵相乘的结果的迹。


高斯核函数

核函数是用来计算映射到高维空间之后的内积的一种简便方法,MMD通常采用高斯核函数对原始数据映射到高维,高斯核函数的公式如下

高斯核函数

||x-x’||表示两个数据点的欧式距离,α表示带宽,带宽是一个超参数,它决定了高斯核函数的平滑程度。


MK-MMD多核MMD

核函数的选取直接决定了MMD距离的大小,因此引入MK-MMD(多核MMD距离),通过选取多个核函数计算MMD距离,然后将这些距离以某种方式线性组合在一起作为最终的MMD结果,相当于就是核函数这个环节,用一堆核函数组合成了最终的核函数,其他步骤不变


通过MMD代码了解MMD公式

网上找的MMD tensorflwo代码实现如下

import tensorflow as tf

def guassian_kernel(source, target, kernel_mul=2.0, kernel_num=5, fix_sigma=None):
    n_s = tf.shape(source)[0]
    n_t = tf.shape(target)[0]
    n_samples = n_s + n_t
    total = tf.concat([source, target], axis=0)
    total0 = tf.expand_dims(total, axis=0)
    total1 = tf.expand_dims(total, axis=1)
    # 高斯核函数的分子
    L2_distance = tf.reduce_sum(((total0 - total1) ** 2), axis=2)
    if fix_sigma:
        bandwidth = fix_sigma
    else:
        bandwidth = tf.reduce_sum(L2_distance) / tf.cast(n_samples ** 2 - n_samples, tf.float32)
    bandwidth /= kernel_mul ** (kernel_num // 2)
    # 高斯核函数的分母
    bandwidth_list = [bandwidth * (kernel_mul ** i) for i in range(kernel_num)]
    # 高斯核函数的数学表达式
    kernel_val = [tf.exp(-L2_distance / bandwidth_temp) for bandwidth_temp in bandwidth_list]
    return sum(kernel_val)

def MMD(source, target, kernel_mul=2.0, kernel_num=5, fix_sigma=None):
    kernels = guassian_kernel(source, target,
                              kernel_mul=kernel_mul, kernel_num=kernel_num, fix_sigma=fix_sigma)
    n_s = tf.shape(source)[0]
    n_t = tf.shape(target)[0]
    XX = tf.reduce_sum(kernels[:n_s, :n_s]) / tf.cast(n_s ** 2, tf.float32)
    YY = tf.reduce_sum(kernels[-n_t:, -n_t:]) / tf.cast(n_t ** 2, tf.float32)
    XY = tf.reduce_sum(kernels[:n_s, -n_t:]) / tf.cast(n_s * n_t, tf.float32)
    YX = tf.reduce_sum(kernels[-n_t:, :n_s]) / tf.cast(n_s * n_t, tf.float32)
    loss = XX + YY - XY - YX
    return loss


以上代码包含两个部分,guassian_kernel用来计算特征向量经过多个高斯核函数组合之后最终的高斯核函数核矩阵,MMD函数是最终矩阵迹的计算过程。
先看guassian_kernel

    n_s = tf.shape(source)[0]
    n_t = tf.shape(target)[0]
    n_samples = n_s + n_t
    total = tf.concat([source, target], axis=0)
    total0 = tf.expand_dims(total, axis=0)
    total1 = tf.expand_dims(total, axis=1)
    # 高斯核函数的分子
    # 每个特征向量和其他特征向量的欧式距离矩阵
    L2_distance = tf.reduce_sum(((total0 - total1) ** 2), axis=2)


以上内容计算高斯核函数的分母,计算每个样本特征向量和其他特征向量的欧式距离,形成一个欧式距离对称阵。

    if fix_sigma:
        bandwidth = fix_sigma
    else:
        # 初始化带宽
        bandwidth = tf.reduce_sum(L2_distance) / tf.cast(n_samples ** 2 - n_samples, tf.float32)
    bandwidth /= kernel_mul ** (kernel_num // 2)


以上内容在对高斯核函数的带宽做初始化,然后分别通过构造5个带宽来构造5个核函数

    # 生成5个带宽代表5个核函数
    bandwidth_list = [bandwidth * (kernel_mul ** i) for i in range(kernel_num)]
    # 高斯核函数的数学表达式
    kernel_val = [tf.exp(-L2_distance / bandwidth_temp) for bandwidth_temp in bandwidth_list]


最终以各个核函数的加和作为总的核函数

    return sum(kernel_val)


这个函数相当于得到了核矩阵,完成了这个公式

核矩阵

这个矩阵是一个方阵,shape=[源域样本数+目标域样本数, 源域样本数+目标域样本数]。
再看MMD函数,下面代码在进行矩阵相乘

    XX = tf.reduce_sum(kernels[:n_s, :n_s]) / tf.cast(n_s ** 2, tf.float32)
    YY = tf.reduce_sum(kernels[-n_t:, -n_t:]) / tf.cast(n_t ** 2, tf.float32)
    XY = tf.reduce_sum(kernels[:n_s, -n_t:]) / tf.cast(n_s * n_t, tf.float32)
    YX = tf.reduce_sum(kernels[-n_t:, :n_s]) / tf.cast(n_s * n_t, tf.float32)


相当于公式的这一步

K*M

对照M矩阵,两个矩阵相乘再求主对角线的和如下

M矩阵

主对角线左上:Ks,s / (ns * ns) - Ks,t / (ns * t)
主对角线右下:- Kt,s * (ns * nt) + Kt,t / (nt * nt) 


上面代码计算XX,YY,XY,YX就是在进行矩阵相乘,得到对角线的元素,最后直接加和就是矩阵的迹,得到MMD。


在风控场景代码实战
问题描述

设有以下样本

群体A坏客户: 350 群体A好客户: 4800 
群体B坏客户: 1000 群体B好客户: 5500


目标是对群体A进行坏客户预测,但是A的坏客户样本明显不足,而B样本的坏客户和A客户有非常大的相似,两者的本质是相似的,只不过是因为业务范围导致不能合并建模,因此识别B中的坏客户的知识可以迁移到A任务上,模型在保证对B有不错分类效果的前提下,还能弥合AB客群的特征分布差异是本次建模的初衷。
最终模型的训练输入是全量source的x和y,70%的target的x,验证使用30%的target的x和y,测试使用全部target的x和y,是一种半监督学习方式。


网络构建

采用tensorflow1的静态图构建一个DAN网络,source和target共享底部,最终损失以source的预测损失和target的mmd损失的组合作为最终优化目标,底部网络采用两层的全连接,其中最后一层的全连接将target和source变换后的状态向量进行mmd计算。

class DAN:
    def __init__(self, feature_size, hidden_1_size, hidden_2_size, learning_rate=0.01, l2_regularizer_scale=0.01):
        self.source_input_x = tf.placeholder(tf.float32, [None, feature_size], name="source_input_x")
        self.target_input_x = tf.placeholder(tf.float32, [None, feature_size], name="target_input_x")
        self.source_input_y = tf.placeholder(tf.float32, [None], name="source_input_y")
        self.global_step = tf.Variable(0, name="global_step", trainable=False)
        self.feature_size = feature_size
        self.hidden_1_size = hidden_1_size
        self.hidden_2_size = hidden_2_size
        self.l2_regularizer_scale = l2_regularizer_scale
        self.learning_rate = learning_rate

        with tf.name_scope("share_net"):
            # dense 1
            source_dense_1_out = tf.layers.dense(self.source_input_x, self.hidden_1_size,
                                                 kernel_regularizer=tf.contrib.layers.l2_regularizer(
                                                     self.l2_regularizer_scale), name="dense_1")
            target_dense_1_out = tf.layers.dense(self.target_input_x, self.hidden_1_size,
                                                 kernel_regularizer=tf.contrib.layers.l2_regularizer(
                                                     self.l2_regularizer_scale), name="dense_1", reuse=True)
            source_dense_1_out_act = tf.nn.sigmoid(source_dense_1_out)
            target_dense_1_out_act = tf.nn.sigmoid(target_dense_1_out)
            # dense 2
            source_dense_2_out = tf.layers.dense(source_dense_1_out_act, self.hidden_2_size,
                                                 kernel_regularizer=tf.contrib.layers.l2_regularizer(
                                                     self.l2_regularizer_scale), name="dense_2")
            target_dense_2_out = tf.layers.dense(target_dense_1_out_act, self.hidden_2_size,
                                                 kernel_regularizer=tf.contrib.layers.l2_regularizer(
                                                     self.l2_regularizer_scale), name="dense_2", reuse=True)
            self.source_dense_2_out_act = tf.nn.sigmoid(source_dense_2_out)
            self.target_dense_2_out_act = tf.nn.sigmoid(target_dense_2_out)

        with tf.name_scope("output"):
            output = tf.squeeze(tf.layers.dense(self.source_dense_2_out_act, 1, activation=None))
            self.prob = tf.nn.sigmoid(output, name="prob")

        with tf.name_scope("loss"):
            self.cls_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
                labels=self.source_input_y, logits=output)) + tf.losses.get_regularization_loss()
            self.mmd_loss = MMD(self.source_dense_2_out_act, self.target_dense_2_out_act)
            self.lambd = 2 / (1 + tf.exp(-10 * self.global_step / 1000)) - 1
            self.loss = self.cls_loss + self.mmd_loss * tf.cast(self.lambd, tf.float32)

        optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate)
        self.train_step = optimizer.minimize(self.loss, global_step=self.global_step)


target和source完全使用同一个底部网络进行前向传播,使用reuse进行网络层共享,在loss组合的时候使用给mmd loss赋予权重

self.lambd = 2 / (1 + tf.exp(-10 * self.global_step / 1000)) - 1



训练过程

训练过程将全部source输入得到分类器损失,70% target输入作为计算mmd的依据,验证集以30%的target的特征输入,输出预测的target的label和实际的label进行比对得到auc,ks指标

    tf.reset_default_graph()
    model = DAN(feature_size=291, hidden_1_size=256, hidden_2_size=64, l2_regularizer_scale=0.00, learning_rate=0.005)
    saver = tf.train.Saver(tf.global_variables(), max_to_keep=1)
    with tf.Session() as sess:
        init_op = tf.group(tf.global_variables_initializer())
        sess.run(init_op)
        source_batches = get_batch(100, 512, source_x, source_y)
        target_batches = get_batch(100, 512, target_train_x, target_test_y)
        # 验证
        val_feed_dict = {model.source_input_x: target_test_x}

        train_loss_list = []
        val_loss_list = []
        val_auc_list = []
        val_ks_list = []
        loss_cls_list = []
        loss_mmd_list = []
        steps = []

        for source_batch, target_batch in zip(source_batches, target_batches):
            epoch, source_batch_x, source_batch_y = source_batch
            _, target_batch_x, _ = target_batch
            feed_dict = {model.source_input_x: source_batch_x, model.source_input_y: source_batch_y,
                         model.target_input_x: target_batch_x}
            _, step, loss_val, cls_loss_val, mmd_loss_val, lambd = sess.run(
                [model.train_step, model.global_step, model.loss, model.cls_loss, model.mmd_loss, model.lambd],
                feed_dict=feed_dict)

            if step % 1 == 0:
                print("epoch:", epoch + 1, "step:", step, "loss:", round(loss_val, 4), "cls_loss:", cls_loss_val,
                      "mmd_loss_val:", mmd_loss_val, "lambd:", lambd)
                train_loss_list.append(loss_val)
                loss_mmd_list.append(mmd_loss_val)
                loss_cls_list.append(cls_loss_val)
                steps.append(step)

            if step % 3 == 0:
                val_prob = sess.run(model.prob, feed_dict=val_feed_dict)
                batch_metrics = get_metrics(val_prob, target_test_y)
                print("{:-^30}".format("evaluation"))
                print("[evaluation]", "target_test_auc:", round(batch_metrics["auc"], 4), "target_test_ks:",
                      round(batch_metrics["ks"], 4), "\n")

                diff_auc = (batch_metrics["auc"] - max(val_auc_list)) if len(val_auc_list) else 0
                # val_loss_list.append(loss_val)
                val_auc_list.append(batch_metrics["auc"])
                val_ks_list.append(batch_metrics["ks"])
                print("本轮auc比之前最大auc{}:{}, 当前最大auc: {}".format("上升" if diff_auc > 0 else "下降", abs(diff_auc),
                                                               max(val_auc_list)))
                if diff_auc > 0:
                    saver.save(sess, os.path.join(BASIC_PATH, "./ckpt/ckpt"))
                    print("[save checkpoint]")
                print("-" * 40)
                if early_stop_auc(val_auc_list, windows=15):
                    print("{:-^30}".format("early stop!"))
                    break


训练中记录总loss,mmd loss,分类器loss随着迭代步长的收敛图如下

loss收敛

在验证集上的auc和ks情况如下

验证集auc,ks


测试

测试代码如下

def predict_pb(input_x, pb_file_no=None):
    """从pb导入模型"""
    max_time = pb_file_no
    if max_time is None:
        max_time = max(os.listdir(os.path.join(BASIC_PATH, "./tfserving")))
    print("读取pb版本:", max_time)
    with tf.Session(graph=tf.Graph()) as sess:
        tf.saved_model.loader.load(sess, [tag_constants.SERVING], os.path.join(BASIC_PATH, "./tfserving", max_time))
        graph = tf.get_default_graph()
        input_self = graph.get_operation_by_name("source_input_x").outputs[0]
        probs = graph.get_tensor_by_name("output/prob:0")
        pred = sess.run(probs, feed_dict={input_self: input_x})

    return pred


分别查看是验证集和全量target样本上的auc和ks

    pred = predict_pb(target_test_x)
    pred_2 = predict_pb(target_train_x)

    auc = roc_auc_score(target_test_y, pred)
    fpr, tpr, threshold = roc_curve(target_test_y, pred)
    ks = abs(fpr - tpr).max()
    print("test: auc:{} ks:{}".format(auc, ks))

    auc = roc_auc_score(target_train_y + target_test_y, list(pred_2) + list(pred))
    fpr, tpr, _ = roc_curve(target_train_y + target_test_y, list(pred_2) + list(pred))
    ks = abs(fpr - tpr).max()
    print("total: auc:{} ks:{}".format(auc, ks))


输出如下

读取pb版本: 1682593104
test: auc:0.7811415362731151 ks:0.43520625889046943
total: auc:0.7961154500140641 ks:0.4780751657919877


和在source上使用树模型直接在target上预测的平均效果对比如下

DAN对比source直接tree

DAN在指标上都略好于只用source训练随机森林的结果。

如何系统的去学习大模型LLM ?

作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四、AI大模型商业化落地方案

img

阶段1:AI大模型时代的基础理解
  • 目标:了解AI大模型的基本概念、发展历程和核心原理。
  • 内容
    • L1.1 人工智能简述与大模型起源
    • L1.2 大模型与通用人工智能
    • L1.3 GPT模型的发展历程
    • L1.4 模型工程
      - L1.4.1 知识大模型
      - L1.4.2 生产大模型
      - L1.4.3 模型工程方法论
      - L1.4.4 模型工程实践
    • L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
  • 内容
    • L2.1 API接口
      - L2.1.1 OpenAI API接口
      - L2.1.2 Python接口接入
      - L2.1.3 BOT工具类框架
      - L2.1.4 代码示例
    • L2.2 Prompt框架
      - L2.2.1 什么是Prompt
      - L2.2.2 Prompt框架应用现状
      - L2.2.3 基于GPTAS的Prompt框架
      - L2.2.4 Prompt框架与Thought
      - L2.2.5 Prompt框架与提示词
    • L2.3 流水线工程
      - L2.3.1 流水线工程的概念
      - L2.3.2 流水线工程的优点
      - L2.3.3 流水线工程的应用
    • L2.4 总结与展望
阶段3:AI大模型应用架构实践
  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
  • 内容
    • L3.1 Agent模型框架
      - L3.1.1 Agent模型框架的设计理念
      - L3.1.2 Agent模型框架的核心组件
      - L3.1.3 Agent模型框架的实现细节
    • L3.2 MetaGPT
      - L3.2.1 MetaGPT的基本概念
      - L3.2.2 MetaGPT的工作原理
      - L3.2.3 MetaGPT的应用场景
    • L3.3 ChatGLM
      - L3.3.1 ChatGLM的特点
      - L3.3.2 ChatGLM的开发环境
      - L3.3.3 ChatGLM的使用示例
    • L3.4 LLAMA
      - L3.4.1 LLAMA的特点
      - L3.4.2 LLAMA的开发环境
      - L3.4.3 LLAMA的使用示例
    • L3.5 其他大模型介绍
阶段4:AI大模型私有化部署
  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
  • 内容
    • L4.1 模型私有化部署概述
    • L4.2 模型私有化部署的关键技术
    • L4.3 模型私有化部署的实施步骤
    • L4.4 模型私有化部署的应用场景
学习计划:
  • 阶段1:1-2个月,建立AI大模型的基础知识体系。
  • 阶段2:2-3个月,专注于API应用开发能力的提升。
  • 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
  • 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值