深入探索Android布局优化(下)

深入探索Android布局优化(上) 前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~。 Android的绘制优化其实可以分为两个部分,即布局(UI)优化和卡顿优化,而布局优化的核心问题就是要解决因布局渲染性能不佳而导致应用卡顿的问题,所以它可以认为是卡顿优化的一个子集。对于Android开发来说,写布局可以说是一个比较简单的工作,但是如果想将写的每一个布局的渲染性能提... 阅读详情

下面,笔者将与大家一起进入进行布局优化的实操环节。

六、布局优化常规方案

布局优化的方法有很多,大部分主流的方案笔者已经在Android性能优化之绘制优化里讲解过了。下面,我将介绍一些其它的优化方案。

1、布局Inflate优化方案演进
1、代码动态创建View

使用Java代码动态添加控件的简单示例如下:

Button button=new Button(this);        
button.setBackgroundColor(Color.RED);
button.setText("Hello World");
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.activity_main, null);
viewGroup.addView(button); 
2、替换MessageQueue来实现异步创建View

在使用子线程创建视图控件的时候,我们可以把子线程Looper的MessageQueue替换成主线程的MessageQueue,在创建完需要的视图控件后记得将子线程Looper中的MessageQueue恢复为原来的。在Awesome-WanAndroid项目下的UiUtils的Ui优化工具类中,提供了相应的实现,代码如下所示:

 /**
 * 实现将子线程Looper中的MessageQueue替换为主线程中Looper的
 * MessageQueue,这样就能够在子线程中异步创建UI。
 *
 * 注意:需要在子线程中调用。
 *
 * @param reset 是否将子线程中的MessageQueue重置为原来的,false则表示需要进行替换
 * @return 替换是否成功
 */
public static boolean replaceLooperWithMainThreadQueue(boolean reset) {
    if (CommonUtils.isMainThread()) {
        return true;
    } else {
        // 1、获取子线程的ThreadLocal实例
        ThreadLocal<Looper> threadLocal = ReflectUtils.reflect(Looper.class).field("sThreadLocal").get();
        if (threadLocal == null) {
            return false;
        } else {
            Looper looper = null;
            if (!reset) {
                Looper.prepare();
                looper = Looper.myLooper();
                // 2、通过调用MainLooper的getQueue方法区获取主线程Looper中的MessageQueue实例
                Object queue = ReflectUtils.reflect(Looper.getMainLooper()).method("getQueue").get();
                if (!(queue instanceof MessageQueue)) {
                    return false;
                }
                // 3、将子线程中的MessageQueue字段的值设置为主线的MessageQueue实例
                ReflectUtils.reflect(looper).field("mQueue", queue);
            }

            // 4、reset为false,表示需要将子线程Looper中的MessageQueue重置为原来的。
            ReflectUtils.reflect(threadLocal).method("set", looper);
            return true;
        }
    }
} 
3、AsynclayoutInflater异步创建View

在第三小节中,我们对Android的布局加载原理进行了深入地分析,从中我们得出了布局加载过程中的两个耗时点:

  • 1、布局文件读取慢:IO过程。
  • 2、创建View慢:使用反射,比直接new的方式要慢3倍。布局嵌套层级越多,控件个数越多,反射的次数就会越频繁。

很明显,我们无法从根本上去解决这两个问题,但是Google提供了一个从侧面解决的方案:使用AsyncLayoutInflater去异步加载对应的布局,它的特点如下:

  • 1、工作线程加载布局。
  • 2、回调主线程。
  • 3、节省主线程时间。

接下来,我将详细地介绍AsynclayoutInflater的使用。

首先,在项目的build.gradle中进行配置:

implementation 'com.android.support:asynclayoutinflater:28.0.0' 

然后,在Activity中的onCreate方法中将setContentView注释:

super.onCreate(savedInstanceState);
// 内部分别使用了IO和反射的方式去加载布局解析器和创建对应的View
// setContentView(R.layout.activity_main); 

接着,在super.onCreate方法前继续布局的异步加载:

// 使用AsyncLayoutInflater进行布局的加载
new AsyncLayoutInflater(MainActivity.this).inflate(R.layout.activity_main, null, new AsyncLayoutInflater.OnInflateFinishedListener() {
        @Override
        public void onInflateFinished(@NonNull View view, int i, @Nullable ViewGroup viewGroup) {
            setContentView(view);
            // findViewById、视图操作等
    }
});
super.onCreate(savedInstanceState); 

接下来,我们来分析下AsyncLayoutInflater的实现原理与工作流程。

