项目分享 | MindSpore Insight AI可视化工具开发心得

news2025/1/21 4:54:00

01 概述

MindSpore Insight是昇思MindSpore的可视化调试调优工具。作为开发者,我参与了MindSpore Insight工具部分功能的开发。本文将对MindSpore Insight进行简要介绍、其次介绍在开发中所用开发框架Vue的响应式原理。

02 MindSpore Insight介绍

MindSpore Insight为昇思MindSpore提供了简单易用的调优调试能力。在训练过程中,可以将标量、张量、图像、计算图、模型超参、训练耗时等数据记录到文件中,通过MindSpore Insight可视化页面进行查看及分析。MindSpore Insight的宏观上的架构如下图所示。其中Summary log是使用昇思MindSpore训练的模型日志,通过python进行对日志进行解码,将数据处理为json格式的API,前端通过请求该API进行相应功能的展示。详细的介绍可查看官网(https://www.mindspore.cn/mindinsight/docs/zh-CN/master/index.html)或点击下方“阅读原文”

03 浅谈Vue2响应式原理

Vue是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。它的核心功能有声明式渲染和响应式,Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。如下图所示,当data属性中的数据发生变化时,其视图就会更新,不需要用户操作DOM就可让视图更新。那么Vue是如何知道更新的是这些数据呢?这就涉及到Vue响应式的实现原理。

Vue的响应式是指以数据驱动视图的,也就是数据发生变化,会重新渲染页面。该过程实现要考虑的有以下三点:

● 数据劫持:追踪数据的变化

● 依赖收集:收集视图依赖的数据

● 通知视图:数据变化时,通知视图部分更新

3.1 数据劫持和依赖收集

数据劫持:指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。在下面的代码很好地诠释了数据劫持。当给obj中的name属性赋值的时候,会触发defineProperty方法中的set函数,而访问obj中的name属性值的时候会触发get函数,在这里set函数和get函数就拦截了访问和修改对象属性的这个行为,在get中和set中可以写上额外的操作,这就是数据劫持。

/*
  Object.defineProperty(obj,prop,descriptor)
    obj 要定义属性的对象
    prop 要定义或修改的属性的名称
    descriptor 要定义或修改的属性描述符
  输出结果:
      数据劫持 set name : 张三
      数据劫持 get name : 张三
      张三
*/
const obj={}
Object.defineProperty(obj,"name",{
        get(){
            console.log("数据劫持 get name :",nameVal);
            return nameVal;
        },
        set(newVal){
            console.log("数据劫持 set name :",newVal)
            nameVal = newVal
        }
});
obj.name="张三";
console.log(obj.name)

依赖收集:视图中用到了哪个数据,视图就依赖哪个数据,把变化的数据收集起来,这个过程就是依赖收集。

3.2实现原理介绍

上图(参考:https://blog.csdn.net/Mikon_0703/article/details/111367773)是Vue实现响应式原理的流程图,主要有三个重要部分:

监听器(Observer):对数据对象进行遍历,利用Object.defineProperty()给属性都加上 setter和getter。这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化。

事件中心(Dep ):用来收集依赖和通知订阅者。如果属性发生变化,需要通知订阅者Watcher,看是否需要更新。因为订阅者有多个,所以需要一个消息订阅器(发布者)Dep(订阅者集合的管理数组)来专门收集这些订阅者,在Observer和Watcher之间进行统一管理。每个Observer实例都有一个Dep实例。

订阅者(Watcher): 将View的相关指令初始化为一个订阅者Watcher,并替换模板数据或绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。

3.3 Vue源码中的体现

Vue2中响应式实现的源码链接:https://github.com/vuejs/vue/blob/v2.6.14/src/core/observer

监听器(Observer)的实现

//https://github.com/vuejs/vue/blob/v2.6.14/src/core/observer/index.js
walk (obj: Object) {
    const keys = Object.keys(obj) // 遍历数据对象利用 
    Object.defineProperty()给属性都加上 setter和getter。
    for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i])
    }
  }
 export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: ?Function,
  shallow?: boolean
) {
  const dep = new Dep()

  const property = Object.getOwnPropertyDescriptor(obj, key)
  if (property && property.configurable === false) {
    return
  }

  // cater for pre-defined getter/setters
  const getter = property && property.get
  const setter = property && property.set
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key]
  }

  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) {
        dep.depend() // 收集依赖
        if (childOb) {
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const value = getter ? getter.call(obj) : val
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value){
        return
      }
      /* eslint-enable no-self-compare */
      if (process.env.NODE_ENV !== 'production' && customSetter) {
        customSetter()
      }
      // #7981: for accessor properties without setter
      if (getter && !setter) return
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      childOb = !shallow && observe(newVal)
      dep.notify() // 当数据发生变化时,事件中心Dep通知订阅者
    }
  })
}

