Java中的动态代理

JAVA 动态代理的实现方式! JDK动态代理要求被代理对象必须基于接口来实现。动态代理类和被代理类必须继承同一个接口。动态代理只能对接口中声明的方法进行代理。而CGLib通过继承被代理类的方式实现代理。CGLib通过继承被代理类的方式实现代理。动态代理:无需声明代理类。是使用反射和字节码的技术,在运行期创建指定接口或类的子类(即动态代理类)以及其实例对象的技术。动态代理类和被代理类必须继承同一个接口。动态代理只能对接口中声明的方法进行代理。代理类可以增强被代理对象的方法。2.3 JDK动态代理 VS CGLib动态代理。 阅读详情

一、Java中的两种动态代理方式

Java中常用的有两种动态代理方式,分别为:JDK动态代理和Cglib动态代理。

JDK动态代理是通过实现接口的方式完成动态代理。

Cglib动态代理是通过继承目标类或实现接口的方式完成动态代理。

二、JDK动态代理

JDK动态代理中最核心的就是Proxy类和InvocationHandler接口。

Proxy类

通过调用这个类中的静态方法newProxyInstance(),可以返回代理对象。

newProxyInstance()方法需要三个参数,分别是:ClassLoader类加载、目标对象实现的所有接口、InvocationHandler实现类。

InvocationHandler接口

这个接口中有一个invoke方法,代理对象通过调用这个方法对目标方法进行增强。

三、案例

需求

需求:创建计算器类,进行加减乘除运算。同时需要在进行加减乘除之前打印参数信息,在加减乘除之后打印计算结果。

创建类实现功能

创建Calculator计算器接口,提供加减乘除方法,创建实现类,并完成打印参数与计算结果的功能。

接口:

package com.demo.dynamic_proxy.jdk;

/**
 * 计算器接口 有加减乘除功能
 */
public interface Calculator {
    int add(int a, int b);  // 加法
    int sub(int a, int b);  // 减法
    int mul(int a, int b);  // 乘法
    int div(int a, int b);  // 除法
}

实现类:

public class CalculatorImpl implements Calculator {

    @Override
    public int add(int a, int b) {
        System.out.println("执行add方法,参数信息:" + a + "," + b);
        int result = a + b;
        System.out.println("add方法执行完毕,计算结果:" + result);
        return result;
    }

    @Override
    public int sub(int a, int b) {
        System.out.println("执sub方法,参数信息:" + a + "," + b);
        int result = a + b;
        System.out.println("sub方法执行完毕,计算结果:" + result);
        return result;
    }

    @Override
    public int mul(int a, int b) {
        System.out.println("执行mul方法,参数信息:" + a + "," + b);
        int result = a + b;
        System.out.println("mul方法执行完毕,计算结果:" + result);
        return result;
    }

    @Override
    public int div(int a, int b) {
        System.out.println("执行div方法,参数信息:" + a + "," + b);
        int result = a + b;
        System.out.println("div方法执行完毕,计算结果:" + result);
        return result;
    }
}

分析存在的问题

如果将打印参数信息和打印计算结果的代码都写到实现类中,会出现以下问题:

1)代码比较分散,过于冗余 ,可以将打印参数信息和结果的代码提取到工具类中。

2)代码过于混乱,非核心业务代码(输出语句)与核心业务代码(加减乘除操作)混合到了一起,不好维护。

可以通过动态代理的方式,对功能进行增强,不需要在业务代码(加减乘除的运算)中添加非核心业务代码(打印参数和结果的代码)。

改进代码

将代码提取到工具类中

package com.demo.dynamic_proxy.jdk.util;

import java.util.Arrays;

public class Logging {
    /**
     * 方法执行前打印参数
     * @param className     类名
     * @param methodName    方法名
     * @param args          执行方法时的参数
     */
    public static void beforeMethod(String className, String methodName, Object[] args){
        System.out.println("执行" + className + "类中的" + methodName + "方法,参数:" + Arrays.toString(args));
    }

    /**
     * 方法执行后打印执行结果
     * @param className     类名
     * @param methodName    方法名
     * @param result        方法的返回值
     */
    public static void afterMethod(String className, String methodName, Object result){
        System.out.println(className + "类中的" + methodName + "方法执行完毕,结果:" + result);
    }
}

使用动态代理的方式对功能进行增强

增强的功能:方法执行之前打印参数、方法执行之后打印结果。

实现步骤,分为四步:

