精华内容
下载资源
问答
  • 数据结构学习指导与典型解释 数据结构学习指导与典型解释 数据结构学习指导与典型解释 数据结构学习指导与典型解释 数据结构学习指导与典型解释 数据结构学习指导与典型解释 数据结构学习指导与典型题...
  • SIP呼叫流程典型流程图解及其详细解释
  • 设计模式 | 解释器模式及典型应用

    千次阅读 2019-01-13 23:47:54
    解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的 “语言” 是指使用规定格式语法的代码。解释器模式是一种类行为型模式。 角色 AbstractExpre...

    微信原文:设计模式 | 解释器模式及典型应用
    博客原文:设计模式 | 解释器模式及典型应用

    本文主要介绍解释器模式,在日常开发中,解释器模式的使用频率比较低

    解释器模式

    解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的 “语言” 是指使用规定格式和语法的代码。解释器模式是一种类行为型模式。

    角色

    AbstractExpression(抽象表达式):在抽象表达式中声明了抽象的解释操作,它是所有终结符表达式和非终结符表达式的公共父类。

    TerminalExpression(终结符表达式):终结符表达式是抽象表达式的子类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常在一个解释器模式中只有少数几个终结符表达式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。

    NonterminalExpression(非终结符表达式):非终结符表达式也是抽象表达式的子类,它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操作一般通过递归的方式来完成。

    Context(环境类):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。

    解释器模式结构图

    示例

    使用解释器模式实现一个简单的后缀表达式解释器,仅支持对整数的加法和乘法即可

    定义抽象表达式接口

    public interface Interpreter {
        int interpret();
    }
    

    非终结符表达式,对整数进行解释

    public class NumberInterpreter implements Interpreter {
        private int number;
    
        public NumberInterpreter(int number) {
            this.number = number;
        }
    
        public NumberInterpreter(String number) {
            this.number = Integer.parseInt(number);
        }
    
        @Override
        public int interpret() {
            return this.number;
        }
    }
    

    终结符表达式,对加法和乘法进行解释

    // 加法
    public class AddInterpreter implements Interpreter {
        private Interpreter firstExpression, secondExpression;
        public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
        @Override
        public int interpret() {    
            return this.firstExpression.interpret() + this.secondExpression.interpret();
        }
        @Override
        public String toString() {
            return "+";
        }
    }
    
    // 乘法
    public class MultiInterpreter implements Interpreter {
        private Interpreter firstExpression, secondExpression;
    
        public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
        @Override
        public int interpret() {
            return this.firstExpression.interpret() * this.secondExpression.interpret();
        }
        @Override
        public String toString() {
            return "*";
        }
    }
    

    工具类

    public class OperatorUtil {
        public static boolean isOperator(String symbol) {
            return (symbol.equals("+") || symbol.equals("*"));
    
        }
        public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
            if ("+".equals(symbol)) {  // 加法
                return new AddInterpreter(firstExpression, secondExpression);
            } else if ("*".equals(symbol)) {    // 乘法
                return new MultiInterpreter(firstExpression, secondExpression);
            } else {
                throw new RuntimeException("不支持的操作符:" + symbol);
            }
        }
    }
    

    测试,对后缀表达式 6 100 11 + * 进行求值

    public class Test {
        public static void main(String[] args) {
            String inputStr = "6 100 11 + *";
            MyExpressionParser expressionParser = new MyExpressionParser();
            int result = expressionParser.parse(inputStr);
            System.out.println("解释器计算结果: " + result);
        }
    }
    

    运行结果

    入栈: 6
    入栈: 100
    入栈: 11
    出栈: 11 和 100
    应用运算符: +
    阶段结果入栈: 111
    出栈: 111 和 6
    应用运算符: *
    阶段结果入栈: 666
    解释器计算结果: 666
    

    示例.类图

    解释器模式总结

    解释器模式为自定义语言的设计和实现提供了一种解决方案,它用于定义一组文法规则并通过这组文法规则来解释语言中的句子。虽然解释器模式的使用频率不是特别高,但是它在正则表达式XML文档解释等领域还是得到了广泛使用。

    主要优点

    • 易于改变和扩展文法。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
    • 每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言
    • 实现文法较为容易。在抽象语法树中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会特别复杂,还可以通过一些工具自动生成节点类代码。
    • 增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合 “开闭原则”。

    主要缺点

    • 对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。
    • 执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而且代码的调试过程也比较麻烦。

    适用场景

    • 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
    • 一些重复出现的问题可以用一种简单的语言来进行表达。
    • 一个语言的文法较为简单。
    • 对执行效率要求不高。

    解释器模式的典型应用

    Spring EL表达式中的解释器模式

    Spring EL表达式相关的类在 org.springframework.expression 包下,类图如下

    org.springframework.expression 包的类图

    涉及的类非常多,这里仅对此时我们最关心的几个类做介绍:

    SpelExpression,表示一个 EL 表达式,表达式在内部通过一个 AST抽象语法树 表示,EL表达式求值是通过 this.ast.getValue(expressionState); 求值

    public class SpelExpression implements Expression {
    	private final String expression;
    	private final SpelNodeImpl ast;
    	private final SpelParserConfiguration configuration;
    	
    	@Override
    	@Nullable
    	public Object getValue() throws EvaluationException {
    		if (this.compiledAst != null) {
    			try {
    				EvaluationContext context = getEvaluationContext();
    				return this.compiledAst.getValue(context.getRootObject().getValue(), context);
    			}
    			catch (Throwable ex) {
    				// If running in mixed mode, revert to interpreted
    				if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
    					this.interpretedCount = 0;
    					this.compiledAst = null;
    				}
    				else {
    					// Running in SpelCompilerMode.immediate mode - propagate exception to caller
    					throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
    				}
    			}
    		}
    
    		ExpressionState expressionState = new ExpressionState(getEvaluationContext(), this.configuration);
    		Object result = this.ast.getValue(expressionState);
    		checkCompile(expressionState);
    		return result;
    	}
    	//...省略...
    }
    

    SpelNodeImpl:已解析的Spring表达式所代表的ast语法树的节点的通用父类型,语法树的节点在解释器模式中扮演的角色是终结符和非终结符。从类图中可以看到,SpelNodeImpl 的子类主要有 Literal,Operator,Indexer等,其中 Literal 是各种类型的值的父类,Operator 则是各种操作的父类

    public abstract class SpelNodeImpl implements SpelNode, Opcodes {
    	protected int pos;  // start = top 16bits, end = bottom 16bits
    	protected SpelNodeImpl[] children = SpelNodeImpl.NO_CHILDREN;
    	@Nullable
    	private SpelNodeImpl parent;
    
    	public final Object getValue(ExpressionState expressionState) throws EvaluationException {
    		return getValueInternal(expressionState).getValue();
    	}
        // 抽象方法,由子类实现,获取对象的值
    	public abstract TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException;
    	//...省略...
    }
    

    IntLiteral 表示整型文字的表达式语言的ast结点

    public class IntLiteral extends Literal {
        private final TypedValue value;
    	public IntLiteral(String payload, int pos, int value) {
    		super(payload, pos);
    		this.value = new TypedValue(value); // 
    		this.exitTypeDescriptor = "I";
    	}
    	@Override
    	public TypedValue getLiteralValue() {
    		return this.value;
    	}
    	// ...
    }
    

    OpPlus 表示加法的ast结点,在 getValueInternal 方法中对操作符两边进行相加操作

    public class OpPlus extends Operator {
    	public OpPlus(int pos, SpelNodeImpl... operands) {
    		super("+", pos, operands);
    		Assert.notEmpty(operands, "Operands must not be empty");
    	}
    	@Override
    	public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    		SpelNodeImpl leftOp = getLeftOperand();
    
    		if (this.children.length < 2) {  // if only one operand, then this is unary plus
    			Object operandOne = leftOp.getValueInternal(state).getValue();
    			if (operandOne instanceof Number) {
    				if (operandOne instanceof Double) {
    					this.exitTypeDescriptor = "D";
    				}
    				else if (operandOne instanceof Float) {
    					this.exitTypeDescriptor = "F";
    				}
    				else if (operandOne instanceof Long) {
    					this.exitTypeDescriptor = "J";
    				}
    				else if (operandOne instanceof Integer) {
    					this.exitTypeDescriptor = "I";
    				}
    				return new TypedValue(operandOne);
    			}
    			return state.operate(Operation.ADD, operandOne, null);
    		}
            // 递归调用leftOp的 getValueInternal(state) ,获取操作符左边的值
    		TypedValue operandOneValue = leftOp.getValueInternal(state);
    		Object leftOperand = operandOneValue.getValue();
    		// 递归调用children[1]的 getValueInternal(state) ,获取操作符右边的值
    		TypedValue operandTwoValue = getRightOperand().getValueInternal(state);
    		Object rightOperand = operandTwoValue.getValue();
    
            // 如果操作符左右都是数值类型,则将它们相加
    		if (leftOperand instanceof Number && rightOperand instanceof Number) {
    			Number leftNumber = (Number) leftOperand;
    			Number rightNumber = (Number) rightOperand;
                
    			if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
    				BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
    				BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
    				return new TypedValue(leftBigDecimal.add(rightBigDecimal));
    			}
    			else if (leftNumber instanceof Double || rightNumber instanceof Double) {
    				this.exitTypeDescriptor = "D";  
    				return new TypedValue(leftNumber.doubleValue() + rightNumber.doubleValue());
    			}
    			//...省略 Float->F, BigInteger->add, Long->J,Integer->I
    			else {
    				// Unknown Number subtypes -> best guess is double addition
    				return new TypedValue(leftNumber.doubleValue() + rightNumber.doubleValue());
    			}
    		}
    		//...
    		return state.operate(Operation.ADD, leftOperand, rightOperand);
    	}
        //...
    }
    

    通过一个示例,调试查看程序中间经历的步骤

    public class SpringELTest {
        public static void main(String[] args) {
            // 1. 构建解析器
            org.springframework.expression.ExpressionParser parser = new SpelExpressionParser();
            // 2. 解析表达式
            Expression expression = parser.parseExpression("100 * 2 + 400 * 1 + 66");
            // 3. 获取结果
            int result = (Integer) expression.getValue();
            System.out.println(result); // 结果:666
        }
    }
    

    EL表达式解析后得到表达式 (((100 * 2) + (400 * 1)) + 66)
    EL表达式解析后得到的表达式

    如果用图形把其这棵AST抽象语法树简单地画出来,大概是这样

    示例.AST抽象语法树

    调用 expression.getValue() 求值,此时的 ast 是语法树的头结点,也就是 + OpPlus,所以通过 this.ast.getValue(expressionState) 进入了 OpPlus 的 getValue 方法(是父类中的方法),接着进入 getValueInternal 方法,然后递归计算操作符左边的值,递归计算操作符右边的值,最后相加返回

    示例.spring EL调试

    参考:
    刘伟.Java设计模式
    Java设计模式精讲

    后记

    欢迎评论、转发、分享

    更多内容可访问我的个人博客:http://laijianfeng.org

    关注【小旋锋】微信公众号,及时接收博文推送

    关注_小旋锋_微信公众号

    展开全文
  • 离散数学结构:学习指导与典型解释,考研必备
  • 数据结构:学习指导与典型解释
  • vlan的经典解释以及相应的典型实验,让你一目了然,不知不觉中掌握vlan知识。
  • 主要用到访问者模式和解释器模式结合来解析freemarker中的表达式,并分别赋值。 先来看看什么是访问者模式,什么是解释器模式,再来分析下freemarker如何使用的。 1.访问者模式 根据GoF描述,主要在...

    折腾这篇文章也快一个小时了,转载请注明出处http://blog.csdn.net/zhouyuqwert/article/details/8682535微笑


    最近因为一些需要,稍微学了下freemarker,基本使用算了解了,本以为模板解析方式同JSP相同,会先解析生成Servlet

    再仔细看了下源码,发现还是很大不同的,虽然最终也是解析成HTML,response.write出去,中间思路看了下还是很不错的。

    主要用到访问者模式和解释器模式结合来解析freemarker中的表达式,并分别赋值。

    先来看看什么是访问者模式,什么是解释器模式,再来分析下freemarker如何使用的。


    1.访问者模式

    根据GoF描述,主要在为基本固定的一些元素更方便地添加操作的,将数据结构与其操作解耦和。

    譬如针对二叉树的遍历时,二叉树节点类型为Element,当访问到这个节点对象时,需要输出操作,即可以将该操作定义到Visitor中,
    这样做的好处是,我不用关心是哪个操作,由visitor来定义,当是前序遍历时,传入ConcreteVisitor1来进行一些操作,当是后序遍历
    时传入ConcreteVisitor2来进行另外一些操作,而且今后如果还要对中序遍历每个节点要有不同操作,只需增加一个相应操作的ConcreteVisitor3
    来完成,无需修改Element的类,将无关操作放在了外面。

    2.解释器模式

    给定一个语言,定义文法的一种表示,定义一个解释器,使用该表示解释语言中的句子。



    如果还记得以前解释器如何写的,看到这个东西应该不陌生了,看起来这个结构跟装饰模式很像, 但还是有些差别的,
    要解释的话得说下Context,Context主要维护着上下文值的关系,也就是文法表达式中终结符的值。
    譬如一个freemarker表达式 <body> ${hello} </body>,会被解析成三个部分,分别是
    <body>
    ${hello}
    </body>
    前面和后面的body标签,自不用解释了,在freemarker中被定义为TextBlock,中间的变量定义为DollarVariable
    那么目前的结构也就是RootExpression = TextBlock DollarVariable TextBlock
    RootExpression也就是NonterminalExpression, 后面的三个都是TerminalExpression
    解释器一进来将会对RootExpression进行解析,RootExpression将会依次调用TextBlock DollarVariable TextBlock的interpret进行解析
    不同类型将会做不同操作,根据传进来的Context参数进行相应赋值并输出等

    3.freemarker解析模板

    简单画了个主要的类图及方法,然后再根据类图做相关解释


    这里的Environment在同时扮演着解释器模式的Context,访问者模式的Visitor和ObjectStructure。
    当Template启动解释时,由Environment进入调用根元素的访问动作,根元素会依次访问所包含的TemplateElement,直到所有叶子节点访问完成,
    这些访问动作是通过调用Environment的visit方法控制,Environment做些相关必要操作,再根据访问的节点类型调用相应节点的访问操作。
    当访问到包含需要解释器的元素节点时,则会启动解释器做解释操作,根据维护的文法Expression类型,调用getStringValue,并传入参数Environment,
    相应类型的表达式根据Environment解释得到输入字符串的值,返回并写到响应流,即解释完成。





    展开全文
  • 原文地址:《一文看懂深度学习(白话解释+8个优缺点+4个典型算法)》 深度学习有很好的表现,引领了第三次人工智能的浪潮。目前大部分表现优异的应用都用到了深度学习,大红大紫的 AlphaGo 就使用到了深度学习。 ...

    本文首发自 easyAI - 人工智能知识库
    原文地址:《一文看懂深度学习(白话解释+8个优缺点+4个典型算法)

    一文看懂深度学习

    深度学习有很好的表现,引领了第三次人工智能的浪潮。目前大部分表现优异的应用都用到了深度学习,大红大紫的 AlphaGo 就使用到了深度学习。

    本文将详细的给大家介绍深度学习的基本概念、优缺点和主流的4个典型算法。

    深度学习、神经网络、机器学习、人工智能的关系

    深度学习、机器学习、人工智能

    简单来说:

    1. 深度学习是机器学习的一个分支(最重要的分支)
    2. 机器学习是人工智能的一个分支

    深度学习、机器学习、人工智能的关系

    目前表现最好的一些应用大部分都是深度学习,正是因为深度学习的突出表现,引发了人工智能的第三次浪潮。详情可以看《人工智能的发展史——3次 AI 浪潮

    深度学习、神经网络

    深度学习的概念源于人工神经网络的研究,但是并不完全等于传统神经网络。

    不过在叫法上,很多深度学习算法中都会包含"神经网络"这个词,比如:卷积神经网络、循环神经网络。

    所以,深度学习可以说是在传统神经网络基础上的升级,约等于神经网络。

    深度学习和神经网络的关系

    大白话解释深度学习

    看了很多版本的解释,发现李开复在《人工智能》一书中讲的是最容易理解的,所以下面直接引用他的解释:

    我们以识别图片中的汉字为例。

    假设深度学习要处理的信息是“水流”,而处理数据的深度学习网络是一个由管道和阀门组成的巨大水管网络。网络的入口是若干管道开口,网络的出口也是若干管道开口。这个水管网络有许多层,每一层由许多个可以控制水流流向与流量的调节阀。根据不同任务的需要,水管网络的层数、每层的调节阀数量可以有不同的变化组合。对复杂任务来说,调节阀的总数可以成千上万甚至更多。水管网络中,每一层的每个调节阀都通过水管与下一层的所有调节阀连接起来,组成一个从前到后,逐层完全连通的水流系统。

    深度学习类似一个水流系统

    那么,计算机该如何使用这个庞大的水管网络来学习识字呢?

    比如,当计算机看到一张写有“田”字的图片,就简单将组成这张图片的所有数字(在计算机里,图片的每个颜色点都是用“0”和“1”组成的数字来表示的)全都变成信息的水流,从入口灌进水管网络。

    深度学习-将图片数字化

    我们预先在水管网络的每个出口都插一块字牌,对应于每一个我们想让计算机认识的汉字。这时,因为输入的是“田”这个汉字,等水流流过整个水管网络,计算机就会跑到管道出口位置去看一看,是不是标记由“田”字的管道出口流出来的水流最多。如果是这样,就说明这个管道网络符合要求。如果不是这样,就调节水管网络里的每一个流量调节阀,让“田”字出口“流出”的水最多。

    这下,计算机要忙一阵了,要调节那么多阀门!好在计算机的速度快,暴力的计算加上算法的优化,总是可以很快给出一个解决方案,调好所有阀门,让出口处的流量符合要求。

    深度学习-识别田字

    下一步,学习“申”字时,我们就用类似的方法,把每一张写有“申”字的图片变成一大堆数字组成的水流,灌进水管网络,看一看,是不是写有“申”字的那个管道出口流水最多,如果不是,我们还得再调整所有的阀门。这一次,要既保证刚才学过的“田”字不受影响,也要保证新的“申”字可以被正确处理。

    深度学习-学习申字

    如此反复进行,知道所有汉字对应的水流都可以按照期望的方式流过整个水管网络。这时,我们就说,这个水管网络是一个训练好的深度学习模型了。当大量汉字被这个管道网络处理,所有阀门都调节到位后,整套水管网络就可以用来识别汉字了。这时,我们可以把调节好的所有阀门都“焊死”,静候新的水流到来。

    深度学习-学习所有汉字

    与训练时做的事情类似,未知的图片会被计算机转变成数据的水流,灌入训练好的水管网络。这时,计算机只要观察一下,哪个出水口流出来的水流最多,这张图片写的就是哪个字。

    深度学习大致就是这么一个用人类的数学知识与计算机算法构建起来的整体架构,再结合尽可能多的训练数据以及计算机的大规模运算能力去调节内部参数,尽可能逼近问题目标的半理论、半经验的建模方式。

    传统机器学习 VS 深度学习

    传统机器学习和深度学习的相似点

    传统机器学习和深度学习的相似点

    在数据准备和预处理方面,两者是很相似的。

    他们都可能对数据进行一些操作:

    • 数据清洗
    • 数据标签
    • 归一化
    • 去噪
    • 降维

    对于数据预处理感兴趣的可以看看《AI 数据集最常见的6大问题(附解决方案)

    传统机器学习和深度学习的核心区别

    传统机器学习和深度学习的核心区别

    传统机器学习的特征提取主要依赖人工,针对特定简单任务的时候人工提取特征会简单有效,但是并不能通用。

    深度学习的特征提取并不依靠人工,而是机器自动提取的。这也是为什么大家都说深度学习的可解释性很差,因为有时候深度学习虽然能有好的表现,但是我们并不知道他的原理是什么。

    深度学习的优缺点

    深度学习的优缺点

    优点1:学习能力强

    从结果来看,深度学习的表现非常好,他的学习能力非常强。

    优点2:覆盖范围广,适应性好

    深度学习的神经网络层数很多,宽度很广,理论上可以映射到任意函数,所以能解决很复杂的问题。

    优点3:数据驱动,上限高

    深度学习高度依赖数据,数据量越大,他的表现就越好。在图像识别、面部识别、NLP 等部分任务甚至已经超过了人类的表现。同时还可以通过调参进一步提高他的上限。

    优点4:可移植性好

    由于深度学习的优异表现,有很多框架可以使用,例如 TensorFlowPytorch。这些框架可以兼容很多平台。

    缺点1:计算量大,便携性差

    深度学习需要大量的数据很大量的算力,所以成本很高。并且现在很多应用还不适合在移动设备上使用。目前已经有很多公司和团队在研发针对便携设备的芯片。这个问题未来会得到解决。

    缺点2:硬件需求高

    深度学习对算力要求很高,普通的 CPU 已经无法满足深度学习的要求。主流的算力都是使用 GPU 和 TPU,所以对于硬件的要求很高,成本也很高。

    缺点3:模型设计复杂

    深度学习的模型设计非常复杂,需要投入大量的人力物力和时间来开发新的算法和模型。大部分人只能使用现成的模型。

    缺点4:没有"人性",容易存在偏见

    由于深度学习依赖数据,并且可解释性不高。在训练数据不平衡的情况下会出现性别歧视、种族歧视等问题。

    4种典型的深度学习算法

    4种典型的深度学习算法

    卷积神经网络 - CNN

    CNN 的价值:

    1. 能够将大数据量的图片有效的降维成小数据量(并不影响结果)
    2. 能够保留图片的特征,类似人类的视觉原理

    CNN 的基本原理:

    1. 卷积层 – 主要作用是保留图片的特征
    2. 池化层 – 主要作用是把数据降维,可以有效的避免过拟合
    3. 全连接层 – 根据不同任务输出我们想要的结果

    CNN 的实际应用:

    1. 图片分类、检索
    2. 目标定位检测
    3. 目标分割
    4. 人脸识别
    5. 骨骼识别

    了解更多《一文看懂卷积神经网络-CNN(基本原理+独特价值+实际应用)

    循环神经网络 - RNN

    RNN 是一种能有效的处理序列数据的算法。比如:文章内容、语音音频、股票价格走势…

    之所以他能处理序列数据,是因为在序列中前面的输入也会影响到后面的输出,相当于有了“记忆功能”。但是 RNN 存在严重的短期记忆问题,长期的数据影响很小(哪怕他是重要的信息)。

    于是基于 RNN 出现了 LSTM 和 GRU 等变种算法。这些变种算法主要有几个特点:

    1. 长期信息可以有效的保留
    2. 挑选重要信息保留,不重要的信息会选择“遗忘”

    RNN 几个典型的应用如下:

    1. 文本生成
    2. 语音识别
    3. 机器翻译
    4. 生成图像描述
    5. 视频标记

    了解更多《一文看懂循环神经网络-RNN(独特价值+优化算法+实际应用)

    生成对抗网络 - GANs

    假设一个城市治安混乱,很快,这个城市里就会出现无数的小偷。在这些小偷中,有的可能是盗窃高手,有的可能毫无技术可言。假如这个城市开始整饬其治安,突然开展一场打击犯罪的「运动」,警察们开始恢复城市中的巡逻,很快,一批「学艺不精」的小偷就被捉住了。之所以捉住的是那些没有技术含量的小偷,是因为警察们的技术也不行了,在捉住一批低端小偷后,城市的治安水平变得怎样倒还不好说,但很明显,城市里小偷们的平均水平已经大大提高了。

    警察们开始继续训练自己的破案技术,开始抓住那些越来越狡猾的小偷。随着这些职业惯犯们的落网,警察们也练就了特别的本事,他们能很快能从一群人中发现可疑人员,于是上前盘查,并最终逮捕嫌犯;小偷们的日子也不好过了,因为警察们的水平大大提高,如果还想以前那样表现得鬼鬼祟祟,那么很快就会被警察捉住。为了避免被捕,小偷们努力表现得不那么「可疑」,而魔高一尺、道高一丈,警察也在不断提高自己的水平,争取将小偷和无辜的普通群众区分开。随着警察和小偷之间的这种「交流」与「切磋」,小偷们都变得非常谨慎,他们有着极高的偷窃技巧,表现得跟普通群众一模一样,而警察们都练就了「火眼金睛」,一旦发现可疑人员,就能马上发现并及时控制——最终,我们同时得到了最强的小偷和最强的警察。

    同时得到了最强的小偷和最强的警察

    了解更多《什么是生成对抗网络 - GAN?(基本概念+工作原理)

    深度强化学习 - RL

    强化学习算法的思路非常简单,以游戏为例,如果在游戏中采取某种策略可以取得较高的得分,那么就进一步「强化」这种策略,以期继续取得较好的结果。这种策略与日常生活中的各种「绩效奖励」非常类似。我们平时也常常用这样的策略来提高自己的游戏水平。

    在 Flappy bird 这个游戏中,我们需要简单的点击操作来控制小鸟,躲过各种水管,飞的越远越好,因为飞的越远就能获得更高的积分奖励。

    这就是一个典型的强化学习场景:

    • 机器有一个明确的小鸟角色——代理
    • 需要控制小鸟飞的更远——目标
    • 整个游戏过程中需要躲避各种水管——环境
    • 躲避水管的方法是让小鸟用力飞一下——行动
    • 飞的越远,就会获得越多的积分——奖励

    游戏是典型的强化学习场景

    你会发现,强化学习和监督学习、无监督学习 最大的不同就是不需要大量的“数据喂养”。而是通过自己不停的尝试来学会某些技能。

    了解更多:《一文看懂什么是强化学习?(基本概念+应用场景+主流算法)

    总结

    深度学习属于机器学习的范畴,深度学习可以说是在传统神经网络基础上的升级,约等于神经网络。

    深度学习和传统机器学习在数据预处理上都是类似的。核心差别在特征提取环节,深度学习由机器自己完成特征提取,不需要人工提取。

    深度学习的优点:

    1. 学习能力强
    2. 覆盖范围广,适应性好
    3. 数据驱动,上限高
    4. 可移植性好

    深度学习的缺点:

    1. 计算量大,便携性差
    2. 硬件需求高
    3. 模型设计复杂
    4. 没有"人性",容易存在偏见

    深度学习的4种典型算法:

    1. 卷积神经网络 - CNN
    2. 循环神经网络 - RNN
    3. 生成对抗网络 - GANs
    4. 深度强化学习 - RL
    展开全文
  • 一张图解释典型编译程序结构框图

    千次阅读 2017-10-04 11:10:14
    编译程序结构框图

    编译程序结构框图

    这里写图片描述

    展开全文
  • [+] 注册流程注销流程基本呼叫建立过程会话更改流程正常呼叫释放过程被叫忙呼叫释放被叫无应答流程一被叫无应答流程二遇忙呼叫前转无应答呼叫前转流程呼叫保持呼叫等等 ...1 2.注销流程:... 3 ...
  • 装饰器本质上是个python函数,实现是由闭包支撑的 应用场景: 1,引入日志 2,函数执行时间统计 3,执行函数前预备处理 4,执行函数后清理功能 5,权限校验等场景 6,缓存 7,事务处理 ...
  • 大数据架构的典型方法方式

    万次阅读 2016-06-04 15:15:30
    NoSQL 技术为应用提供了缓存搜索特性,但既然是处理数据,就需要定义一种方法来处理各种数据流,以便能够给用户输出见解或数据服务。通过审视被IT组织使用广泛的数据架构来定义处理的拓扑结构。当考虑服务水平SLA...
  • 解释编译器区别联系

    千次阅读 2016-09-18 19:46:51
    比如php,postscritp,javascript就是典型解释性语言。  编译器是把源代码整个编译成目标代码,执行时不在需要编译器,直接在支持目标代码的平台上运行,这样执行效率比解释执行快很多。比如C语言代码被编译成二...
  • 编译器和解释器的区别

    千次阅读 2018-02-07 14:18:31
     菜鸟经常将编译器和解释器弄混淆,无奈之下,于是向高手请教。  高手说: “  解释器是一条一条的解释执行源语言。比如php,postscritp,javascript就是典型解释性语言。   编译器是把源代码整个...
  • 运放参数的详细解释和分析

    万次阅读 多人点赞 2014-09-18 16:47:14
    输入偏置电流输入失调电流
  • 超赞!编译器和解释器的异同,瞬间明白了

    万次阅读 多人点赞 2017-11-28 22:34:15
    菜鸟经常将编译器和解释器弄混淆,无奈之下,于是向高手请教。  高手说: “  解释器是一条一条的解释执行源语言。比如php,postscritp,javascript就是典型解释性语言。   编译器是把源代码整个编译...
  • 解释型语言编译型语言的区别

    万次阅读 多人点赞 2013-11-24 17:58:28
    解释型语言编译型语言的区别 首先,我们编程都是用的高级语言(写汇编机器语言的大牛们除外),计算机不能直接理解高级语言,只能理解运行机器语言,所以必须要把高级语言翻译成机器语言,计算机才能运行高级...
  • 典型推荐算法总结

    万次阅读 多人点赞 2018-11-23 21:05:42
    推荐算法种类很多,但是目前应用最广泛的应该是协同过滤类别的推荐算法,本文就对协同过滤类别的推荐算法做一个概括总结,后续也会对一些典型的协同过滤推荐算法做原理总结。 1. 推荐算法概述  推荐算法是非常...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 262,798
精华内容 105,119
关键字:

典型解释和意思