由于我们是使用new的方式创建的AsyncLayoutInflater,所以我们先来看看它的构造函数:

 public AsyncLayoutInflater(@NonNull Context context) {
    // 1
    this.mInflater = new AsyncLayoutInflater.BasicInflater(context);
    // 2
    this.mHandler = new Handler(this.mHandlerCallback);
    // 3
    this.mInflateThread = AsyncLayoutInflater.InflateThread.getInstance();
} 

在注释1处,创建了一个BasicInflater,它内部的onCreateView并没有使用Factory做AppCompat控件兼容的处理:

protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
    String[] var3 = sClassPrefixList;
    int var4 = var3.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        String prefix = var3[var5];

        try {
            View view = this.createView(name, prefix, attrs);
            if (view != null) {
                return view;
            }
        } catch (ClassNotFoundException var8) {
        }
    }

    return super.onCreateView(name, attrs);
} 

由前面的分析可知,在createView方法中仅仅是做了反射创建出对应View的处理。

接着,在注释2处,创建了一个全局的Handler对象,主要是用于将异步线程创建好的View实例及其相关信息回调到主线程。

最后,在注释3处,获取了一个用于异步加载View的线程实例。

接着,我们继续跟踪AsyncLayoutInflater实例的inflate方法:

@UiThread
public void inflate(@LayoutRes int resid, @Nullable ViewGroup parent, @NonNull AsyncLayoutInflater.OnInflateFinishedListener callback) {
    if (callback == null) {
        throw new NullPointerException("callback argument may not be null!");
    } else {
        // 1
        AsyncLayoutInflater.InflateRequest request = this.mInflateThread.obtainRequest();
        request.inflater = this;
        request.resid = resid;
        request.parent = parent;
        request.callback = callback;
        this.mInflateThread.enqueue(request);
    }
} 

在注释1处,这里使用InflateRequest对象将我们传进来的三个参数进行了包装,并最终将这个InflateRequest对象加入了mInflateThread线程中的一个ArrayBlockingQueue中:

public void enqueue(AsyncLayoutInflater.InflateRequest request) {
    try {
        this.mQueue.put(request);
      } catch (InterruptedException var3) {
        throw new RuntimeException("Failed to enqueue async inflate request", var3);
    }
} 

并且,在InflateThread这个静态内部类的静态代码块中调用了其自身实例的start方法以启动线程:

static {
    sInstance.start();
}

public void run() {
    while(true) {
        this.runInner();
    }
}

public void runInner() {
    AsyncLayoutInflater.InflateRequest request;
    try {
        // 1
        request = (AsyncLayoutInflater.InflateRequest)this.mQueue.take();
    } catch (InterruptedException var4) {
        Log.w("AsyncLayoutInflater", var4);
        return;
    }

    try {
        // 2
        request.view = request.inflater.mInflater.inflate(request.resid, request.parent, false);
    } catch (RuntimeException var3) {
        Log.w("AsyncLayoutInflater", "Failed to inflate resource in the background! Retrying on the UI thread", var3);
    }

    // 3
    Message.obtain(request.inflater.mHandler, 0, request).sendToTarget();
} 

在run方法中,使用了死循环的方式去不断地调用runInner方法,在runInner方法中,首先在注释1处从ArrayBlockingQueue队列中获取一个InflateRequest对象,然后在注释2处将异步加载好的view对象赋值给了InflateRequest对象,最后,在注释3处,将请求作为消息发送给了Handler的handleMessage:

private Callback mHandlerCallback = new Callback() {
    public boolean handleMessage(Message msg) {
        AsyncLayoutInflater.InflateRequest request = (AsyncLayoutInflater.InflateRequest)msg.obj;
        // 1
        if (request.view == null) {
            request.view = AsyncLayoutInflater.this.mInflater.inflate(request.resid, request.parent, false);
        }

        request.callback.onInflateFinished(request.view, request.resid, request.parent);
        AsyncLayoutInflater.this.mInflateThread.releaseRequest(request);
        return true;
    }
}; 

在handleMessage方法中,当异步加载得到的view为null时,此时在注释1处还做了一个fallback处理,直接在主线程进行view的加载,以此兼容某些异常情况,最后,就调用了回调接口的onInflateFinished方法将view的相关信息返回给Activity对象。

小结

由以上分析可知,AsyncLayoutInflater是通过侧面缓解的方式去缓解布局加载过程中的卡顿,但是它依然存在一些问题:

  • 1、不能设置LayoutInflater.Factory,需要通过自定义AsyncLayoutInflater的方式解决,由于它是一个final,所以需要将代码直接拷处进行修改。
  • 2、因为是异步加载,所以需要注意在布局加载过程中不能有依赖于主线程的操作。

