React16源码: React中的update和updateQueue的源码实现

05-React 状态更新 在 React 中触发更新的方式主要有以下几种:ReactDOM.render、setState、forUpdate 以及 hooks 中的 useState 等,关于 hooks 的后面会专门写一篇文章分析。 阅读详情

React中的update和updateQueue


1 )概述

  • 在 ReactDOM.render 过程中,还需要创建一个 update 对象
  • update 用于记录组件状态的改变的一个对象,它存放于Fiber对象的 updateQueue 中
  • updateQueue,它是一个单向链表的结构,一次整体的更新过程当中
  • 可能在这个queue里会存在多 Update
  • 在这次更新的过程当中,会根据这些 update 的结果算出最终的一个新的state的节果
  • 多个 update 可以同时存在,比如说我们有一个事件里面,连续调用了三次 setState
  • 这三次操作产生的是三个 update,并不会每次 setState,就更新一下整个应用
  • 而是会等3个setState执行完, 3个update创建完, 放到 updateQueue 里面,然后再进行更新的操作
  • 这个涉及到后续的调度的过程,以及 batchUpdates 的原理, 这个暂时不管

2 )源码

现在来看下 update 如何去创建以及它的一个数据结构

参考: https://github.com/facebook/react/blob/v16.6.0/packages/react-reconciler/src/ReactFiberReconciler.js

找到 scheduleRootUpdate 函数