1)创建类【用来生成代理对象】

2)在类中提供目标对象属性 ,需要被增强的对象。

3)在类中提供有参构造器为目标对象属性赋值 。

4)提供获取代理对象的方法。

package com.demo.dynamic_proxy.jdk;

import com.demo.dynamic_proxy.jdk.util.Logging;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyProxy {

    // 目标对象,需要增强的对象
    private Object target;

    // 有参构造器为目标对象进行赋值
    public MyProxy(Object target) {
        this.target = target;
    }

    // 获取代理对象的方法
    public Object getProxyObject(){
        // 代理对象
        Object proxyObject = null;
        // 获取类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        // 获取目标对象实现的所有接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        // 调用Proxy.newProxyInstance()方法,创建代理对象
        proxyObject = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            /**
             * @param proxy     代理对象
             * @param method    要执行的方法
             * @param args      执行方法时需要的参数
             * @return  调用目标对象方法后返回的执行结果
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 目标对象类名
                String targetClassName = target.getClass().getName();
                // 要执行的方法名
                String targetMethodName = method.getName();
                // 在方法调用之前,打印方法参数
                Logging.beforeMethod(targetClassName, targetMethodName, args);
                // 调用目标对象的方法
                Object result = method.invoke(target, args);
                // 调用方法之后,输出执行结果
                Logging.afterMethod(targetClassName, targetMethodName, result);
                // 将执行结果返回
                return result;
            }
        });
        // 将代理对象返回
        return proxyObject;
    }
}

测试代码

@Test
public void test(){
    // 创建目标对象,也就是需要被增强的对象
    CalculatorImpl calculator = new CalculatorImpl();
    // 创建MyProxy并获取代理对象
    MyProxy myProxy = new MyProxy(calculator);
    Calculator proxyObject = (Calculator) myProxy.getProxyObject();
    // 调用方法
    proxyObject.add(1, 2);
}

执行结果:

执行com.demo.dynamic_proxy.jdk.impl.CalculatorImpl类中的add方法,参数:[1, 2]
正在执行add方法......
com.demo.dynamic_proxy.jdk.impl.CalculatorImpl类中的add方法执行完毕,结果:3

我们通过动态代理的方式完成了参数和执行结果的打印功能,以后需要调整打印信息时,只需要修改一处即可。

四、底层原理分析

JDK动态代理是如何生成代理对象的呢?底层真的没有创建类吗?

底层其实是有创建类的,Java中必须有类才能够使用这个类的实例,JDK动态代理运行时,底层创建代理类实现目标对象的接口,并生成代理类的字节码,通过类加载器将字节码进行加载,最后再生成代理类对象实例。

查看Proxy类的newProxyInstance()方法:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         */
        // 通过这个方法来生成代理类
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            // 创建代理类实例
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

其中,通过getProxyClass0方法来获取代理类

Class<?> cl = getProxyClass0(loader, intfs);

getProxyClass0方法中有一段核心的代码:

byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces);

这段代码就是生成代理类的字节码信息的。

我们试着调用这个方法,并获取到class字节码:

@Test
public void test01(){
    // 要生成的类的名称
    String className = "myClass";
    // 指定class类名以及代理类要实现的接口
    byte[] bytes = ProxyGenerator.generateProxyClass(className, new Class[]{Calculator.class});
    FileOutputStream fos = null;
    try {
        // 将生成的字节信息输出到 myClass.class
        fos = new FileOutputStream(new File("D:\\" + className + ".class"));
        fos.write(bytes);
    }catch (Exception e){
        System.out.println(e.getMessage());
    }finally {
        if(fos != null){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用反编译工具打开class文件,这里使用的是IDEA:

字节码中的add方法:

完整代码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import com.demo.dynamic_proxy.jdk.Calculator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class myClass extends Proxy implements Calculator {
    private static Method m1;
    private static Method m2;
    private static Method m4;
    private static Method m3;
    private static Method m6;
    private static Method m5;
    private static Method m0;

    public myClass(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int mul(int var1, int var2) throws  {
        try {
            return (Integer)super.h.invoke(this, m4, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final int add(int var1, int var2) throws  {
        try {
            return (Integer)super.h.invoke(this, m3, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final int sub(int var1, int var2) throws  {
        try {
            return (Integer)super.h.invoke(this, m6, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final int div(int var1, int var2) throws  {
        try {
            return (Integer)super.h.invoke(this, m5, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("com.demo.dynamic_proxy.jdk.Calculator").getMethod("mul", Integer.TYPE, Integer.TYPE);
            m3 = Class.forName("com.demo.dynamic_proxy.jdk.Calculator").getMethod("add", Integer.TYPE, Integer.TYPE);
            m6 = Class.forName("com.demo.dynamic_proxy.jdk.Calculator").getMethod("sub", Integer.TYPE, Integer.TYPE);
            m5 = Class.forName("com.demo.dynamic_proxy.jdk.Calculator").getMethod("div", Integer.TYPE, Integer.TYPE);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

五、总结

  1. JDK动态代理是通过实现接口的方式完成对目标对象功能的增强。

  1. JDK动态代理底层创建代理类,实现目标对象所实现的接口,并生成代理类的字节码信息,通过类加载器进行加载,最后创建代理类对象,通过代理对象调用InvocationHandler接口实现类的invoke方法完成功能的增强。

  1. 通过调用Proxy类的newProxyInstance方法创建代理对象,代理对象调用InvocationHandler接口中的invoke实现对目标对象的增强功能。

Java 动态代理原理图解 (附:2种实现方式详细对比) 动态代理在 Java 中有着广泛的应用,例如:Spring AOP 面向切面编程,Hibernate 数据查询、以及 RPC Dubbo 远程调用等,都有非常多的实际应用。 阅读详情

相关推荐

什么是 Java 中的动态代理?

动态代理是 Java 提供的一种机制,它允许在运行时动态创建代理类和对象,而无需手动编写代理类的代码。代理对象可以在不改变目标对象代码的情况下,为目标对象扩展功能。

2302_81141145的博客 1234

JAVA的动态代理详解

动态代理有什么作用?如何使用动态代理?

biyn9的博客 1万+

Java中的动态代理——附带动态代理源码跟踪分析

代理是基本的设计模式之一,它是为了插入一些额外操作或者不同操作而插入的“实际”对象的对象,它通常在实际被访问对象与访问者之间承当着中间人的职能,代替访问者去访问真实对象。当然有,接下来,我将采用动态代理的方式简化代理类的代码,让一个类实现N个代理类的功能。如果能看到生成的Proxy内部的实现,动态代理的谜团就解开了,继续跟踪Step6。在项目根目录下会生成一个文件夹,java中动态代理生成的类都以$ProxyX命名,调试代码的时候看到这种命名的类,那么这个类就是动态代理生成的。代理类的内部长啥样?

terase梅 1068

java动态代理

前段时间去学习了一下RPC原理,其中提到了动态代理。特意去学习了一下,为了防止以后忘记,写下这篇博客做个记录,有不对的地方欢迎指正。 java中的常见的动态代理如Spring AOP。关于动态代理首先需要了解代理模式,根据代理类的创建时间又可以分为静态代理和动态代理。 1、代理模式 代理模式是常见的设计模式之一,Java我们通常通过new一个对象然后调用其对应的方法来访问我们需要的服务。代理模式则...

飞!!!的博客 5万+

Java动态代理两种实现方式

Java实现动态代理的两种方式。 相对来说cglib更加方便。可以实现为实现接口的类(非final类)

PCIE Lane Margining Linux 环境配置

Copy all the provided files in folder PYC38 or PYC310 to the created pcie_lmt folder. Index of /ftp/python/3.8.10/Copy below commands to a file and rename it as "scan_pcie.py", the commands are from "685662 PCIe-LMT-Gen4_Gen5-r0p77.pdf" in the lane margi

mysongshine的博客 1436

Java中的动态代理是什么?

动态代理在Java中提供了一种灵活的方式来控制方法调用,广泛应用于各种场景,如AOP(面向切面编程)、框架开发等。

weixin_73526362的博客 1194

告别以太网瓶颈:手把手教你为AI训练集群搭建InfiniBand网络(以NVIDIA DGX A100/H100为例)

本文详细指导如何为AI训练集群搭建InfiniBand网络,解决以太网瓶颈问题,特别针对NVIDIA DGX A100/H100系统。通过硬件选型、网络架构设计和性能调优,显著提升多机多卡训练效率,适用于大规模模型训练场景。

weixin_30336061的博客 310

Java中的动态代理详解

转载:https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html 前言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对...

2188

AI写作:为AI人工智能领域赋能

AI写作技术作为自然语言处理(NLP)领域的重要应用方向,正在深刻改变内容创作的方式。系统介绍AI写作的技术原理分析主流AI写作模型的架构特点提供实践性的代码示例探讨实际应用中的关键问题展望未来发展趋势本文涵盖从基础理论到高级应用的完整知识体系,适用于希望深入了解AI写作技术的开发者和研究人员。背景介绍:建立基本概念框架核心概念:解析关键技术原理算法实现:通过代码演示具体实现数学原理:深入底层数学模型实践应用:展示真实场景案例资源推荐:提供学习路径和工具。

AI天才研究院 3054

基于ESP32的无线DMX节点设计:从Art-Net/sACN到DMX512的协议转换与实现

在舞台灯光和建筑照明控制系统中,DMX512是行业标准的数字调光协议,用于控制灯具的亮度、颜色和效果。其原理是通过RS-485差分信号串行传输512个通道的数据,每个通道对应一个控制值。然而,传统有线DMX布线复杂、成本高,在移动装置、历史建筑或临时活动中部署困难。为解决此问题,业界发展出了基于以太网的灯光控制协议,如Art-Net和sACN(E1.31),它们将DMX数据封装在UDP包中,通过网络传输。这项技术的核心价值在于实现了灯光控制的网络化与无线化,大幅提升了系统的灵活性和部署效率。其典型应用场景包

weixin_30175731的博客 227

Java中的动态代理模式

代理模式是一种结构型设计模式,为其他对象提供一个代理以控制对这个对象的访问。

wu17852323162的博客 1026

MATLAB实战:5步搞定铣削稳定性叶瓣图(附完整代码解析)

本文提供了一份基于MATLAB的铣削稳定性叶瓣图实战指南。通过5个清晰步骤,从动力学原理出发,详细解析了利用半离散法构建稳定性判据、模块化代码设计、高效参数扫描及高级可视化的完整流程,并附有完整代码,帮助工程师快速预测和规避加工颤振,优化铣削工艺参数。

weixin_29197051的博客 194

Java动态代理与Spring AOP中的Cglib动态代理详解

在Java编程中,动态代理是一种在运行时动态创建代理类及其对象的技术。通过动态代理,我们可以在不修改原有类代码的情况下,为这些类添加新的行为或功能。Java提供了两种主要的动态代理机制:基于接口的Java动态代理和基于类的Cglib动态代理。在Spring AOP(面向切面编程)中,Cglib动态代理扮演着重要角色。本文将详细讨论这两种动态代理的实现。

dazhong2012的专栏 2023

一步一步详解LSTM网络【从RNN到LSTM到GRU等,直至attention】

本文主要译至并加上了部分笔者的见解,对于全面理解LSTM有一定的帮助。

zik的博客 3078

低功耗边缘设备部署指南:YOLO26 INT8量化与TensorRT加速全流程

将YOLO26 INT8部署到低功耗边缘设备,核心原则是“校准为王、敏感层精准回退、端到端验证”。校准集≥500张,来自真实推理场景,未经训练增强校准集预处理与推理pipeline逐行对齐trtexec命令必带--fp16作为fallback量化后用polygraphy定位敏感层,而非盲猜仅回退必要层(通常2-3个),保留INT8收益在真实部署场景测试集上验证mAP,不以COCO为准C++部署使用异步推理+双缓冲nsys profiling确认无传输瓶颈。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 212

Java动态代理

Java动态代理

YIYIYI 1131

Python 实战:爬取高德地图交通数据(路况拥堵指数分析)

高德地图是由高德软件有限公司开发的一款地图导航产品,提供详细的地图浏览、路线规划、实时路况、公共交通查询等功能。高德地图拥有庞大的用户群体和海量的交通数据,这些数据对于交通管理、城市规划、出行服务等领域具有重要的价值。通过对高德地图交通数据的分析,我们可以了解城市交通的运行状况,识别拥堵路段,预测交通流量,为交通管理部门和出行者提供决策支持。

yansideyucsdn的博客 2684

java动态代理和cglib动态代理

Java 动态代理和Cglib动态代理

leon709的专栏 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JAVA动态代理

动态代理是Java实现AOP的核心技术,通过运行时生成代理对象解耦业务逻辑与非功能性需求。JDK动态代理适用于接口代理,CGLIB适用于无接口的类代理。实际开发中,优先选择JDK动态代理;若目标类无接口,则使用CGLIB。

2401_89221445的博客 1080

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

下一篇: JdbcTemplate的使用
qingfengmax
博客等级 码龄9年 6粉丝 7原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值