Dep的实现

//https://github.com/vuejs/vue/blob/v2.6.14/src/core/observer/dep.js
export default class Dep {
  static target: ?Watcher;
  id: number;
  subs: Array<Watcher>;

  constructor () {
    this.id = uid++
    this.subs = []
  }

  addSub (sub: Watcher) {
    this.subs.push(sub)
  }

  removeSub (sub: Watcher) {
    remove(this.subs, sub)
  }

  depend () {
    if (Dep.target) {
    Dep.target.addDep(this)
    }
  }

  notify () {
    // stabilize the subscriber list first
    const subs = this.subs.slice()
    if (process.env.NODE_ENV !== 'production' && !config.async) {
      // subs aren't sorted in scheduler if not running async
      // we need to sort them now to make sure they fire in correct
      // order
      subs.sort((a, b) => a.id - b.id)
    }
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update() //当数据发生变化时,通知订阅者更新视图
    }
  }
}

Watcher的实现

//https://github.com/vuejs/vue/blob/v2.6.14/src/core/observer/watcher.js
/**
   * Subscriber interface.
   * Will be called when a dependency changes.
   */
  update () { // 订阅者更新视图方法
    /* istanbul ignore else */
    if (this.lazy) {
      this.dirty = true
    } else if (this.sync) {
      this.run()
    } else {
      queueWatcher(this)
    }
  }

04 总结

首先感谢昇思MindSpore社区提供的这次开源机会,这是我第一次参加开源项目,从这次开源经历中让我掌握了项目的开发流程,以及开源社区中的成员如何协同开发维护一个项目,另外此次开源经历,让我了解了小白如何参与开源、如何正确的提交PR。最后,我引用Apache APISIX PMC成员王院生的一句话:”参与开源,让我觉得自己终于与这个世界融为一体,不再是孤立的个体“ ,我也会继续参与开源,持续为开源贡献自己的一份力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/105834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习笔记之波尔兹曼机(二)梯度求解(正相、负相均采用MCMC)

机器学习笔记之波尔兹曼机——基于MCMC的梯度求解引言回顾&#xff1a;波尔兹曼机波尔兹曼机的结构表示模型参数的对数似然梯度基于MCMC梯度求解过程存在的问题关于单个变量的后验概率关于单个变量后验概率的推导过程单个变量后验概率与受限玻尔兹曼机引言 上一节介绍了波尔兹…

【Java基础知识复盘】基础语法篇

本人知识复盘系列的博客并非全部原创&#xff0c;大部分摘自网络&#xff0c;只是为了记录在自己的博客方便查阅&#xff0c;往后也会陆续在本篇博客更新本人查阅到的新的知识点&#xff0c;望悉知&#xff01; 基础语法 数据类型 定义 java语言是强类型语言&#xff0c;对于…

TiDB丨教你一招,实现MySQL与TiDB灵活切换

文章目录一、前言二、MySQL与TiDB切换方案1. 部署DM集群2. 添加数据源3. 创建同步任务三、 切换到 TiDB1、停止DM数据同步2、开启 Binlog 增量同步四、 故障切换回 MySQL五、总结一、前言 在日常工作中&#xff0c;原应用系统是跑在单机MySQL上&#xff0c;但随着业务量的慢慢…

读研转码,纠结技术方向

作者&#xff1a;阿秀校招八股文学习网站&#xff1a;https://interviewguide.cn这是阿秀的第「227」篇原创你好&#xff0c;我是阿秀。很多本科非科班的小伙伴都会选择通过读个研来达到转码的目的&#xff0c;主要是想给自己一个2-3年的缓冲时间。其中有的研究生专业是计算机的…

一文带你了解MindSpore的知识及安装入手

&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d; &#x1f947;博主昵称&#xff1a;Jovy. &#x1f35f;博客主页…

自动控制原理笔记-控制系统的数学模型

目录 建模方法 控制系统的数学模型——微分方程&#xff1a; 将方框图变为具体公式&#xff1a; 非线性系统微分方程的线性化&#xff1a; 线性定常微分方程的求解&#xff1a; 拉普拉斯变换的有关概念&#xff1a; 复数的有关概念&#xff1a; 拉氏变换的定义&#xf…

DolphinDB 分布式表数据更新原理和性能介绍

1. 概述 DolphinDB 从 1.30.6 版本开始支持更新分布式表数据。更新操作支持事务&#xff0c;具备事务 ACID 的特性&#xff0c;且通过 MVCC 实现快照隔离级别。DolphinDB 为多模数据库&#xff0c;目前支持两种存储引擎&#xff1a; OLAP 和 TSDB &#xff08;详见 DolphinDB …

