多线程面试要点

Java多线程面试核心要点与实战解析 多线程编程是Java开发中的核心技术,涉及线程生命周期、同步机制、并发工具等多个维度。理解线程状态转换(如RUNNABLE、BLOCKED等)和同步原理(如synchronized、ReentrantLock)是基础。Java内存模型(JMM)的happens-before规则保证了多线程环境下的可见性和有序性。在实际应用中,合理使用线程池(如ThreadPoolExecutor)和并发集合(如ConcurrentHashMap)能显著提升系统性能。面试中常考察的CAS原理、死锁排查等问题,反映了候选人对并 阅读详情

一、线程的基础知识

1、线程和进程的区别

一个线程就是一个指令流,将指令流中的一条条指令以一定顺序交给CPU执行

一个进程之内可以分为一到多个线程。

二者对比

进程是正在运行程序的实例,进程中包含了线程,每个线程执行不同的任务。

不同的进程使用不同的内存空间,在当前进程下的所有线程可以共享内存空间。

线程更轻量,线程上下文切换成本一般上要比进程上下文切换低(上下文切换是指从一个线程切换到另外一个线程)

2、并行和并发的区别

单核CPU

  • 单核CPU下线程实际还是串行执行的
  • 操作系统中有一个组件叫作任务调度器,将CPU的时间片分给不同的程序使用,只是由于CPU在线程间(时间片很短)切换的非常快,人类的感觉是同时运行的。
  • 一般会将这种线程轮流使用CPU的做法称为并发(concurrent)

并发:(concurrent)是同一时间应对(dealing with)多件事情的能力,多个线程轮流使用一个或多个CPU

并发:(parallel)是同一时间动手做(doing)多件事的能力,4个CPU同时处理4个线程。

3、创建线程的方式有哪些

1)继承Thread类

public class MyThread extends Thread{

    @Override
    public void run(){
        System.out.println();
    }

    public static void main(String[]args){
        //创建线程
        MyThread my1 = new MyThread();
        my1.start();
    }
}

2)实现runable接口

public class MyRunable implements Runnable{
    @Override
    public void run(){
        System.out.println("");
    }
    public static void main(String[]args){
        MyRunable my = new MyRunable();
        my.start();
    }
}

3)实现Callable接口

public class MyCallable implements Callable<String>{

    @Override
    public String call() throws Exception(){
        System.out.println(System.currentThread().getName());
        return "OK";
    }

    public static void main(String[]args){
        MyCallable my = new MyCallable();
        FutureTask<String> ft = new FutureTask<String>(my);
        Thread t1 = new Thread(ft);
        t1.start();
        String result = ft.get();
        System.out.println(result);
    }
}

4)线程池创建线程

public class MyExecutors implements Runnable{

    @Override
    public void run(){
        System.out.println("MyRunnable ... run ...");
    }

    public static void main(String[]args){
        //创建线程池对象
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        threadPool.submit(new MyExecutors());

        //关闭线程池
        threadPool.shutdown();
    }
}

2、Runnable 和 Callable有什么区别?

Runnable 接口run方法没有返回值

Callable接口call方法有返回值,是个泛型,和Future、FutureTask配合可以获取异步执行的结果。

Callable接口的call方法允许抛出异常;而Runnable接口的run不能抛出异常。

3、启动线程的时候,可以使用run方法吗?run()和start()方法执行有什么不同

可以使用run方法。

run():只是一个普通方法可以执行多次。

start() :用来启动线程,通过该线程调用run方法执行run方法中所定义的逻辑。start只能执行一次。

4、线程间包括哪些状态,状态之间是如何变化的

5、新建T1、T2、T3 三个线程,如何保证它们按顺序执行

可以使用线程中的join方法解决

join() 等待线程运行结束。

t.join() 阻塞调用此方法的线程进入 timed_waiting。

直到线程t执行完成后,此线程再继续执行。

6、notify()和notifyAll() 有什么区别

notify() :随机唤醒一个处于wait状态下的线程。

notifyAll():唤醒全部处于wait状态下的线程。

7、java中wait和sleep方法的不同

共同点

wait(),wait(long)和sleep(long) 的效果都是让当前线程暂时放弃CPU的使用权,进入阻塞状态。