function scheduleRootUpdate(
  current: Fiber,
  element: ReactNodeList,
  expirationTime: ExpirationTime,
  callback: ?Function,
) {
  if (__DEV__) {
    if (
      ReactCurrentFiber.phase === 'render' &&
      ReactCurrentFiber.current !== null &&
      !didWarnAboutNestedUpdates
    ) {
      didWarnAboutNestedUpdates = true;
      warningWithoutStack(
        false,
        'Render methods should be a pure function of props and state; ' +
          'triggering nested component updates from render is not allowed. ' +
          'If necessary, trigger nested updates in componentDidUpdate.\n\n' +
          'Check the render method of %s.',
        getComponentName(ReactCurrentFiber.current.type) || 'Unknown',
      );
    }
  }

  const update = createUpdate(expirationTime);
  // Caution: React DevTools currently depends on this property
  // being called "element".
  update.payload = {element};

  callback = callback === undefined ? null : callback;
  if (callback !== null) {
    warningWithoutStack(
      typeof callback === 'function',
      'render(...): Expected the last optional `callback` argument to be a ' +
        'function. Instead received: %s.',
      callback,
    );
    update.callback = callback;
  }
  enqueueUpdate(current, update);

  scheduleWork(current, expirationTime);
  return expirationTime;
}
  • 可见,update的创建过程, const update = createUpdate(expirationTime);, 进入到 createUpdate函数
    • import {createUpdate, enqueueUpdate} from './ReactUpdateQueue';
    • 找到 ReactUpdateQueue.js 文件,定位 createUpdate 函数
      export function createUpdate(expirationTime: ExpirationTime): Update<*> {
        return {
          // 对应这一次创建的更新的过期时间, 
          expirationTime: expirationTime,
      
          // tag 对应4种情况
          // export const UpdateState = 0; // 更新 state
          // export const ReplaceState = 1; // 替代 state
          // export const ForceUpdate = 2; // 强制更新
          // export const CaptureUpdate = 3; // 渲染过程中,如果有错误被捕获,会生成一个 update, 让我们重新渲染节点的方式, Error Boundary 在组件内部捕获渲染的错误的一个更新
          // 指定更新的类型,值为以上几种:0, 1, 2, 3
          tag: UpdateState,
          // 更新内容, 对应实际执行的操作内容,比如,在上述 createUpdate中的 update.payload = {element}; 这里是把整个传进去的App, ReactElement 及其整棵树 渲染到 DomRoot 里面
          // 初始渲染的 payload 就如上述
          // 如果是更新,比如 setState 接收的第一个参数,可能是一个对象或方法作为 payload
          payload: null,
          callback: null,
          
          // next 对应下一个 update, 因为,update 都是存放在 updateQueue 中的, 而 updateQueue 是一个单项列表的结构
          // 每个 update 都有一个 next, 在 UpdateQueue 中有一个 firstUpdate 和 lastUpdate 记录的是单项列表的开头和结尾
          // 从开头到结尾都是通过 next 串联起来的,把整个update 单链表的结构连接起来
          // 通过拿到 firstUpdate 基于next一层层找到 lastUpdate
          next: null,
          // 指向下一个 side effect
          nextEffect: null,
        };
      }
      
    • 同样定位到 UpdateQueue 里面
      export type UpdateQueue<State> = {
        // 每次更新应用渲染完成后,调用 UpdateQueue 计算出一个新的state 存放在 baseState 上
        // 下一次节点有更新,产生了一个更新的队列,在计算新的state时,会在 baseState 基础上计算
        baseState: State,
      
        // firstUpdate 和 lastUpdate 记录单项链表的数据结构
        // 队列中的第一个 Update
        firstUpdate: Update<State> | null,
        // 队列中的最后一个 Update
        lastUpdate: Update<State> | null,
      
        // 下面两个也是记录单项链表的数据结构,只不过对应有错误捕获的时候的 Update
        firstCapturedUpdate: Update<State> | null,
        lastCapturedUpdate: Update<State> | null,
      
        // 第一个 side effect
        firstEffect: Update<State> | null,
        // 最后一个 side effect
        lastEffect: Update<State> | null,
      
        // 第一个和最后一个 捕获产生的 side effect
        firstCapturedEffect: Update<State> | null,
        lastCapturedEffect: Update<State> | null,
      };
      
    • update 和 updateQueue 数据结构相对来说是比较简单的
    • 在 createUpdate 内部要调用一个 enqueueUpdate, 如果在 setState 和 forceUpdate 里面的操作
    • 去创建update时,需要调用 enqueueUpdate ,进入这个函数
      export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {
        // Update queues are created lazily.
        const alternate = fiber.alternate;
        let queue1;
        let queue2;
        if (alternate === null) {
          // There's only one fiber.
          queue1 = fiber.updateQueue;
          queue2 = null;
          if (queue1 === null) {
            queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
          }
        } else {
          // There are two owners.
          queue1 = fiber.updateQueue;
          queue2 = alternate.updateQueue;
          if (queue1 === null) {
            if (queue2 === null) {
              // Neither fiber has an update queue. Create new ones.
              queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
              queue2 = alternate.updateQueue = createUpdateQueue(
                alternate.memoizedState,
              );
            } else {
              // Only one fiber has an update queue. Clone to create a new one.
              queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
            }
          } else {
            if (queue2 === null) {
              // Only one fiber has an update queue. Clone to create a new one.
              queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
            } else {
              // Both owners have an update queue.
            }
          }
        }
        if (queue2 === null || queue1 === queue2) {
          // There's only a single queue.
          appendUpdateToQueue(queue1, update);
        } else {
          // There are two queues. We need to append the update to both queues,
          // while accounting for the persistent structure of the list — we don't
          // want the same update to be added multiple times.
          if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
            // One of the queues is not empty. We must add the update to both queues.
            appendUpdateToQueue(queue1, update);
            appendUpdateToQueue(queue2, update);
          } else {
            // Both queues are non-empty. The last update is the same in both lists,
            // because of structural sharing. So, only append to one of the lists.
            appendUpdateToQueue(queue1, update);
            // But we still need to update the `lastUpdate` pointer of queue2.
            queue2.lastUpdate = update;
          }
        }
      
        if (__DEV__) {
          if (
            fiber.tag === ClassComponent &&
            (currentlyProcessingQueue === queue1 ||
              (queue2 !== null && currentlyProcessingQueue === queue2)) &&
            !didWarnUpdateInsideUpdate
          ) {
            warningWithoutStack(
              false,
              'An update (setState, replaceState, or forceUpdate) was scheduled ' +
                'from inside an update function. Update functions should be pure, ' +
                'with zero side-effects. Consider using componentDidUpdate or a ' +
                'callback.',
            );
            didWarnUpdateInsideUpdate = true;
          }
        }
      }
      
      • const alternate = fiber.alternate; 先读取 alternate,这个就是 current 到 workInProgress 的映射关系
      • 在这里就要确保 current 和 workInProgress 对应的 updateQueue 是相同的
      • 在这里会统一被处理,在这里,参数 fiber 是 current, alternate 是 workInProgress
      • 先判断 alternate 是否存在, 不存在处理 queue1 和 queue2, 进入 createUpdateQueue
        export function createUpdateQueue<State>(baseState: State): UpdateQueue<State> {
          const queue: UpdateQueue<State> = {
            baseState,
            firstUpdate: null,
            lastUpdate: null,
            firstCapturedUpdate: null,
            lastCapturedUpdate: null,
            firstEffect: null,
            lastEffect: null,
            firstCapturedEffect: null,
            lastCapturedEffect: null,
          };
          return queue;
        }
        
      • 生成的 UpdateQueue 就是之前看过的这个数据结构
      • 接着往下的判断中进入 appendUpdateToQueue
        function appendUpdateToQueue<State>(
          queue: UpdateQueue<State>,
          update: Update<State>,
        ) {
          // Append the update to the end of the list.
          if (queue.lastUpdate === null) {
            // Queue is empty
            queue.firstUpdate = queue.lastUpdate = update;
          } else {
            queue.lastUpdate.next = update; // 当前最后(后面会变成倒数第二位元素)的next指向update
            queue.lastUpdate = update; // queue的lastUpdate 指向 update
          }
        }
        
        • 如果 lastUpdate 不存在,则说明 Queue 是空的,则进行处理
        • 如果存在,进行继续如上 enqueueUpdate中的 if else 的处理
      • 接着往下 都是这类逻辑,具体逻辑都在上面 enqueueUpdate 源码中
      • 总体来讲是初始化 Fiber 上面的 updateQueue, 以及进行更新
    • 它接收的两个参数,Fiber 和 Update 对象
      • Fiber 对象是在 创建 update时用到的Fiber
      • 对应 ReactDOM.render 就是我们的 RootFiber
      • 就是我们 FiberRoot 的 current
    • 在调用 scheduleRootUpdate 函数的 updateContainerAtExpirationTime 函数中
      export function updateContainerAtExpirationTime(
        element: ReactNodeList,
        container: OpaqueRoot,
        parentComponent: ?React$Component<any, any>,
        expirationTime: ExpirationTime,
        callback: ?Function,
      ) {
        // TODO: If this is a nested container, this won't be the root.
        const current = container.current;
      
        if (__DEV__) {
          if (ReactFiberInstrumentation.debugTool) {
            if (current.alternate === null) {
              ReactFiberInstrumentation.debugTool.onMountContainer(container);
            } else if (element === null) {
              ReactFiberInstrumentation.debugTool.onUnmountContainer(container);
            } else {
              ReactFiberInstrumentation.debugTool.onUpdateContainer(container);
            }
          }
        }
      
        const context = getContextForSubtree(parentComponent);
        if (container.context === null) {
          container.context = context;
        } else {
          container.pendingContext = context;
        }
      
        return scheduleRootUpdate(current, element, expirationTime, callback);
      }
      
      • const current = container.current; container.current 就对应一个 Fiber 对象
