精华内容
下载资源
问答
  • DOMAIN
    千次阅读
    2014-12-19 06:38:05

    文章转自:

    http://deadhorse.me/nodejs/2013/04/13/exception_and_domain.html

    https://cnodejs.org/topic/516b64596d38277306407936

    http://blog.fens.me/nodejs-core-domain/

    domain的API介绍

    基本概念

    • 隐式绑定: 把在domain上下文中定义的变量,自动绑定到domain对象
    • 显式绑定: 把不是在domain上下文中定义的变量,以代码的方式绑定到domain对象

    API介绍

    • domain.create(): 返回一个domain对象
    • domain.run(fn): 在domain上下文中执行一个函数,并隐式绑定所有事件,定时器和低级的请求。
    • domain.members: 已加入domain对象的域定时器和事件发射器的数组。
    • domain.add(emitter): 显式的增加事件
    • domain.remove(emitter): 删除事件
    • domain.bind(callback): 以return为封装callback函数
    • domain.intercept(callback): 同domain.bind,但只返回第一个参数
    • domain.enter(): 进入一个异步调用的上下文,绑定到domain
    • domain.exit(): 退出当前的domain,切换到不同的链的异步调用的上下文中。对应domain.enter()
    • domain.dispose(): 释放一个domain对象,让node进程回收这部分资源

    异步异常处理

    异步异常的特点

    由于node的回调异步特性,无法通过try catch来捕捉所有的异常:

    try {
      process.nextTick(function () {
        foo.bar();
      });
    } catch (err) {
      //can not catch it
    }
    

    而对于web服务而言,其实是非常希望这样的:

    //express风格的路由
    app.get('/index', function (req, res) {
      try {
        //业务逻辑
      } catch (err) {
        logger.error(err);
        res.statusCode = 500;
        return res.json({success: false, message: '服务器异常'});
      }
    });
    

    如果try catch能够捕获所有的异常,这样我们可以在代码出现一些非预期的错误时,能够记录下错误的同时,友好的给调用者返回一个500错误。可惜,try catch无法捕获异步中的异常。所以我们能做的只能是:

    app.get('/index', function (req, res) {
      // 业务逻辑  
    });
    
    process.on('uncaughtException', function (err) {
      logger.error(err);
    });
    

    这个时候,虽然我们可以记录下这个错误的日志,且进程也不会异常退出,但是我们是没有办法对发现错误的请求友好返回的,只能够让它超时返回。

    domain

    在node v0.8+版本的时候,发布了一个模块domain。这个模块做的就是try catch所无法做到的:捕捉异步回调中出现的异常。
    于是乎,我们上面那个无奈的例子好像有了解决的方案:

    var domain = require('domain');
    
    //引入一个domain的中间件,将每一个请求都包裹在一个独立的domain中
    //domain来处理异常
    app.use(function (req,res, next) {
      var d = domain.create();
      //监听domain的错误事件
      d.on('error', function (err) {
        logger.error(err);
        res.statusCode = 500;
        res.json({sucess:false, messag: '服务器异常'});
        d.dispose();
      });
    
      d.add(req);
      d.add(res);
      d.run(next);
    });
    
    app.get('/index', function (req, res) {
      //处理业务
    });
    

    我们通过中间件的形式,引入domain来处理异步中的异常。当然,domain虽然捕捉到了异常,但是还是由于异常而导致的堆栈丢失会导致内存泄漏,所以出现这种情况的时候还是需要重启这个进程的,有兴趣的同学可以去看看domain-middleware这个domain中间件。

    诡异的失效

    我们的测试一切正常,当正式在生产环境中使用的时候,发现domain突然失效了!它竟然没有捕获到异步中的异常,最终导致进程异常退出。经过一番排查,最后发现是由于引入了redis来存放session导致的。

    var http = require('http');
    var connect = require('connect');
    var RedisStore = require('connect-redis')(connect);
    var domainMiddleware = require('domain-middleware');
    
    var server = http.createServer();
    var app = connect();
    app.use(connect.session({
      key: 'key',
      secret: 'secret',
      store: new RedisStore(6379, 'localhost')
    }));
    //domainMiddleware的使用可以看前面的链接
    app.use(domainMiddleware({
      server: server,
      killTimeout: 30000
    }));
    

    此时,当我们的业务逻辑代码中出现了异常,发现竟然没有被domain捕获!经过一番尝试,终于将问题定位到了:

    var domain = require('domain');
    var redis = require('redis');
    var cache = redis.createClient(6379, 'localhost');
    
    function error() {
      cache.get('a', function () {
        throw new Error('something wrong');
      });
    }
    
    function ok () {
      setTimeout(function () {
        throw new Error('something wrong');
      }, 100);
    }
    var d = domain.create();
    d.on('error', function (err) {
      console.log(err);
    });
    
    d.run(ok);    //domain捕获到异常
    d.run(error); //异常被抛出
    

    奇怪了!都是异步调用,为什么前者被捕获,后者却没办法捕获到呢?

    Domain剖析

    回过头来,我们来看看domain做了些什么来让我们捕获异步的请求(代码来自node v0.10.4,此部分可能正在快速变更优化)。如果对domain还不甚了解的同学可以先简单过一下domain的文档

    node事件循环机制

    在看Domain的原理之前,我们先要了解一下nextTick_tickCallback两个方法

    function laterCallback() {
      console.log('print me later');
    }
    
    process.nextTick(laterCallback);
    console.log('print me first');
    

    上面这段代码写过node的人都很熟悉,nextTick的作用就是把laterCallback放到下一个事件循环去执行。而_tickCallback方法则是一个非公开的方法,这个方法是在当前时间循环结束之后,调用之以继续进行下一个事件循环的入口函数。

    换而言之,node为事件循环维持了一个队列,nextTick入队,_tickCallback出列。

    domain的实现

    在了解了node的事件循环机制之后,我们再来看看domain做了些什么。
    domain自身其实是一个EventEmitter对象,它通过事件的方式来传递捕获的错误。这样我们在研究它的时候,就简化到两个点:

    • 什么时候触发domain的error事件:

      • 进程抛出了异常,没有被任何的try catch捕获到,这时候将会触发整个process的processFatal,此时如果在domain包裹之中,将会在domain上触发error事件,反之,将会在process上触发uncaughtException事件。
    • domain如何在多个不同的事件循环中传递:

      1. 当domain被实例化之后,我们通常会调用它的run方法(如之前在web服务中的使用),来将某个函数在这个domain示例的包裹中执行。被包裹的函数在执行的时候,process.domain这个全局变量将会被指向这个domain实例。当这个事件循环中,抛出异常调用processFatal的时候,发现process.domain存在,就会在domain上触发error事件。
      2. 在require引入domain模块之后,会重写全局的nextTick_tickCallback,注入一些domain相关的代码
      //简化后的domain传递部分代码
      function nextDomainTick(callback) {
        nextTickQueue.push({callback: callback, domain: process.domain});
      }
      
      function _tickDomainCallback() {
        var tock = nextTickQueue.pop();
        //设置process.domain = tock.domain
        tock.domain && tock.domain.enter();
        callback();
        //清除process.domain
        tock.domain && tock.domain.exit();        
        }
      };
      

    这个是其在多个事件循环中传递domain的关键:nextTick入队的时候,记录下当前的domain,当这个被加入队列中的事件循环被_tickCallback启动执行的时候,将新的事件循环的process.domain置为之前记录的domain。这样,在被domain所包裹的代码中,不管如何调用process.nextTick, domain将会一直被传递下去。
    3. 当然,node的异步还有两种情况,一种是event形式。因此在EventEmitter构造函数有如下代码:

        if (exports.usingDomains) {
          // if there is an active domain, then attach to it.
          domain = domain || require('domain');
          if (domain.active && !(this instanceof domain.Domain)) {
            this.domain = domain.active;
          }
        }
    

    实例化EventEmitter的时候,将会把这个对象和当前的domain绑定,当通过emit触发这个对象上的事件时,像_tickCallback执行的时候一样,回调函数将会重新被当前的domain包裹住。
    4. 而另一种情况,是setTimeoutsetInterval,同样的,在timer的源码中,我们也可以发现这样的一句代码:

       if (process.domain) timer.domain = process.domain;
    

    EventEmmiter一样,之后这些timer的回调函数也将被当前的domain包裹住了。

    node通过在nextTick, timer, event三个关键的地方插入domain的代码,让它们得以在不同的事件循环中传递。

    更复杂的domain

    有些情况下,我们可能会遇到需要更加复杂的domain使用。

    • domain嵌套:我们可能会外层有domain的情况下,内层还有其他的domain,使用情景可以在文档中找到
    // create a top-level domain for the server
    var serverDomain = domain.create();
    
    serverDomain.run(function() {
      // server is created in the scope of serverDomain
      http.createServer(function(req, res) {
        // req and res are also created in the scope of serverDomain
        // however, we'd prefer to have a separate domain for each request.
        // create it first thing, and add req and res to it.
        var reqd = domain.create();
        reqd.add(req);
        reqd.add(res);
        reqd.on('error', function(er) {
          console.error('Error', er, req.url);
          try {
            res.writeHead(500);
            res.end('Error occurred, sorry.');
          } catch (er) {
            console.error('Error sending 500', er, req.url);
          }
        });
      }).listen(1337);
    });
    

    为了实现这个功能,其实domain还会偷偷的自己维持一个domain的stack,有兴趣的童鞋可以在这里看到。

    回头解决疑惑

    回过头来,我们再来看刚才遇到的问题:为什么两个看上去都是同样的异步调用,却有一个domain无法捕获到异常?理解了原理之后不难想到,肯定是调用了redis的那个异步调用在抛出错误的这个事件循环内,是不在domain的范围之内的。我们通过一段更加简短的代码来看看,到底在哪里出的问题。

    var domain = require('domain');
    var EventEmitter = require('events').EventEmitter;
    
    var e = new EventEmitter();
    
    var timer = setTimeout(function () {
      e.emit('data');  
    }, 10);
    
    function next() {
      e.once('data', function () {
        throw new Error('something wrong here');
      });
    }
    
    var d = domain.create();
    d.on('error', function () {
      console.log('cache by domain');
    });
    
    d.run(next);
    

    此时我们同样发现,错误不会被domain捕捉到,原因很清晰了:timere两个关键的对象在初始化的时候都时没有在domain的范围之内,因此,当在next函数中监听的事件被触发,执行抛出异常的回调函数时,其实根本就没有处于domain的包裹中,当然就不会被domain捕获到异常了!

    其实node针对这种情况,专门设计了一个API:domain.add。它可以将domain之外的timerevent对象,添加到当前domain中去。对于上面那个例子:

    d.add(timer);
    //or
    d.add(e);
    

    timer或者e任意一个对象添加到domain上,就可以让错误被domain捕获了。

    再来看最开始redis导致domain无法捕捉到异常的问题。我们是不是也有办法可以解决呢?
    @python发烧友 的这条微博我们就能理解,其实对于这种情况,还是没有办法实现最佳的解决方案的。现在对于非预期的异常产生的时候,我们只能够让当前请求超时,然后让这个进程停止服务,之后重新启动。graceful模块配合cluster就可以实现这个解决方案。

    domain十分强大,但不是万能的。希望在看过这篇文章之后,大家能够正确的使用domian,避免踩坑。:)


    题外推荐

    在整个问题排查与代码研究过程中,有一个工具起了巨大的作用:node-inspector,它可以让node代码在chrome下进行单步调试,能够跟进到node源码之中,@goddyzhao的文章使用node-inspector来调试node详细介绍了如何使用node-inspector


    更多相关内容
  • 2014 Deep Domain Confusion_ Maximizing for Domain Invariance.pdf
  • domain-verification

    2021-05-02 15:10:55
    安装$ npm install domain-verification用法consta domainVerification = require('domain-verification');domainVerification.html(domain_url,domain_html_name,hash_value);domainVerification.txt(domain_url,...
  • ip domain-lookup命令解释

    2018-11-07 10:32:46
    ip domain-lookup命令解释 与 实例 2500#
  • 明小子Domain4.3永久破解版
  • split-domain.js 简单的域名分割器。 安装 $ npm install split-domain --save 用法 Node.js import splitDomain from 'split-domain' const domain = splitDomain ( 'example.com' ) domain . subDomain // => ''...
  • 领域驱动设计方面的权威著作! 作者:Vaughn Vernon 书名:Implementing Domain-Driven Design 特点: PDF高清文字版
  • nodejs 模块 getDomina根据url获取到相应的域名安装方法npm install git://github....使用方法示例var getDomain = require('./../lib/getDomain');getDomain('http://www.rutube.com');结果示例rutube.com
  • Domain adaptation 与 Domain generalization

    千次阅读 2022-01-21 20:23:37
    一、Domain adaptation (DA) 1. 基本介绍 1. 什么是domain?: 一堆数据服从相同的分布。 2. Domain adaptation 研究的问题 给了一个training set 这个set可能是由一个或多个domain 构成的,给定的testing set的...

    一、Domain adaptation (DA)

    1. 基本介绍

    1. 什么是domain?:
    一堆数据服从相同的分布。
    2. Domain adaptation 研究的问题
    给了一个training set 这个set可能是由一个或多个domain 构成的,给定的testing set的domain与training set是不同的。利用training有Label 的数据训练模型,使得这个模型在testing数据上也可以使用,并且取得良好的效果。

    在经典的机器学习中,当 源域目标域 数据分布不同,但是两者的任务相同时,这种 特殊 的迁移学习就是域自适应(Domain Adaptation)。

    上面含义若看不太懂,简要解释如下:我们一般都是假设训练集和测试集分布一致,但是在实际中,训练集和测试集其实分布会有差异,因为测试场景非可控,因此存在测试集和训练集分布有很大差异的情况,这时候训练好的模型在测试集上效果却不理想,为解决这样的问题,出现了迁移学习。 简单举例来说:我们熟知的人脸识别,如果用东方人人像来训练,最后用于识别西方人,那当然性能会明显下降。
    3. Domain adaptation 的解决思路
    解决Domain adaptation问题主要的思路就是将source训练好的模型能够用在target上,域适配问题最主要的就是如何减少source和target不同分布之间的差异。

    域适配包括无监督域适配和半监督域适配,前者的target是完全没有label的,后者的target有部分的label,但是数量非常的少。

    这里主要介绍基于深度学习的方法,在我们已知finetuning之后,其实很容易想到,将在有标签的域A上训练好的模型用在无标签或者少量标签的域B上,中间的操作只需要改变输入,但是这种方式就会由于域A和域B数据分布不同导致效果并不一定会非常好,如果有方式能够减少A和B的差异,那就可以用同一个模型来跑A和B的数据。

    2. Shallow DA

    • 样本自适应 Instance adaptation :对源数据每一个样本加权,学习一组权重使得分布差异最小化,然后重新采样,从而逼近目标域的分布。源域总有一部分数据类似于目标域,找到那部分数据就可以了,越像的数据,给的权重就越大。
    • 特征自适应 Feature adaptation:将源域和目标域投影到公共特征子空间,这样两者的分布相匹配,通过学习公共的特征表示,这样在公共特征空间,源域和目标域的分布就会相同。将源域和目标域提取到一个共同的特征空间中,使他们之间足够近,足够对齐,目标域的性能就可以提升。
    • 模型自适应 Model adaptation:考虑目标域的误差,对源域误差函数进行修改。假设利用上千万的数据来训练好一个模型,当我们遇到一个新的数据领域问题的时候,就不用再重新去找几千万个数据来训练,只需把原来训练好的模型迁移到新的领域,在新的领域往往只需相对较少的数据就同样可以得到很高的精度。实现的原理则是利用模型之间存在的相似性。

    在这里插入图片描述
    以下是三种自适应的公式表达
    在这里插入图片描述

    3. Deep DA

    在深度DA中,DA大部分是特征自适应(Feature adaptation)。

    fine-tune(微调):冻结预训练模型的部分卷积层(通常是靠近输入的多数卷积层),训练剩下的卷积层(通常是靠近输出的部分卷积层)和全连接层。

    卷积神经网络的核心:
    1)浅层卷积提取基础特征,即信息是更general, 更边缘的信息,如边缘,轮廓等基础特征。
    2)深层卷积提取抽象特征,如整个脸型。越深层,提取的特征就越是特定的某个任务,即特征中融入了很多domain的信息,其特征更适用于源域而不适用目标域。

    3.1 关于Fine-tune的一个实验

    3.1 .1 实验操作
    1. 使用Dataset A,在一个固定的网络结构上进行训练得到model A(下图第一行绿色)
    2. 再使用Dataset B,在相同的网络结构上训练得到model B(下图第二行紫色)。
    3. 固定model B的前3层,在Dataset B上训练得到B3B(下图第三行上半部分),不固定model B的前3层,在Dataset B上训练得到B3B+(下图第三行下半部分)
    4. 同理固定/不固定model A的前三层,在Dataset B上训练得到A3B/A3B+(下图第四行)。
      在这里插入图片描述
    3.1 .2 实验现象解释
    1. 对于BnB(2)而言,原来训练好的B模型的前两层直接拿来就可以用,而且不需要调整,不会对精度造成影响。从3层开始有点下降,到了第4~5层,模型精度开始下降,然而到了6-7层,模型精度又奇迹般地回升了!这是为什么呢?

    作者说明如下:对于一开始精度下降的4~ 5层,确实是到了这一步,feature变得specific了,但是都是从B数据训练来的,就算4~ 5层的特征specific,那不也是数据B的特征吗?为什么会下降呢?作者认为:**中间连续层之间存在一定的相互适应调整关系,这种关系是复杂而又脆弱的,这种关系不能够仅仅通过上层学习到,所以在3层开始,我们固定底层,导致网络无法进行上下之间的相互适应调整,使得3层之后的层无法进行很好地协调而学习到相对于task很specific的特征,使得精度开始下降。**而到了6~7层,精度又回升了,这是因为网络一共就8层,你把6层都固定住了,基本上整个特征学习也被固定住了,因此精度和原来的B不会相差太多。因此作者认为:神经网络中间特征层的连续协调关系要强于最顶和最下层的,这是之前文献所没有注意到的。

    1. 对于BnB+来说(3),模型精度没有什么变化,说明finetune对模型没有损失,并且训练时间还可减少,对训练有促进作用。

    2. 对AnB来说,直接将网络的前两层迁移到B,固定住,貌似对精度不会有什么影响,这说明AlexNet的前两层学习的特征是很基础,很泛化的,因此可以直接从A迁移到B而不损失精度。到了4~ 5层,精度开始大幅下降,而到了6~ 7层,精度出现小小上升然后又下降,这是为什么呢?根据BnB的结论,我们认为这种下降由两个因素导致:1)中间层之间具有相互适应协调的依赖关系。 2)特征太specific了,导致迁移到B上特征不适用

    3. 再看AnB+,加入了finetune之后的模型,在任何时候表现都很好,甚至比base B的表现还好,这又一次说明finetune对模型有很好的促进作用!
      在这里插入图片描述

    3.1 .3 实验结果
    • 神经网络的前3层基本都是general feature,进行迁移的效果会比较好;
    • 深度迁移网络中加入fine-tune,效果会提升比较大,可能会比原网络效果还好;
    • Fine-tune可以比较好地克服数据之间的差异性;
    • 深度迁移网络要比随机初始化权重效果好;
    • 网络层数的迁移可以加速网络的学习和优化。

    3.2 Discrepancy-based DA

    衡量两个domain之间的相似性
    在这里插入图片描述

    3.2.1 DDC (Deep Domain Confusion)

    问题:两类数据的分布不同,source训练好的分类器在target不一定适用
    解决方案:在训练的时候能够同时减小source和target分布的差异,来让网络学习到更有迁移性的特征。

    如何减小差异:神经网络中额外加入一个适配层和域误差损失来自动的学习一些特征表达。主要还是利用MMD,假设映射函数为 ϕ \phi ϕ,可以采用的优化目标如下,第一项是优化监督分类器,第二项是缩小domain之间的差异。
    L = L C ( X L , y ) + λ M M D 2 ( X S , X T ) L = L_C(X_L,y)+\lambda MMD^2(X_S,X_T) L=LC(XL,y)+λMMD2(XS,XT)

    适配层增加在哪里,维数取多少:MMD能够帮助来选择放层的位置以及决定层的维数,所以相关参数的确定就通过MMD来得到。 1.经过计算source和target在网络的不同层的特征表达之间的MMD数值,最后确定放在了fc7(倒数第二层)。2.第一个经过计算source和target在网络的不同层的特征表达之间的MMD数值,最后确定维度(512维)。

    在这里插入图片描述

    3.2.2 DAN

    在DDC的基础上进行了改进:

    1. 多个全连接层(最后三层)算domain之间的MMD loss以降低domain之间的差异。
    2. 网络浅层进行特征映射的时候,使用更加复杂的高斯核的组合MMD(多核MMD)。具体实现中采用了多核MMD,根据核技巧和多核的无偏估计,能够将复杂度变成O(n),且可以正常使用SGD的方式来优化
      在这里插入图片描述

    3.3 Adversarial-based DA

    3.3.1 DANN( Domain Adversarial Neural Network ,又称 RevGrad 2016)

    解决方案:针对无监督域的自适应,提取出源域和目标域同分布的特征(绿色部分),在特征上学习分类(蓝色)。方法是利用对抗学习的思想迫使提取的特征同分布(粉色部分),而且满足分类要求。
    在这里插入图片描述
    目标函数:提取的特征满足两个要求:1)可以分类,所以该特征可以使得分类器分类损失最小;2)源域目标域特征同分布,这要求判别器难以判别样本来自哪个域,需要最大化判别器的损失。这两个损失要求相反,那就增加一个梯度反转层来实现域判别器梯度的反转。

    从以上介绍,可以看出Feature Extractor和Domain Classifier是两个对抗的部分,因此自然也是一个minimax的问题。将以上三个部分的参数分别记为 θ f , θ y , θ d \theta_{f},\theta_{y},\theta_{d} θf,θy,θd,因此得到下面优化目标:

    E ( θ f , θ y , θ d ) = Σ i ∈ S L y i ( θ f , θ y ) − λ Σ i ∈ S ∪ U L d i ( θ f , θ d ) E(\theta_{f},\theta_{y},\theta_{d})=\Sigma_{i\in S}L^{i}_{y}(\theta_{f},\theta_{y})-\lambda\Sigma_{i\in S\cup U}L^{i}_{d}(\theta_{f},\theta_{d}) E(θf,θy,θd)=ΣiSLyi(θf,θy)λΣiSULdi(θf,θd)

    其中 i ∈ S i \in S iS表示样本来自源域, L y i L^{i}_{y} Lyi代表的是分类损失,比如Multi-Class Cross-Entropy, L d i L^{i}_{d} Ldi表示Domain Classifier分类的损失(具体做法是源域的样本的Domain Label为0,目标域样本的为1,训练一个二分类器,采用Binary Cross Entropy损失)。

    那么优化过程就是下面所示的迭代过程:
    在这里插入图片描述
    为了避免迭代优化,DANN引入了一个梯度反转层(Gradient Reversal, RevGrad),主要是在Domain Classifier的梯度回传的过程中加一个反向操作,使得优化过程可以不用迭代。

    特征可视化结果:
    在这里插入图片描述

    3.3.2 MADA

    问题:目标域是源域的子集,无法直接进行聚类。

    解决方案:应该精细到类别与类别的对齐。只在网络最后一层加判别器,但是是有多个判别器,每一个判别器对应一个子类

    网络介绍:看蓝色箭头部分:目标域进入到源域的分类器中得到分类概率,这个分类概率对目标域的feature进行加权,实现语义信息的对齐。举个栗子:如果target域的一幅图像经过之前训练好的源域的网络中,网络会对它所属类别进行归类。=> 引入语义的对齐

    在这里插入图片描述在这里插入图片描述

    3.3.4 Weighted Adversarial Nets

    3.4 Reconstruction-based DA

    待续。。。

    二、Domain generalization

    待续。。。

    三、二者之间的异同

    • Domain adaptation :是一种将源任务和目标任务一样,但源域和目标域的数据分布不一样,并且源域有大量的标记样本,目标域则没有(或很少)标记样本的迁移学习方法。DA在训练中,源域和目标域数据均能访问(无监督DA中则只有无标记的目标域数据)。
    • Domain generalization: 主要做的就是通过多个标注好的源域数据,学习一个通用的特征表示,并希望该表示也能应用于未见过的相似样本,即目标域数据,即使目标域一个数据都没有。故训练过程中,我们只能访问若干个用于训练的源域数据,测试数据是不能访问的。

    毫无疑问,DG是比DA更具有挑战性和实用性的场景:毕竟我们都喜欢“一次训练、到处应用”的足够泛化的机器学习模型。

    DA与DG比较

    • DA不够高效,每来一个新域,都需要重复进行适应,而DG只需训练一次;
    • DA的性能比DG的性能要高,由于使用了目标域的数据;
    • DA的强假设是目标域的数据是可用的,显然有些情况是无法满足的,或者代价昂贵。
    • DA关注如何利用无标注的目标数据,而DG主要关注泛化性

    参考文献:

    1. How transferable are features in deep neural networks
    2. 迁移学习之Domain Adaptation
    3. 文献阅读·80-DANN(RevGrad)
    4. Understanding Transfer Learning (B)
    5. Domain Generalization Notes
    展开全文
  • Functional and Reactive Domain Modeling teaches readers how to think of the domain model in terms of pure functions and how to compose them to build larger abstractions. It begins with the basics of ...
  • wildfly 21的domain配置

    万次阅读 2020-12-23 21:05:34
    wildfly可以使用Standalone模式或者domain模式启动,standalone模式就很简单了,可以看做是一个单独的服务器。今天我们将会详细讲解一下domain模式。

    简介

    wildfly可以使用Standalone模式或者domain模式启动,standalone模式就很简单了,可以看做是一个单独的服务器。今天我们将会详细讲解一下domain模式。

    wildfly模式简介

    wildfly可以在两种模式下面工作,他们是standalone和managed domain。

    standalone模式表示的是一个独立的服务器,它们可以通过使用standalone.sh来启动。如果使用的是standalone模式,但是又需要使用多服务器的集群模式,那么需要用户自己在应用层去处理。

    如果想中心化管理多个多个服务的话,那么可以用到managed domain模式。

    在managed domain模式下,wildfly可以通过一个domain controller来控制和管理其他的domain server。

    我们看下managed domain下的服务器部署示意图:

    上面示意图中,一个host表示的是一个实体或者虚拟机。在一个host中可以部署多个server instances。

    我们可以通过domain.sh来启动host controller。

    host controller负责启动和停止server服务,并且负责和Domain Controller进行交互。

    host controller通过读取domain/configuration/host.xml的配置信息,来进行服务器的配置。

    上图中有一个特殊的host controller叫做Domain Controller。Domain Controller负责整个domain的管理工作。

    域控制器的主要职责是维护域的中央管理策略,以确保所有主机控制器都知道其当前内容,并协助主机控制器确保根据此策略配置任何正在运行的应用程序服务器实例。 默认情况下,此中央管理策略存储在Domain Controller主机的domain/configuration/domain.xml中。

    server group中的一组server都有相同的配置,可以将它们看做是一个。一个 Domain Controller 可以管理多个server group.

    我们看一个server group的定义:

    <server-group name="main-server-group" profile="default">
        <socket-binding-group ref="standard-sockets"/>
        <deployments>
            <deployment name="foo.war_v1" runtime-name="foo.war" />
            <deployment name="bar.ear" runtime-name="bar.ear" />
        </deployments>
    </server-group>
    

    最后一个概念就是server,server表示的是一个运行的应用程序。server和Host Controller 运行在不同的JVM中的,并且server是由Host Controller 来启动的。

    注意,不管是standalone还是managed domain,这都是取决于你内部的服务是怎么管理的,是一个个单独的部署还是使用中心化的管理方式,他们和外部用户的服务方式是无关的,也就是说不管使用standalone还是managed domain,都可以搭建服务集群。

    domain controller的配置

    domain controller是一个中心化的对domain进行管理的服务。我们需要一个host被配置为domain controller,还需要暴露它的管理接口以供被管理的host进行连接。

    我们看下一个domain controller的配置:

    <domain-controller>
       <local/>
    </domain-controller>
    

    上面的例子中,local表示的是本地host。

    如果这个机子被当做是domain controller,那么必须配置和暴露管理接口:

    <management-interfaces>
      <native-interface security-realm="ManagementRealm">
        <socket interface="management" port="${jboss.management.native.port:9999}"/>
      </native-interface>
      <http-interface security-realm="ManagementRealm">
        <socket interface="management" port="${jboss.management.http.port:9990}"/>
      </http-interface>
    </management-interfaces>
    

    其中,interface指向的management是在host.xml中配置的:

    <interfaces>
       <interface name="management">
           <inet-address value="192.168.0.101"/>
       </interface>
    </interfaces>
    

    默认情况下master domain controller是需要认证才能被访问的,我们需要通过使用add-user来为slave domain controller 创建用户,以连接到master domain controller。

    所以,我们在add-user的最后一步,我们需要输入y:

    Is this new user going to be used for one AS process to connect to another AS process e.g. slave domain controller?
    yes/no? y
    To represent the user add the following to the server-identities definition <secret value="cE3EBEkE=" />
    

    我们需要记住上面的xml格式的secret,以便在后续slave的配置中使用。

    Host controller的配置文件

    有了domain controller,我们就可以通过host controller加入存在的domain了。

    在做host controller的配置的时候,需要注意,host的逻辑名在一个domain内部必须是唯一的。并且host controller是通过IP地址来连接到domain controller的。

    所以我们需要在host.xml中给host起一个唯一的名字:

    <host xmlns="urn:jboss:domain:3.0"
         name="slave">
    [...]
    </host>
    

    如果没有指定host的名字,将会使用jboss.host.name的值作为host的名字。如果这个值也没有设置,那么将会使用HOSTNAME或者COMPUTERNAME作为host的名字。

    我们需要在hsot controller中指定domain controller的连接信息:

    <domain-controller>
       <remote protocol="remote" host="192.168.0.101" port="9999" username="slave" security-realm="SlaveRealm"/>
    </domain-controller>
    

    这里我们需要指定一个security realm,用来存放slave的密码:

    <security-realm name="SlaveRealm">
      <server-identities>
        <secret value="cE3EBEkE=" />
      </server-identities>
    </security-realm>
    

    这个secret,就是在使用user-add工具的时候创建的密码。

    忽略域范围的资源

    我们知道domain controller的职责就是保证所有正在运行的host controller都拥有和domain controller域范围配置一致的本地副本。

    这些域范围的配置指的是不以 /host = * 开头的资源,比如那些保存在domain.xml中的资源。

    如果host controller不是想做domain controller的备份,或者说host controller不想重新启动一个新的server group。那么host controller只需要保存已运行server group相关的域范围配置即可,并不需要保存所有的是域范围配置。

    这样可以减少数据的传输,提升系统的效率。

    如果要忽略域范围的资源我们可以使用ignore-unused-configuration=“true”。

    <domain-controller>
        <remote security-realm="ManagementRealm" ignore-unused-configuration="true">
            <discovery-options>
                <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote}" host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9999}"/>
            </discovery-options>
        </remote>
    </domain-controller>
    

    Server groups

    Server groups就是服务分组,它是由domain controller来定义的,每个server-group都需要和profile,socket-binding-group进行关联,我们看个例子:

    <server-groups>
       <server-group name="main-server-group" profile="default">
           <jvm name="default">
              <heap size="64m" max-size="512m"/>
              <permgen size="128m" max-size="128m"/>
           </jvm>
           <socket-binding-group ref="standard-sockets"/>
       </server-group>
       <server-group name="other-server-group" profile="bigger">
           <jvm name="default">
               <heap size="64m" max-size="512m"/>
           </jvm>
           <socket-binding-group ref="bigger-sockets"/>
       </server-group>
    </server-groups>
    

    上面配置中的socket-binding-group也是在domain.xml中定义的,指定了网络的interface和端口:

    <socket-binding-groups>
        <socket-binding-group name="standard-sockets" default-interface="public">
            <socket-binding name="http" port="8080"/>
            [...]
        </socket-binding-group>
        <socket-binding-group name="bigger-sockets" include="standard-sockets" default-interface="public">
            <socket-binding name="unique-to-bigger" port="8123"/>
        </socket-binding-group>
    </socket-binding-groups>
    

    socket-binding-group还可以使用include来引用其他的socket-binding-group。

    profile是subsystems的集合,subsystem就是应用程序需要的各种功能。

    <profiles>
        <profile name="default">
            <subsystem xmlns="urn:jboss:domain:web:1.0">
                <connector name="http" scheme="http" protocol="HTTP/1.1" socket-binding="http"/>
                [...]
            </subsystem>
            <\!-\- The rest of the subsystems here \-->
            [...]
        </profile>
        <profile name="bigger">
            <subsystem xmlns="urn:jboss:domain:web:1.0">
                <connector name="http" scheme="http" protocol="HTTP/1.1" socket-binding="http"/>
                [...]
            </subsystem>
            <\!-\- The same subsystems as defined by 'default' here \-->
            [...]
            <subsystem xmlns="urn:jboss:domain:fictional-example:1.0">
                <socket-to-use name="unique-to-bigger"/>
            </subsystem>
        </profile>
    </profiles>
    

    Servers

    Servers是在host controller中定义的,而Servers group是在domain controller中定义的。

    每个server都要属于一个server group,server就是服务,每个server都会启动一个jvm。 我们先看下server的定义:

    <servers>
        <server name="server-one" group="main-server-group">
            <\!-\- server-one inherits the default socket-group declared in the server-group \-->
            <jvm name="default"/>
        </server>
     
        <server name="server-two" group="main-server-group" auto-start="true">
            <socket-binding-group ref="standard-sockets" port-offset="150"/>
            <jvm name="default">
                <heap size="64m" max-size="256m"/>
            </jvm>
        </server>
     
        <server name="server-three" group="other-server-group" auto-start="false">
            <socket-binding-group ref="bigger-sockets" port-offset="250"/>
        </server>
    </servers>
    

    在server中,我们可以重新定义socket-binding-group。

    auto-start的意思是server是否回随着host controller的启动而启动。

    最后,我们看下在host.xml中的jvm的定义:

    <jvms>
        <jvm name="default">
            <heap size="64m" max-size="128m"/>
        </jvm>
    </jvms>
    

    我们可以在server中对其进行重写。

    总结

    以上就是wildfly中,对domain的配置规则,可以看到在domain中,可以启动多个server,配置和管理起来比tomcat要复杂很多,不过功能也相应的强大很多,我们可以借鉴这些优秀软件的设计思想,从而应用到我们的自己的程序中。

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/wildfly-21-domain/

    本文来源:flydean的博客

    欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    展开全文
  • Domain Modeling Made Functional Tackle Software Complexity with Domain-Driven Design and F# 英文无水印原版pdf pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本...
  • crossdomain.xml

    热门讨论 2013-09-03 11:48:26
    crossdomain.xml用于unity3d生成的webplayer不能读取数据库的问题,用于unity3d生成的webplayer不能读取数据库的问题
  • Domain driven design distilled
  • domain adaptation 小综述

    千次阅读 2021-11-10 09:18:04
    前段时间为了一个项目读了一些domain adaptation的论文,希望了解领域背景和前沿,现在进行一个总结。 首先介绍下domain adaptation的概念,简单地说就是,在一个数据集上训练得到的模型无法很好地在另一个数据集...
    • 前段时间为了一个项目读了一些domain adaptation的论文,希望了解领域背景和前沿,现在进行一个总结。

    • 首先介绍下domain adaptation的概念,简单地说就是,在一个数据集上训练得到的模型无法很好地在另一个数据集上表现,两个数据集之间存在差异。用上术语就是两个domain之间存在domain shift,导致了性能的下降。举个例子,自然图像数据集上训练得到的目标检测模型,应用到遥感图像上表现很差,是因为自然图像和遥感图像之间存在着domain shift。domain adaptation 就是为了寻找各种各样的方法去克服domain shift。

    • domain adaptation 中有个子领域 unsupervised domain adaptation,这是我读的论文中主要涉及的领域,也是相对来说应用到真实场景中更加自然的一个方向。unsupervised domain adaptation 是指这样一类问题:

      你有两个数据集/数据源,我们称其中一个为source domain,另一个为 target domain。关于source domain我们有完善的标注,但它不是我们应用的目标,我们想要应用到 target domain 上,也就是说追求的是 target domain 上有较高的测试指标。但关于target domain我们根本没有标注。举个例子,我们希望在黑暗图像上有较好的目标检测效果,但我们只有很多黑暗图像,却没有关于这些图像的目标检测标注。那么把黑暗图像当作 target domain,我们可以借助有标注的高光图像数据集如coco和voc,把这样的数据集当作 source domain,通过种种方法,利用source domain 的 labeled samples 和 target domain 的 unlabeled samples,想办法克服两个domain之间的domain shift得到一个能够在target domain 上进行预测并且效果较好的方法,就是unsupervised domain adaptation的目标。

    • domain adaptation 问题除了 unsupervised domain adaptation 外还有 semi-supervised domain adaptation,这种 DA 的t arget domain 有 partial label。除此之外还可以有另一种分类方式,是根据 domain 的数量,有multi-single的domain adaptation和 single-single 的 domain adaptation 等,涉及到multi-domain adaptation的往往在方法的考虑要考虑如何无监督地或有监督地识别出不同的domain分别处理或是统计方法进行建模等,而 single-single domain adaptation 则更加关注于 domain shift 这一核心,接下来也将主要介绍 unsupervised domain adaptation 中的 single-single 方向。

    • 对于 single-source unsupervised domain adaptation,有三个方向:

      • 一个是通过数据增强和训练流程的控制等,学得一个对 domain 不敏感的模型;
      • 另一个是希望学得一个对不同 domain 不变的特征空间,换句话说,希望将 target domain 和 source domain 映射到这样一个特征空间,在这个空间下 target domain 的特征和 source domain 的特征有相同的分布。这个映射通常就是利用卷积神经网络来完成的;
      • 第三个方向则是利用GAN进行domain的transfer,要么是将source domain的图片通过GAN的风格转换变成target domain的图片,然后利用这些转换后的图片以及原有的标签训练一个针对target domain的模型,要么是训练一个将target domain到source domain的风格迁移的GAN和一个source domain上的模型,然后测试的时候直接将target domain的图片先转换成source domain再进行预测。
    • 对于上述的第二个方向,也有两类方法。一类是人为设计出某个公式,来衡量两个分布之间的距离,一类是利用GAN的框架,利用discriminator来衡量两个分布之间的距离。接下来具体介绍各类的流程:

    • 第一类的方法,例子是这篇论文:“Learning Target-Domain-Specific Classifier for Partial Domain Adaptation,” IEEE TRANSACTIONS ON NEURAL NETWORKS AND LEARNING SYSTEMS, VOL. 32, NO. 5, MAY 2021

    • 这类方法主要流程是这样的,用一个网络 F 1 F1 F1去提取source domain 图片输入的特征 f 1 f1 f1,用一个网络 F 2 F2 F2 去提取 target domain 图片输入的特征 f 2 f2 f2,用一个loss函数 L L L 去计算一个batch下多个 f 1 f1 f1和多个 f 2 f2 f2这两个集合之间的分布距离 l l l,其实理论上,这个loss应该衡量整个source domain和整个target domain两个分布之间的距离的,但一般都采取batch的方式,也就是说从source domain和target domain中分别采样一个batch的子集,那么这个 batch 的 source domain 的图片得到的特征和 target domain 的图片得到的特征之间的距离应该可以代表两个数据集在这个特征空间上的距离。通过减小 l l l,就能得到一个domain invariant的特征空间。当然训练过程中同时还会将 f 1 f1 f1 继续前向传播产生预测结果并利用已有的label进行监督训练(一般是图像分类任务)。根据情况,可能会将 F 1 F1 F1 F 2 F2 F2共享权重,也就是用一个网络来提取两个domain的特征。所以得到的流程图就类似下面这样(截图自上一点的例子论文"Learning Target-Domain-Specific Classifier for Partial Domain Adaptation"):
      在这里插入图片描述

    • 第二类方法是利用GAN的流程进行的,简单地说,就是把上述的衡量两个分布之间距离的loss函数改成一个discriminator,通过训练希望让discriminator分不出两个domain生成的feature是哪个domain生成的,从而得到一个domain invariant的特征空间,例子论文是:“Adversarial Discriminative Domain Adaptation”,是2017 CVPR的论文。

    • 流程大概如下面几个图:
      在这里插入图片描述
      在这里插入图片描述

    • 而第三个方向的典型论文是这篇2018 CVPR的论文"From source to target and back: Symmetric Bi-Directional Adaptive GAN"把这里的GAN改成了cycleGAN。下面是它的流程:
      在这里插入图片描述

    • 此外呢,研究domain adaptation的通常都是在分类任务上验证的,其实这些方法也可以应用到具体的其它领域,其实就和目标检测与行人检测的关系是一样的。比如这一篇ECCV2020的文章"YOLO in the Dark - Domain Adaptation Method for Merging Multiple Models",就将domain adaptation的方法用到了黑暗图像目标检测上。

    展开全文
  • Domain Adaptation(领域自适应,MMD,DANN)

    万次阅读 多人点赞 2020-12-26 17:03:22
    Domain Adaptation 现有深度学习模型都不具有普适性,即在某个数据集上训练的结果只能在某个领域中有效,而很难迁移到其他的场景中,因此出现了迁移学习这一领域。其目标就是将原数据域(源域,source domain)尽...
  • 而对于底片缺陷检测(类似于下图中的医学射线图像),与传统数据集相比我主观上认为不属于同一个域,因此就涉及到了域适应 Domain Adaptation、域泛化 Domain Generation 和跨域 Cross Domain。数据集间是否属于同一...
  • linux IRQ Management(四)- IRQ Domain

    千次阅读 2019-09-26 15:45:35
    了解IRQ Domain 1.概述   Linux kernel使用如下两个ID来标识一个来自外设的中断: IRQ number,CPU需要为每一个外设中断编号,即IRQ Number。这个IRQ number是一个虚拟的interrupt ID,和硬件无关,仅仅...
  • 同任务但不同domain数据的统一模型

    千次阅读 2021-12-02 11:13:00
    不同的domain之间存在特征交集,比如电商领域的CTR(曝光给用户预测其点击的概率)任务存在着部分相同的用户群体和商品,这部分信息其实在不同的domain任务中可以共享,但是又不完全相同,比如同一用户在不同的...
  • 本篇是迁移学习专栏介绍的第六篇论文,来自来自加州大学伯克利分校的Eric Tzeng等人发表在arXiv 2014的DDC(Deep Domain Confusion)。DDC针对预训练的AlexNet(8层)网络,在第7层(也就是feature层,softmax的上一...
  • Spatial Attention Pyramid Network for Unsupervised Domain Adaptation [paper] CSCL: Critical Semantic-Consistent Learning for Unsupervised Domain Adaptation [paper] Learning ...
  • 2020 Domain Adaptation 最新论文:插图速览(三) 目录 Learning to Combine: Knowledge Aggregation for Multi-Source Domain Adaptation Every Pixel Matters: Center-aware Feature Alignment for Domain ...
  • 设置cookie的domain属性

    千次阅读 2021-02-27 17:38:08
    //设置域Cookie cookie.Domain = ".devin.cn"; //设置用户名称 cookie.Values.Add(CookieUserName, UserName); //设置Cookie身份验证码 cookie.Values.Add(CookieUserCode, this.CookieCode().ToString()); //...
  • unix domain socket 浅析

    千次阅读 2020-12-14 20:41:03
    unix domain socket unix domain socket 是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC: Inter-Process Communication),它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,...
  • libvirt virsh domain命令解析(一)

    千次阅读 2019-11-25 22:11:35
    这里首先介绍domain domain 域, 可以看做是一个虚拟机实例 通过 virsh -h 可以查看所有命令, 能够看到每个命令的介绍信息(这里不做一一翻译) # virsh -h virsh [options]... [<command_string>] vi...
  • Node.js Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常。 Domain 模块可分为隐式绑定和显式绑定: 隐式绑定: 把在domain上下文中定义的变量,自动绑定到domain对象 显式绑定: 把不是...
  • 这类接口的逻辑很简单,根据自己的映射类型,初始化struct irq_domain中的各个成员,调用__irq_domain_add将该irq domain挂入irq_domain_list的全局列表。   static inline struct fwnode_handle *of_node_...
  • Domain Specific Languages(martin fowler)

    热门讨论 2011-08-01 09:23:29
    Domain Specific Languages By: Martin Fowler Publisher: Addison-Wesley Professional Pub. Date: September 24, 2010 Print ISBN-10: 0-321-71294-3 Print ISBN-13: 978-0-321-71294-3 Web ISBN-10: 0-13-210754-...
  • 文章目录简介什么是Unix domain Socket使用socat来创建Unix Domain Sockets使用ss命令来查看Unix domain Socket使用nc连接到Unix domain Socket服务总结 简介 之前的文章我们讲到了Socket中的Stream Socket和...
  • 今天在测试前辈的代码的时候遇到了这个问题,检查了好多遍自己的cookie明明没有出错,而且还参照了网上的一些教程发现好多跟自己的情况都不怎么相符。 后来无奈之下就询问了前辈,最后前辈发现问题,原因是这段代码...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 820,841
精华内容 328,336
关键字:

DOMAIN