不同点

1、方法归属不同

  • sleep(long) 是Thread的静态方法。
  • 而wait(),wait(long)都是Object的成员方法,每个对象都有。

2、醒来时机不同

  • 执行sleep(long) 和 wait(long)的线程都会在等待相应毫秒后醒来。
  • wait(long) 和 wait() 还可以被notify唤醒,wait()如果不唤醒一直等下去。
  • 它们都可以被打断唤醒。

3、锁特性不同(重点)

  • wait 方法的调用必须先获取wait对象的锁,而sleep则无此限制。
  • wait方法执行后会释放对象锁,允许其它线程获得该对象锁(我放弃cpu,其它线程可以用)。
  • 而sleep如果再synchronized代码中执行,并不会释放对象锁(我放弃cpu,其它线程也不能用)。

8、如何停止一个正在运行的线程

有三种方式可以停止线程

  • 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
  • 使用stop方法强行终止(不推荐,方法已作废)。
  • 使用interrupt方法中断线程
    1. 打断阻塞的线程(sleep,wait,join)的线程,线程会抛出InterruptedException异常
    2. 打断正常线程,可以根据打断状态来标记是否退出线程。

二、线程中并发安全

1、Synchronized 互斥锁

Synchronized 对象锁,采用互斥的方式让同一时刻至多只有一个线程能持有 对象锁,其它线程再获取这个对象锁时就会阻塞住。

Monitor

Monitor被翻译为监视器,是由jvm提供,c++语言实现。

Owner:存储当前获取锁的线程,只能有一个线程可以获取

EntryList:关联没有抢到锁的线程,处于Blocked状态的线程。

WaitSet: 关联调用了wait方法的线程,处于waiting状态的线程。

2、Synchronized 关键字的底层原理。

基础

  • Synchronized[对象锁]采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】。
  • 它的底层由monitor实现的,monitor是jvm级别的对象(C++实现),线程获得锁需要使用对象(锁)关联monitor。
  • 在monitor内部有三个属性,分别是owner、entrylist、waitset。
  • 其中owner是关联的获得锁的线程,并且只能关联一个线程;entrylist管理的是处于阻塞状态的线程,waitset是线程调用wait(),处于waiting状态的线程。

进阶

  • Monitor实现的锁属于重量级锁,锁升级过程。
  • Monitor实现的锁属于重量级锁,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能较低。
  • 在JDK1.6引入了两种新型锁机制: 偏向锁和轻量级锁,它们的引入是为了在没有多线程竞争或基本没有竞争的场景下因使用传统所机制带来的性能开销问题。
3、对象的内存结构

在HotSpot虚拟机中,对象在内存中存储的布局可分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充。

MarkWord

4、Monitor重量级锁

每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Wrod中就被重置指向Monitor对象的指针。

5、轻量级锁

在Java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步块中的代码。这种情况下,用重量级锁都是没必要的。因此JVM引入了轻量级锁的概念。

1、加锁流程

1)在线程栈中创建一个Lock Record,将其obj字段指向锁对象。

2)通过CAS指令将Lock Record的地址存储在对象头的mark word中,如果对象处于无锁状态则修改成功,代表该线程获得了轻量级锁。

3)如果是当前线程已经持有了该锁了,代表这是一次锁重入了。设置Lock Record第一部分为null,起到了一个重入计数的作用

4)如果CAS修改失败,说明发生了竞争,需要膨胀为重量级锁。

2、解锁过程

1)遍历线程栈,找到所有obj字段等于当前锁对象的Lock Record。

2)如果Lock Record的Mark Word为null,代表这是一次重入,将obj设置为null后continue。

3)如果Lock Record的 Mark Word不为null,则利用CAS指令将对象头的mark word恢复成为无锁状态。如果失败则膨胀为重量级锁。

6、偏向锁

轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行CAS操作。

Java 6 中引入了偏向锁来做进一步优化:只有第一次使用CAS将线程ID设置到对象的Mark word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有。

7、Monitor实现的锁属于重量级锁,锁的升级过程?

Java中的synchronized有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有,不同线程交替持有锁、多线程竞争锁三种情况。

8、Java内存模型(JMM)