react源码阅读3 update与updateQueue react-dom后续updateContainer部分。阅读React包的源码版本为16.8.6。   在上一章节中我们看到了react-dom中render函数的逻辑是给传入的React组件创建了一个fiberRoot对象,用于标识它是整个应用的起点,上面拥有很多应用更新相关的表示符。然后创建对应的fiber给fiberRoot节点,fiber对象是每一个ReactElement都拥有的节点,... 阅读详情

相关推荐

C++版Cesium实战:从OpenGL到3DTiles的全流程开发指南

本文提供了一份C++版Cesium全流程开发指南,详细阐述了如何利用OpenGL和Qt从零构建高性能、可离线部署的三维GIS应用。内容涵盖开发环境搭建、OpenGL渲染引擎初始化、Cesium核心坐标系与场景管理移植,并重点解析了3DTiles数据的解析、异步加载与渲染优化等硬核实战技术,旨在帮助开发者实现与现有C++工业软件的深度集成。

weixin_28077113的博客 165

React 的源码与原理解读(十):updateQueue 与 processUpdateQueue

这个章节是补充的章节,因为我突然发现将了 lanes 的时候提到了我们的 updateQueue ,我以前之前讲过了,结果发现之前因为涉及了大量 lanes 的内容所以没讲,那么在将 hooks 之前,我们补充一篇 updateQueue 以及相关操作的讲解,这篇会让你在我学习**lanes ** 系统之后,对于我们怎么样依赖 lanes 系统进行我们的更新有更深刻的了解

weixin_46463785的博客 2014

hcaptcha逆向实战:从API解析到参数构造的完整链路

本文详细拆解了hcaptcha验证码的逆向实战流程,从环境准备、捕获API与版本号,到解析核心加密逻辑hsw.js,再到构造getcaptcha请求参数,最后完成验证提交。文章重点剖析了motionData、n、c等关键参数的获取与构造方法,为开发者模拟浏览器行为、实现自动化验证提供了清晰的完整链路指南。