xcode使用gdal库

GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。 GDAL提供对多种栅格数据的支持&#xff0c;包括Arc/Info ASCII Grid(asc)&#…

4 个分析 GameFi 项目的工具

Nov. 2022, Vincy 区块链游戏通常有几种 token、几十种类别的 NFT&#xff0c;以及复杂的奖励机制来吸引和留住玩家。同时添加机器人和清洗交易&#xff0c;使得准确评估特定项目的有机利益和潜力变得具有挑战性。 这就是为什么在投入时间和金钱之前分析 GameFi 项目的基础数…

Linux中的Rsync备份服务

目录 一、备份基本概述 1.备份的定义 2.备份的原因 3.备份分类 &#xff08;1&#xff09;完全备份 &#xff08;2&#xff09;增量备份 4.实现备份工具 二、Rsync——远程同步 1.Rsync基本介绍 2.Rsync同步模式 &#xff08;1&#xff09;推 &#xff08;2&#xf…

【Linux】项目自动化构建工具make / Makefile 及进度条小程序

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;make项目管…

关于对死锁的理解

文章目录什么是死锁&#xff1f;举例理解死锁如何解决死锁锁池与等待池的理解什么是锁池与等待池锁池与等待池的区别两个线程交替执行什么是死锁&#xff1f; 所谓死锁&#xff0c;是指互斥锁标记使用不当造成多个线程&#xff0c;相互持有对方想要申请的资源&#xff0c;不释…

HummerRisk V0.7.0:支持京东云、webhook、PDF下载等

HummerRisk V0.7.0发布&#xff1a;新增京东云支持&#xff0c;系统增加webhook支持&#xff0c;灵活扩展&#xff0c;新增多种页面的PDF下载&#xff0c;新增主机的批量导入和Windows类型主机的检测支持。 感谢社区中小伙伴们的反馈&#xff0c;你们的认可是我们前进的动力。…

四旋翼无人机学习第16节--labview开发allegro的PAD与封装查询工具

文章目录1 前言2 使用展示(有labview软件)2.1 使用界面展示2.2 配置文件展示2.3 封装检索2.4 pad检索2.5 软件退出3 使用展示(无labview软件)4 源文件下载方式1 前言 在学习allegro过程中&#xff0c;设计封装需要先设计组成封装的PAD&#xff0c;也就是使用Padstack Editor工…

Linux学习-93-SELinux安全上下文操作

18.6 SELinux安全上下文查看方法 SELinux 管理过程中&#xff0c;进程是否可以正确地访问文件资源&#xff0c;取决于它们的安全上下文。进程和文件都有自己的安全上下文&#xff0c;SELinux 会为进程和文件添加安全信息标签&#xff0c;比如 SELinux 用户、角色、类型、类别等…

Android设计模式详解之原型模式

前言 原型模式是一个创建型设计模式。 定义&#xff1a;用原型实例指定创建对象的种类&#xff0c;并通过复制这些原型创建新的对象。 使用场景&#xff1a; 类初始化需要消耗非常多的资源&#xff0c;这个资源包括数据、硬件资源&#xff0c;通过原型复制避免这些消耗&…

音质更出色的骨传导耳机,设计也很时尚,南卡Runner CC3上手

这两年我几乎每天都会用耳机&#xff0c;现在耳机的种类也不少&#xff0c;如果是户外健身的话&#xff0c;我觉得骨传导耳机比挂脖式的耳机更好用&#xff0c;这种耳机因为不入耳的使用方式&#xff0c;在我们听音乐的同时&#xff0c;还可以更清晰地感知周围的情况&#xff0…

【Django项目开发】自动生成接口文档(二)

文章目录一、安装第三方库drf-yasg2二、注册到子应用INSTALLED_APPS三、配置路由1、注意四、接口文档中展示详细的文档说明视图类中接口的标准注释五、视图类中自己定义的方法实现接口文档注释1、注意一、安装第三方库drf-yasg2 pip install drf-yasg2二、注册到子应用INSTALL…

新技术不断发展,一个全新的互联网行业的新风口已然来临

拥抱实体经济&#xff0c;绝对是当下互联网玩家们的首要选择。无论是头部的互联网企业来讲&#xff0c;还是新生的互联网玩家而言&#xff0c;它们都不约而同地将关注的焦点聚焦在了这样一个方向上。   透过这一点&#xff0c;我们可以非常明显地感受到&#xff0c;一个全新的…

网络技术展开型介绍(超详细)二

♥️作者&#xff1a;小刘在这里 ♥️每天分享云计算网络运维课堂笔记&#xff0c;疫情之下&#xff0c;你我素未谋面&#xff0c;但你一定要平平安安&#xff0c;一 起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;…