由于AsyncLayoutInflater仅仅只能通过侧面缓解的方式去缓解布局加载的卡顿,因此,我们下面将介绍一种从根本上解决问题的方案。对于AsynclayoutInflater的改进措施,可以查看祁同伟同学封装之后的代码,具体的改进分析可以查看Android AsyncLayoutInflater 限制及改进,这里附上改进之后的代码:

/**
* 实现异步加载布局的功能,修改点:
* 1. 单一线程;
* 2. super.onCreate之前调用没有了默认的Factory;
 * 3. 排队过多的优化;
*/
public class AsyncLayoutInflaterPlus {

    private static final String TAG = "AsyncLayoutInflaterPlus";
    private Handler mHandler;
    private LayoutInflater mInflater;
    private InflateRunnable mInflateRunnable;
    // 真正执行加载任务的线程池
    private static ExecutorService sExecutor = Executors.newFixedThreadPool(Math.max(2,
        Runtime.getRuntime().availableProcessors() - 2));
    // InflateRequest pool
    private static Pools.SynchronizedPool<AsyncLayoutInflaterPlus.InflateRequest> sRequestPool = new Pools.SynchronizedPool<>(10);
    private Future<?> future;

    public AsyncLayoutInflaterPlus(@NonNull Context context) {
        mInflater = new AsyncLayoutInflaterPlus.BasicInflater(context);
        mHandler = new Handler(mHandlerCallback);
    }

    @UiThread
    public void inflate(@LayoutRes int resid, @Nullable ViewGroup parent, @NonNull CountDownLatch countDownLatch,
                    @NonNull AsyncLayoutInflaterPlus.OnInflateFinishedListener callback) {
        if (callback == null) {
            throw new NullPointerException("callback argument may not be null!");
        }
        AsyncLayoutInflaterPlus.InflateRequest request = obtainRequest();
        request.inflater = this;
        request.resid = resid;
        request.parent = parent;
        request.callback = callback;
        request.countDownLatch = countDownLatch;
        mInflateRunnable = new InflateRunnable(request);
        future = sExecutor.submit(mInflateRunnable);
    }

    public void cancel() {
        future.cancel(true);
    }

    /**
    * 判断这个任务是否已经开始执行
    *
    * @return
    */
    public boolean isRunning() {
        return mInflateRunnable.isRunning();
    }