ik678901的博客 632

React18原理: React核心对象之Update、UpdateQueue、Hook、Task对象

updateQueue是fiber对象的一个属性,它们之间数据结构和引用关系如下。注意task中没有next属性,它不是一个链表,其顺序是通过堆排序来实现的。小顶堆数组,始终保证数组中的第一个task对象优先级最高。2 )Update对象相关的数据结构。Hook与fiber的关系。

Wang的专栏 1817

SAP和Oracle EBS作为全球顶级的ERP系统,在中国市场深耕数十年,尤其是在大型国企、央企和跨国企业中,已经形成了强大的用户习惯和“舒适区”依赖

国产ERP替代国际系统的关键挑战在于打破用户对SAP/Oracle的操作习惯和心理依赖。需采取多维策略:战略上明确价值主张、分阶段实施;产品上优化用户体验、确保数据迁移;实施上加强情景化培训、流程再造。成功替代70%取决于变革管理,需将"被动替换"转为"主动升级",让用户在新系统中建立更优的舒适区。

金牌架构师 384

Vue3 - Element Plus上传组件el-upload上传多个文件时,让on-change监听事件仅执行一次并获取最终文件列表方法(开启多选文件并手动上传,拿到文件列表统一循环调用接口上传)

vue3,elementplus,Upload上传,el-upload,文件上传组件,上传组件on-change里执行多次,取消自动上传后change重复执行问题,upload上传多个文件后导致on-change执行多次拿不到最终文件列表,Element-plus的upload组件on-change不断执行怎么办,上传多个文件多次执行调用,上传多个文件时如何只执行一次on-change方法拿到最终的文件列表,vue3elementplus上传组件开启多个上传后导致change方法执行好几次,仅调用一

🏆 前端领域优质创作者 1万+

react源码分析(12)-updateQueue介绍