JMM(Java Memory Model)Java内存模型,定义了共享内存中多线程程序读写操作的行为规范,通过这些规则规范对内存的读写操作从而保证指令的正确性。

谈谈JMM(Java内存模型)

JMM java内存模型,定义了共享内存中多线程读写操作的行为规范,通过这些规则来规范对内存的读写操作从而保证指令的正确性。

JMM把内存分为两块,一块是私有线程的工作区域(工作内存),一块是所有线程的共享区域(主内存)。

线程跟线程之间是相互隔离,线程跟线程交互需要通过主内存。

9、CAS

CAS的全称是:Compare And Swap(比较再交换),它体现的一种乐观锁的思想,在无锁情况下保证线程操作共享数据的原子性。

在JUC(java.util.concurrent)包下实现的很多类都用到了CAS操作。

AbstractQueuedSynchronizer(AQS框架)

AtomicXXX类

10、CAS数据交换流程

一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当旧的预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。如果CAS操作失败,通过自旋的方式等待并再次尝试,直到成功

因为没有加锁,所以线程不会陷入阻塞,效率较高

如果竞争激烈,重试频繁发生,效率会受影响

11、乐观锁和悲观锁

CAS是基于乐观锁的思想:最乐观的设想,不怕别的线程来修改共享变量,就算改了也没关系,自旋重试。

synchronized 是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,上锁之后谁都不能修改。

12、volatile的理解

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具有两层含义

1)保证线程间的可见性

2)禁止进行指令重排序

用volatile修饰共享变量,能够防止编译器等优化发生,让一个线程对共享变量的修改对另一个线程可见。

13、谈谈你对volatile的理解

问题分析:主要是因为JVM虚拟机中有一个JIT(即时编译器)给代码做了优化。

解决方案一:在程序运行的时候加入vm参数-Xint表示禁用即时编译器,不推荐,得不偿失。

解决方案二:在修饰stop变量的时候加上volatile,当前搞死JIT,不对volatile修饰的变量进行优化。

volatile禁止指令重排序

用volatile修饰共享变量会在读、写共享变量时加入不同的屏障,组织其他读写操作越过屏障,从而达到阻止重排序的效果。

volatile使用技巧:

  • 写变量让volatile修饰的变量在代码最后位置
  • 读变量让volatile修饰的变量在代码最开始位置

14、什么是AQS

全程是AbstractQueuedSynchronizer,即抽象队列同步器。它是构建锁或者其他同步组件的基础框架

AQS与Synchronized的区别

synchronized

AQS

关键字,c++语言实现

java 语言实现

悲观锁,自动释放锁

悲观锁,手动开启和关闭

锁竞争激烈都是重量级锁,性能差

锁竞争激烈的情况下,提供了多种解决方案

AQS常见的实现类

  • ReentrantLock 阻塞式锁
  • Semaphore 信号量
  • CountDownLatch 倒计时锁

AQS-基本工作机制

AQS是否是公平锁:

新的线程与队列中的线程共同来抢资源,是非公平锁。

新的线程到队列中等待,只让队列中的head线程获取锁,是公平锁。

15、ReentrantLock的实现原理

ReentrantLock翻译过来就是可重入锁,相对于synchronized具备以下特点:

  • 可中断。
  • 可以设置超时时间。
  • 可以设置公平锁。
  • 支持多个条件变量。
  • 与synchronized一样,都支持重入。

ReentrantLock主要利用CAS+AQS队列来实现。它支持公平锁和非公平锁,两者的实现类似。

构造方法接收一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。公平锁的效率往往没有非公平锁的效率高,在多线程访问的情况下,公平锁表现出较低的吞吐量。

1、ReentranLock的实现原理。

ReentrantLock表示支持重新进入的锁,调用lock方法获取了锁之后,再次调用lock,是不会再阻塞。

ReentrantLock主要利用CAS+AQS队列来实现。

支持公平锁和非公平锁,在提供的构造器中无参数默认是非公平锁,可以传参数设置为公平锁。

2、synchronized 和 Lock有什么区别

语法层面

synchronized是关键字,源码在jvm中,用c++语言实现。

Lock是接口,源码由jdk提供,用java语言实现。

使用synchronized时,退出同步代码块会自动释放,而使用Lock时,需要手动调用unlock方法。