    private Handler.Callback mHandlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            AsyncLayoutInflaterPlus.InflateRequest request = (AsyncLayoutInflaterPlus.InflateRequest) msg.obj;
            if (request.view == null) {
                request.view = mInflater.inflate(
                    request.resid, request.parent, false);
            }
            request.callback.onInflateFinished(
                request.view, request.resid, request.parent);
            request.countDownLatch.countDown();
            releaseRequest(request);
            return true;
        }
    };

    public interface OnInflateFinishedListener {
        void onInflateFinished(View view, int resid, ViewGroup parent);
    }

    private class InflateRunnable implements Runnable {
        private InflateRequest request;
        private boolean isRunning;

        public InflateRunnable(InflateRequest request) {
            this.request = request;
        }

        @Override
        public void run() {
            isRunning = true;
            try {
                request.view = request.inflater.mInflater.inflate(
                    request.resid, request.parent, false);
            } catch (RuntimeException ex) {
                // Probably a Looper failure, retry on the UI thread
                Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI"
                    + " thread", ex);
            }
            Message.obtain(request.inflater.mHandler, 0, request)
                .sendToTarget();
        }

        public boolean isRunning() {
            return isRunning;
        }
    }

    private static class InflateRequest {
        AsyncLayoutInflaterPlus inflater;
        ViewGroup parent;
        int resid;
        View view;
        AsyncL
Android Jetpack Compose 动画性能优化 Jetpack Compose 允许开发者自定义动画曲线,以满足特定的动画效果需求。自定义动画曲线需要开发者具备一定的数学基础,但可以带来更加个性化的动画效果。在自定义动画曲线时,开发者需要关注曲线的平滑性和可读性。过于复杂的曲线可能会使动画效果变得难以预测,甚至出现卡顿现象。因此,在自定义动画曲线时,开发者需要权衡曲线的复杂度和动画效果。本文从动画时长、动画曲线、动画布局和动画资源等多个方面详细阐述了Android Jetpack Compose 动画性能优化。 阅读详情

相关推荐

安卓玩《文兰故事》生存建造指南:从庇护所到部落经营

3D开放世界与生存建造是当前手游的两大热门标签,它们共同构成一种动态循环:玩家在广阔地图中探索、采集,同时要应对饥寒、体力与时间压力,再将资源转化为可持续经营的部落基地。对安卓玩家而言,这类游戏还叠加了设备性能的考验——画质档位、帧率与散热管理是否得当,直接影响卡顿、闪退和黑屏是否频繁出现。理解“探索-生存-建造-经营”的流水线逻辑,掌握从开局选址、建筑布局到部落分工的工程化方法,并学会调整安卓端图形参数、排查安装故障,便能显著降低试错成本。以此为起点,新手也能在两小时内建立起一套稳定的开荒节奏,逐步体验从

weixin_28741413的博客 307

Android布局优化实战技巧

本文详细阐述了Android布局优化的实战技巧,从布局层次、布局性能、代码优化和工具与库的使用等多个方面提供了丰富的建议和方案。通过这些技巧的应用,开发者可以打造出更高效、更流畅的Android应用,提升用户体验。在实际开发中,开发者应充分重视布局优化,不断探索和尝试新的优化方法,以实现应用性能的全面提升。未来的研究方向可以包括布局算法的优化、新技术的应用以及更高效的布局工具和库的开发。

2501_92487565的博客 355

Android布局基础与UI设计入门:打造精美应用界面

恭喜你!现在你已经掌握了Android UI开发的基础知识,包括各种布局类型、常用控件的使用以及一些UI优化技巧。这些知识将帮助你设计出既美观又实用的Android应用界面。

m0_65382359的博客 2058

中文移动GUI智能体评测基准GUI-CEval:构建、评测与优化实践

图形用户界面(GUI)自动化是软件工程和人工智能交叉领域的关键技术,其核心在于让智能体理解并操作界面元素以完成任务。其工作原理通常结合计算机视觉(CV)与自然语言处理(NLP)技术,通过解析屏幕像素或UI元素树来感知状态,再通过决策模型输出点击、输入等动作序列。这项技术的价值在于能够极大提升自动化测试、机器人流程自动化(RPA)和无障碍辅助等场景的效率与可靠性。在实际应用中,智能体需要应对不同应用(App)的复杂布局和动态交互。然而,现有技术生态长期缺乏针对中文界面环境的标准化评测体系,导致模型在中文App

weixin_29056865的博客 279

抖音 Android 包体积优化探索:资源二进制格式的极致精简

动手点关注干货不迷路????前言目前,安卓端对于包体积的优化方案已经多如过江之鲫,我们系列的上一篇文章介绍了 Class 字节码的优化,本期我们将关注点聚焦到资源文件上,从资源二进制文件的全新角度,拓展出包体积优化的新思路。在资源文件优化方面,通常的优化手段多集中在图片/文件压缩、资源文件名称混淆、离线下载资源文件等方面,而我们的新思路基于对于常规思路的深度分析及思考。一开...

字节跳动技术团队官方博客 2444

从ConstraintLayout到Jetpack Compose:全面掌握Android UI设计与布局技术

本文系统解析ConstraintLayout与Jetpack Compose的核心技术,涵盖ConstraintLayout的高效约束布局、动态优化及Material Design 3适配,对比Jetpack Compose的声明式UI开发优势。通过实战案例展示如何从传统XML布局迁移至现代开发范式,提升性能与开发效率,适配复杂交互需求,助力开发者全面掌握Android UI设计全流程。

全栈 1223

Android视图加载优化——Factory2设置方法_android viewfactory

第三种方法是重写Activity的,改写的方法,返回自定义的。自定义的可以重写方法,加入自己的处理逻辑。这个方法是我从ViewPump学到的。

2501_90404930的博客 938

安卓讲课笔记3.2 帧式布局

1. 了解帧式布局用途; 2. 熟悉帧式布局常用属性; 3. 掌握线性布局嵌套帧式布局

howard2005的专栏 922

45、Android 高级 UI 开发:分页滑动与导航抽屉

本文介绍了Android高级UI开发中的分页滑动与导航抽屉功能的实现方法。通过FragmentPagerAdapter和ViewPager实现分页滑动浏览Fragment内容,适用于图片画廊或复杂页面导航;使用NavigationView和DrawerLayout创建导航抽屉,实现灵活的侧边菜单布局,并结合Fragment实现多页面切换。文章还展望了后续如何为应用添加数据库功能,包括SQLite数据库的基本操作。此外,详细解析了关键代码逻辑,并提供了优化用户体验的建议,如动画效果和选中状态高亮。最终通过流程

android的专栏 129

安卓案例:线性布局嵌套

本教程通过实例详细解析了Android中线性布局(LinearLayout)的使用方法与核心属性,强调其在界面设计中的重要作用。首先简述了线性布局的特点,即支持子视图垂直或水平排列,并能够通过权重进行空间分割。接着以实际代码为例,逐步展示了如何在主布局文件中运用嵌套的线性布局实现多行多列的复杂布局效果,同时结合 gravity、weight 等属性调整组件位置与大小。最后布置课后作业,要求利用线性布局模拟网格布局样式,进一步巩固学习成果,旨在帮助开发者熟练掌握并灵活应用线性布局进行界面设计。

howard2005的专栏 1万+

18、安卓系统的多样应用与物联网探索

本文探讨了安卓系统在物联网、娱乐等多个领域的广泛应用与技术实现。从Arduino与安卓的硬件交互开发,到Android Auto和Android Wear的应用场景,再到智能家居和多媒体设备的创新案例,全面展示了安卓系统的多样性和潜力。同时,还深入解析了系统构建、硬件驱动、测试调试等技术要点,并对未来发展进行了展望,描绘了更加智能化和互联化的趋势。

tree8的博客 142

界面上下固定_基于ANSYS的胶粘结构界面开裂有限元计算

引言:目前工程上主要有螺栓,过盈,焊接和胶粘四种常用的连接方式,本文基于ANSYS Workbench环境,引入内聚力模型来实现对胶粘结构界面开裂失效的计算,文中的界面失效参数为随意给定,不是工程实际测试数据,仅起到演示作用!1.问题的描述如图所示给出了胶粘结构的三维模型,该胶粘结构由上下钢板组成,中间通过胶粘接到一起。(胶不需要建模,其影响主要通过内聚力模型实现)上下板的材料为结构钢,...

weixin_29473667的博客 1万+

OpenWrt kmod内核不兼容?手把手教你用脚本强制安装驱动模块(附国内镜像源)

本文详细解决了OpenWrt kmod内核不兼容问题,提供智能脚本强制安装驱动模块的方法,并附有国内镜像源加速配置。通过自动化脚本修改内核MD5校验值,确保kmod包正常安装,同时推荐多个国内镜像源以提升下载速度。

weixin_42549451的博客 543

龙虾 Skill 技能库|OpenClaw+Hermes 全集成 一键调用所有 AI 技能

龙虾 Skill 技能库、OpenClaw、Hermes Agent、AI 技能集成、本地 AI 自动化、办公工具、数字员工

weixin_42219287的博客 625

计算机考研408复试题汇总

TCP连接是全双工的,两端都可以先挥手 其中一端完成数据发送任务后,发送一个FIN包来终止,另一端针对这个FIN包回复确认包, 直到另一端也发送请求终止数据包FIN,另一端作出确认应答,并且还要发送一个ACK=1表示确认号有效,如果没有收到这个就可以进行重传.

ca1m4n的博客 1万+

Unity Sprite Editor切片功能详解:如何快速将一张大图拆分成多个小图(附常见问题解决)

本文详细解析了Unity Sprite Editor的切片功能,指导开发者如何高效地将一张大图拆分为多个独立小图。文章涵盖了自动与手动切片操作步骤、轴心点设置、子精灵命名管理等核心技巧,并针对切片错位、性能优化等常见问题提供了实用解决方案,帮助提升2D游戏资源处理效率。

i0j1k2l3m的博客 648

《YOLO多模态创新改进专栏目录 》全网独家创新,多模态融合改进教程,包含早期融合、中期融合、后期融合、损失函数改进、二次创新模块、独家创新等几百种创新点改进,答疑群提供完整项目,永久更新中

🔥《YOLO多模态创新改进专栏》重磅来袭!🚀 本专栏汇集最新顶会顶刊创新点,提供1000+篇YOLO多模态改进方案(涵盖v8-v26),包含: 多模态融合策略(早期/中期/后期) 损失函数优化 独家创新模块 详细改进步骤 ✨特色服务: ✔️ 配套完整可运行项目 ✔️ 专业答疑群支持(含非计算机专业指导) ✔️ 持续更新至2026年 ✔️ 适用目标检测/OBB/分割/分类等多任务 💡适合人群: 科研人员 | 研究生 | 需发SCI/CCF论文者 环境要求宽松,新手友好,助力快速产出科研成果! 📈早订优

Ai缝合怪、助力小伙伴高效发论文 750

华为OD机试真题 新系统 2026-04-19 Java&Go 实现【分辨率排序】

华为OD机试真题 新系统 2026-04-19 Python&JS 实现【分辨率排序】

MISAYAONE的博客 309

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

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

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

上一篇: Android显示框架:Android应用视图的载体View
下一篇: [- Flutter基础篇 -] 聊聊那些弹框
CV大师啊
博客等级 码龄5年 5984粉丝 15原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值