目录 2021SC@SDUSC updateQueue总览--对前文中所提到的update做详细介绍 分析 processUpdateQueue函数 总结 2021SC@SDUSC updateQueue总览--对前文中所提到的update做详细介绍 首先说明一下在updateQueue中所提到的update类型所包含的具体结构。 export type Update<State> = {| // TODO: Temporary field. Will remove

weixin_45668912的博客 1133

uniapp(全端兼容)-最新详细实现接入腾讯云IM即时通讯教程,uniapp在安卓苹果app端/小程序/h5移动端等集成使用腾讯云im插件,提供消息列表与聊天对话示例,支持发图片/私聊/实时监听消息

uni-app,腾讯云IM,安卓app,苹果app,微信小程序,移动端,H5网页,手机网站,微信小程序、支付宝小程序,手机app端,nvue,im即时通讯,腾讯云IM详细教程,如何接入腾讯IM即时通讯,使用腾讯im有没有插件,怎么使用腾讯云IM插件,tim-wx-sdk,聊天sdk,即时通讯im uniapp私聊/群聊/聊天室,实现IM即时通讯仿微信聊天功能,对接腾讯云IM+音视频,调用腾讯即时通信IM的示例,卡顿很卡不流畅,音视频,全局监听,仿微信IM,uni-huanxin-im,sdk,实现多端实时通

✅ 精选推荐文章 1万+

React 学习小结(六)

所有的 Tips 均为本人 OneNote 中的笔记,复制过来就是图片,懒得转文本了 第八章:react 扩展 一、扩展一:setState React 系列小结: React 学习小结(一) React 学习小结(二) React 学习小结(三) React 学习小结(四) ...

APythonC的博客 595

华为OD机考双机位C卷 - 员工派遣 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 员工派遣 (OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 1035

《网络安全自学教程》- Windows安全机制:安全标识符,身份鉴别和访问控制

这篇文章详细介绍Windows和Linux如何标识用户,如何根据标识验证用户身份,如何根据用户身份做访问控制。

wangyuxiang946的博客 1万+

React16源码: React中的updateHostRoot的源码实现

`HostRoot` 是一个比较特殊的节点, 因为在一个react应用当中,它只会有一个 `HostRoot`, 它对应的 Fiber 对象是我们的 `RootFiber` 对象,重点在于它的更新过程

Wang的专栏 1392

(数字图像处理MATLAB+Python)第五章图像增强-第一节:图像增强概述和基于灰度级变换的图像增强

图像增强(Image Enhancement):指不考虑图像降质原因,利用各种数学方法和变换手段,增强图像中人们感兴趣部分或提高有用的图像特征的清晰度。从图像质量来看,图像增强提高了图像的可懂度,改善了图像的视觉效果例如在现实场景中,针对那些对比度较差、视觉效果不好的图像,我们就可以利用图像增强改善视觉质量图像增强可分为如下几种基于灰度级变换的图像增强基于直方图修正的图像增强基于照度反射模型的图像增强基于模糊技术的图像增强基于伪彩色处理的图像增强其他图像增强方法分段线性灰度级变换。

快乐江湖的博客 3334

【笔记-react】《imooc-React源码深度解析 高级前端工程师必备技能》

第01章 课程导学 01-01 课程导学 一、UI=fn(x) 核心api:setState 没有directive双向绑定 二、vue,angular更新大版本,需要调整兼容 三、react,引入fiber,从根本上解决了,js单线程运行,如果计算量太大,导致动画卡帧,交互卡顿问题 四、第1章:React API,及每个API的作用 createElement、createContext、JSX=>JS、ConcurrentMode、Ref、Component、Suspense、Hooks 五、第2

aSuncat 1167

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

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【react源码】(三)React 应用中的高频对象

本章主要浏览了 react 运行链路中出现的高频对象, 并对它们的数据结构做出了单独解释. 提前了解这些对象的数据结构, 更加有利于之后对 react 源码的深入分析. 在后续对整个运行核心的解读中会多次引用到这些对象, 并对其在运行时的具体作用深入解读....

weixin_44828588的博客 693

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

基于React 源码深入浅出setState:深度刨析updater的结构和原理

作者 : 墨成 React 版本 :16.4.1阅读本文之前,建议阅读:1.基于React 源码深入浅出setState:官方文档的启示录2.基于React 源码深入浅出setState:setState异步实现在上一篇详细了解了setState的一些机制和原理,同时对 updater也作了简单的解释,这篇文章我们将详细了解这个updater的数据结构和调用堆栈.代码如下:react\pa...

weixin_33892359的博客 233

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

react源码解析12.状态更新流程

react源码解析12.状态更新流程 视频课程(高效学习):进入课程 课程目录: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命周期 12.状态更新流程 13.hooks源码 14.手写hooks 15.scheduler&Lane 16.concurrent模式 17.co

bemystery的博客 248

React源码解析:从updateContainerImpl看Fiber更新与调度机制

React的渲染性能优化往往需要深入理解其内部更新机制。Fiber架构作为React 16以来的核心调度基础,将组件树分解为可中断的工作单元,而更新容器的方法则是连接业务代码与底层调度器的关键桥梁。在React中,无论是createRoot还是render入口,最终都会汇聚到updateContainerImpl这一内部方法。它负责创建更新对象、挂载到更新队列并触发调度,决定了优先级如何被分配以及何时进入render阶段。理解这一机制,有助于解释为什么某些状态变更会引发整个组件树的重渲染,以及如何利用并发特

weixin_30225755的博客 135

react源码解析14.手写hooks

react源码解析14.手写hooks 视频讲解(高效学习):进入学习 往期文章: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命周期 12.状态更新流程 13.hooks源码 14.手写hooks 15.scheduler&Lane 16.concurrent模式 17.c

潇晨1998的博客 165

10 分钟调优 micro 编辑器与 xfce4-terminal:老旧笔记本、树莓派轻量开发提速

micro 是一款跑在终端里的现代文本编辑器,xfce4-terminal 是 Xfce 桌面环境里的轻量终端模拟器。下面用一台 2012 年的老笔记本做例子,把 micro 编辑器性能优化 拆成「终端层、编辑器层、系统层」三步走,同时给出一份 xfce4-terminal 配置,让光标不卡、内存不爆,SSH 远程时复制粘贴也正常。 ## 一台 2012 年老笔记本的开机现场 想象你在用一台

gitblog_00179的博客 264

React源码解读之更新的创建

React的鲜活生命起源于,这个过程会为它的一生储备好很多必需品,我们顺着这个线索,一探婴儿般React应用诞生之初的悦然。更新创建的操作我们总结为以下两种场景。

weixin_59558923的博客 78
上一篇: React16源码: React中Fiber对象的源码实现
下一篇: React16源码: React中的expirationTime过期时间的计算源码实现
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值