功能层面

二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能。

Lock提供了许多synchronized不具备的功能,例如公平锁、可打断、可超时、多条件变量。

Lock有适合不同场景的实现,如ReentrantLock, ReentrantReadWriteLock(读写锁)。

性能层面

在没有竞争时,synchronized做了很多优化,如偏向锁、轻量级锁,性能不错。

在竞争激烈时,Lock的实现通常会提供更好的性能。

16、死锁产生的条件是什么

死锁:一个线程需要同时获取多把锁,这时容易产生死锁。

线程t1持有A的锁等待获取B锁,线程t2持有B的锁等待获取A锁。

1、如何进行死锁诊断

当程序出现死锁现象,可以使用jdk自带的工具:jps和jstack

jps:输出JVM中运行的进程状态信息。

jstack:查看java进程内线程的堆栈信息。

1.2 其它解决工具,可视化工具

jconsole

用于对jvm的内存,线程,类的监控,是一个基于jmx的GUI性能检测工具。

打开方式:java安装目录bin目录下 直接启动jconsole.exe就行。

VisualVM:故障处理工具

能够监控线程,内存情况,查看方法的CPU时间和内存中的对象,已被GC的对象,反向查看分配的堆栈。

打开方式:java安装目录bin目录下 直接启动 jvisualvm.exe就行。

17、聊一下ConcurrentHashMap

ConcurrentHashMap是一种线程安全的高效Map集合。

底层数据结构:

JDK1.7 底层采用分段的数组+链表实现。

JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。

1、JDK1.7中ConcurrentHashMap

2、JDK1.8中ConcurrentHashMap

18、导致并发程序出现问题的根本原因

Java并发编程的三大特性

  • 原子性
  • 可见性
  • 有序性

原子性:一个线程在CPU中操作不可暂停,也不可中断,要不执行完成,要不不执行。

不是原子操作,怎么保证原子操作呢?

  1. synchronized : 同步加锁
  2. JUC里面的lock:加锁

内存可见性:让一个线程对共享变量的修改对另一个线程可见。

解决方案: synchronized、volatile、LOCK

有序性:指令重排(JIT),处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。

解决方案:volatile

三、线程池

1、说一下线程池的核心参数

corePoolSize:核心线程数目

maximumPoolSize:最大核心线程数目 maximumPoolSize = 救急线程 + 核心线程

keepAliveTime:生存单位时间

TimeUnit:时间单位 毫秒、秒

BlockingQueue<Runnable>:当没有空闲核心线程时,新来的任务会加入到此队列排队,队列满会创建救急线程执行任务。

ThreadFactory:线程工厂 -可以定制线程对象的创建,例如设置线程名字、是否是守护线程等。

RejectedExecutionHandler:当所有线程都在繁忙,workQueue 也放满时,会触发拒绝策略。

2、线程池的执行原理

3、线程池中哪些常见的阻塞队列

workQueue - 当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务。

  1. ArrayBlockingQueue:基于数组结构的有界阻塞队列,FIFO。
  2. LinkedBlockingQueue:基于链表结构的有界阻塞队列,FIFO。
  3. DelayedWorkQueue:是一个优先级队列,它可以保证每次出队的任务都是当前队列中执行时间最靠前的。
  4. SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出
     
4、ArrayBlockingQueue与LinkedBlockingQueue的区别

5、如何确定核心线程数

IO密集型任务

一般来说:文件读写、DB读写、网络请求等 核心线程数大小设置为2N+1

CPU秘籍型任务

一般来说:计算型代码、Bitmap转换、Gson转换等 核心线程数大小设置为N+1.

6、线程池的种类有哪些

在java.util.concurrent.Executors类中提供了大量创建连接池的静态方法,常见就有4种。

1、创建使用固定线程数的线程池

public static ExecutorService newFixedThreadPool(int nThreads){
   return new ThreadPoolExecutor(nThreads,nThreds
                                 ,0L
                                 ,timeUnit.MILLSECONDS
                                 ,new LinkedBlockingQueue<Runnable>);
}

核心线程数与最大线程数一样,没有临时线程。

阻塞队列是LinkedBlockingQueue,最大容量为Integer.MAX_VALUE。

适用于任务量已知,相对耗时的任务。

2、单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO)执行。

public static ExecutorService newSingleThreadExecutor(){
    return new FinalizableDelegateExecutorService(
        new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLSECONDS,new LinkedBlockingQueue<Runnable>()
    );
}

适用于按照顺序执行的任务。

3、可缓存线程池

public static ExecutorService newCachedThredPool(){
    return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.Seconds,
                                 new SynchronousQueue<Runnable>);
}

核心线程数为0

最大线程数是Integer.MAX_VALUE

阻塞队列为SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作。

适合任务数比较密集,但每个任务执行时间较短的情况。

7、为什么不建议用Executors创建线程池

参考阿里开发手册《Java开发手册-嵩山版》

四、使用场景

1、线程池使用场景(CountDownLatch、Future)

项目使用到了多线程

CountDownLatch(闭锁/倒计时锁)用来进行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)。

  • 其中构造参数用来初始化等待计数值。
  • await() 用来等待计数归零
  • countDown() 用来让计数减一

西门子S7-1200PLC与FANUC机器人进行PROFINET IO通信的具体方法和步骤详解 阅读详情

相关推荐

ABAP动态填充Word模板:基于cl_docx_document的XML替换方案

本文详细介绍了ABAP中基于cl_docx_document类的动态Word模板填充方案。该方案通过直接操作DOCX文件的XML核心,完美解决了传统OLE/DOI方法在格式保真、性能和后台运行方面的痛点,是实现复杂、批量Word文档生成的优雅解决方案。

gpt4scribbler的博客 526

scGPT-spatial 复现

文章摘要:Spatial scGPT项目复现流程 本文详细介绍了复现Spatial scGPT项目的完整流程,包含数据预处理、模型训练等关键步骤。首先需要使用scanpy加载H5AD文件并进行归一化、对数变换等预处理。然后构建基因词汇表(vocab),提取基因表达值和空间坐标信息。接着使用DataCollator进行数据分箱、掩码和填充处理。最后搭建TransformerModel进行训练。文章特别指出了需要自行补全的缺失部分,包括基因词汇表构建、空间坐标提取、数据集类定义和训练主循环脚本等。作者还提供了详

victory0431的博客 1684

Pytorch.nn.Linear 解析(数学角度)

pytorch.nn.Linear 是一个类,下面是它的一些初始化参数 in_features : 输入样本的张量大小 out_features : 输出样本的张量大小 bias : 偏置 它主要是对输入数据做一个线性变换。 y=xAT+b y=xA^T+b y=xAT+b 这里A是权重矩阵,b是偏置。他们都是根据 in_features 生成 测试代码: m = torch.nn.Linea...

Medlen 1万+

Echats-wordcloud 文字云图的踩坑点【Unknown series wordCloud】

一直都是报 【ECharts Unknown series wordCloud】这玩意可能要刷脸,祝你好运吧~

Sky_Bug的博客 2418

UNITY2022 Cardboard环境搭建

必须安装 Git,并且 git 可执行文件必须位于 PATH 环境变量中。考文档:https://developers.google.cn/cardboard/develop/unity/quickstart?转到 Assets/Samples/Google Cardboard//Hello Cardboard/Scenes/HelloCardboard 场景中。粘贴https://github.com/googlevr/cardboard-xr-plugin.git到文本输入字段中。

weixin_39510925的博客 1212

基于Python实现基于遥感指数的水体提取

基于Python实现基于遥感指数的水体提取

gis收藏家的博客 6149

citespace基本操作

聚类分析 时间线图 这些结果都是高被引文献的相关呈现结果,代表该领域的文献基础 下面可以看看该project的前沿领域 选择keywords 和term go! 调整显示方式 生成凸线图:表示 在某个研究领域或者时间段内 ,大家对某个领域或者某个词的关注度突然增高,凸显前沿方向的转变 以此来发现热点 ...

生信小博士的博客 1万+

OpenCv —— 检测车牌号(附完整源码)

OpenCv —— 检测车牌号

5601

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深度学习工具包 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")

上一篇: MySQL面试内容2
下一篇: Redis各版本下载
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工作这么多年,学会了内卷

共同加油,继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值