精华内容
下载资源
问答
  • 论述层次模型的概念 举例子: 满足下面的基本层次联系的集合为层次模型 1)有且只有一个节点没有双亲节点,这个结构称为根节点 (2)根以外的其他结点有且只有一个双亲节点。 层次模型的实例 (1)教员学生层次数据库模型...

    最近学校上数据库的课程 在网上整理了一些

    什么是概念模型 有什么作用:

    实际是现实世界到信息世界的第一中间层次
    对数据库设计的有力工具 数据库设计人员与用户交流的语言 、

    论述层次模型的概念 举例子:

    满足下面的基本层次联系的集合为层次模型
    1)有且只有一个节点没有双亲节点,这个结构称为根节点
    (2)根以外的其他结点有且只有一个双亲节点。

    层次模型的实例
    (1)教员学生层次数据库模型
    (2)行政机构层次数据库模型
    (3)行政区域层次数据库模型

    论述网状模型的概念 举例子:

    满足下面两个条件的基本层次联系集合为网状模型。
    (1)允许一个以上的结点无双亲;
    (2)一个结点可以有多于一个的双亲’
    实例:
    (1)学生选课网状数据库模型
    (2)教师选教室网状数据模型
    (2)学生选 教室网址数据模型

    论述数据库系统的三级模式结构 优点?:

            三种模式包括外模式、概念模式、内模式,
    

    有效地组织、管理数据,提高了数据库的逻辑独立性和物理独立性。
    用户级对应外模式,概念级对应概念模式,物理级对应内模式,使不同级别的用户对数据库形成 不同的视图。
    优点

    1. 保证数据的独立性。将模式与内模式分开,保证了数据的物理独立性。讲外模式和模式分开,保证了数据的逻辑独立性。
    2. 简化了用户接口。按照外模式编写应用程序或输入命令,而不需要了解数据库内部的存储结构,方便用户使用系统。
    3. 有利于数据共享。在不同的外模式下可由多个用户共享系统中的数据,减少了数据冗余。
    4. 有利于数据的安全保密。在外模式下根据要求进行操作,只能对限定的数据操作,保证了其他数据的安全。

    什么叫数据于程序的物理独立性?什么叫数据与程序的逻辑独立性?为什么数据库系统具有数据于程序的独立性

    数据与程序的的逻辑独立性:

    当模式改变时(例如增加新的关系,新的属性,改变属性的数据类型等),由数据库管理员对各个外模式/模式的映像做相应的改变,可以使外模式保持不变。应用程序是依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。
    数据于程序的物理独立性:

    当数据库的存储结构改变了,由数据库管理员对模式/内模式映像做响应的改变,可以使模式保持不变,从而应用程序也不必改变,保证了数据与程序的物理独立性,简称数据的物理独立性。

    数据库管理系统在三级模式之间提供的两层映像保证了数据库系统中的数据能够具有较高的逻辑独立性和物理独立性

    论述数据库管理员 系统分析员 数据库设计人员 应用程序员的职责

    系统分析员负责应用系统的需求分析和规范说明,要和用户及DBA相结合,确定系统的硬件软件配置,并参与数据库系统的概要分析。
     
      数据库设计人员负责数据库中数据的确定、数据库各级模式的设计。数据库设计人员必须参加用户需求调查和系统分析,然后进行数据库设计。在很多情况下,数据库设计人员由数据库管理员担任。
      应用研究员负责设计和编写应用系统的程序模块,并进行调试和安装。

    展开全文
  • 层次数据结构的数据表设计 存储树形结构数据是一个常见问题,同时也有多种解决方案。 这里介绍三种树形结构的表设计方案: 邻接表模型 基于路径和层级表设计 基于左右值编码表设计(MPT) 这里以一个在线...

    层次数据结构的数据表设计

    存储树形结构数据是一个常见的问题,同时也有多种解决方案。

    这里介绍三种树形结构的表设计方案:

    • 邻接表模型
    • 基于路径和层级的表设计
    • 基于左右值编码的表设计(MPT)

    这里以一个在线食品店作为例子,食品通过类别、颜色和品种组织食品。

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYAHZQNJ-1612956420839)(assets\image-20210129145428312.png)]

    一、邻接表模型

    最简单的方法就是使用邻接表模型或者叫做递归模型。通过显示地描述某一节点的父节点,从而能够建立二维的关系表,你只需要一个简单的函数去迭代查询即可获取你的数据。

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CUR3I5zx-1612956420841)(assets\image-20210129145448067.png)]
    优点:

    • 设计简单
    • 实现容易
    • 直观

    缺点:

    • 由于是递归模型CRUD操作低效

    二、基于路径和层级的表设计

    在一的基础上加上一个 level 字段来表示当前节点到根节点的距离和一个 key 字段来表示搜索路径。

    1. Node_id 主键
    2. Name 名字
    3. Parent_id 父节点的id
    4. key 搜索路径
    5. level 表示当前节点到根节点的距离或者层级

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJWbeWkX-1612956420845)(assets\image-20210129145544265.png)]
    两种需求查询解决方案如下:

    1. 查找d的所有子孙节点:select * from table_name where key like "${d.key}-${d.id}-%"
    2. 查找某个节点的所有子节点:select * from table_name where key like "${d.key}-${d.id}-%" and level=${d.level}+1

    此设计结构简单,利用key和level两个辅助字段可以完成查询操作比一更加高效,而且维护这两个字段成本很低。

    三、基于左右值编码的表设计(MPT)

    为了避免对于树形结构查询时的“递归”过程,基于Tree的前序遍历设计一种全新的无递归查询、无限分组的左右值编码方案,来保存该树的数据。
    在这里插入图片描述
    如下图所示, 从根节点Food左侧开始,标记为1,并沿前序遍历的方向,依次在遍历的路径上标注数字,最后我们回到了根节点Food,并在右边写上了18。

    注:lft 和 rgt 分别对应 DFS 的发现时间 d 和完成时间相同 f
    在这里插入图片描述
    如果我们需要查询Fruit的后续节点,只需找出所有左值大于2,并且右值小于11的节点即可。

    1. 获取某节点的子孙节点

    返回某节点子孙节点的前序遍历列表,以Fruit为例:

    SQL: SELECT* FROM Tree WHERE Lft BETWEEN 2 AND 11 ORDER BY Lft ASC

    查询结果如下:
    在这里插入图片描述
    那么某个节点到底有多少的子孙节点呢?

    通过该节点的左、右值我们可以将其子孙节点圈进来,则子孙总数 = (右值 – 左值– 1) / 2,以Fruit为例,其子孙总数为:(11 –2 – 1) / 2 = 4。

    同时,为了更为直观地展现树形结构,我们需要知道节点在树中所处的层次,通过左、右值的SQL查询即可实现。以Fruit为例:SELECT COUNT(*) FROM Tree WHERE Lft <= 2 AND Rgt >=11。为了方便描述,我们可以为Tree建立一个视图,添加一个层次数列,该列数值可以写一个自定义函数来计算,函数定义如下:

    CREATE FUNCTION dbo.CountLayer
    (
        @node_id int
    )
    RETURNS int
    AS
    begin
      declare @result int
      set @result = 0
      declare @lft int
      declare @rgt int
      if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where node_id = @node_id
        select @result = count(*) from Tree where Lft <= @lft and Rgt >= @rgt
      end
      return @result
    end
    GO
    

    基于层次计算函数,我们创建一个视图,添加了新的记录节点层次的数列:

    CREATE VIEW dbo.TreeView
    AS
    SELECT Node_id, Name, Lft, Rgt, dbo.CountLayer(Node_id) AS Layer FROM dbo.Tree ORDER BY Lft
    GO
    

    创建存储过程,用于计算给定节点的所有子孙节点及相应的层次:

    CREATE PROCEDURE [dbo].[GetChildrenNodeList]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
        select * from TreeView where Lft between @lft and @rgt order by Lft ASC
      end
    GO
    

    现在,我们使用上面的存储过程来计算节点Fruit所有子孙节点及对应层次,查询结果如下:
    在这里插入图片描述
    在进行树的查询遍历时,只需要进行2次数据库查询,消除了递归,再加上查询条件都是数字的比较,查询的效率是极高的,随着树规模的不断扩大,基于左右值编码的设计方案将比传统的递归方案查询效率提高更多。

    2. 获取某节点的族谱路径

    假定我们要获得某节点的族谱路径,则根据左、右值分析只需要一条SQL语句即可完成。

    以Fruit为例:SELECT* FROM Tree WHERE Lft < 2 AND Rgt > 11 ORDER BY Lft ASC

    相对完整的存储过程如下:

    CREATE PROCEDURE [dbo].[GetParentNodePath]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
        select * from TreeView where Lft < @lft and Rgt > @rgt order by Lft ASC
      end
    GO
    

    3. 为某节点添加子孙节点

    假定我们要在节点“Red”下添加一个新的子节点“Apple”,该树将变成如下图所示,其中红色节点为新增节点。
    在这里插入图片描述
    相对完整的插入子节点的存储过程:

    CREATE PROCEDURE [dbo].[AddSubNode]
    (
      @node_id int,
      @node_name varchar(50)
    )
    AS
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        SET XACT_ABORT ON
        BEGIN TRANSCTION
        select @rgt = Rgt from Tree where Node_id = @node_id
        update Tree set Rgt = Rgt + 2 where Rgt >= @rgt
        update Tree set Lft = Lft + 2 where Lft >= @rgt
        insert into Tree(Name, Lft, Rgt) values(@node_name, @rgt, @rgt + 1)
        COMMIT TRANSACTION
        SET XACT_ABORT OFF
      end
    GO
    

    4. 删除某节点

    如果我们想要删除某个节点,会同时删除该节点的所有子孙节点,而这些被删除的节点的个数为:(被删除节点的右值 – 被删除节点的左值+ 1) / 2,而剩下的节点左、右值在大于被删除节点左、右值的情况下会进行调整。来看看树会发生什么变化,以Beef为例,删除效果如下图所示。
    在这里插入图片描述
    则我们可以构造出相应的存储过程:

    CREATE PROCEDURE [dbo].[DelNode]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        SET XACT_ABORT ON
        BEGIN TRANSCTION
          select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
          delete from Tree where Lft >= @lft and Rgt <= @rgt
          update Tree set Lft = Lft – (@rgt - @lft + 1) where Lft > @lft
          update Tree set Rgt = Rgt – (@rgt - @lft + 1) where Rgt > @rgt
          COMMIT TRANSACTION
        SET XACT_ABORT OFF
      end
    GO
    

    小结

    优点:

    • 消除了递归查询,实现了无限嵌套
    • 查询是基于整数的比较,效率很高

    缺点:

    • 节点的添加、删除及修改代价较大

    在基于数据库的一般应用中,查询的需求总要大于删除和修改,同时我们可以扩展MPT来实现更多的优化,例如:如果对层级需求较高,可以结合MPT和二中的方法来实现。

    Reference

    层次数据结构的数据表设计:https://juejin.cn/post/6844903861413478407#heading-7

    树形结构的数据库表Schema设计:https://blog.csdn.net/monkey_d_meng/article/details/6647488

    展开全文
  • 未显示需要 javascript 的文档选项级别: 初级徐享忠 (xuxz02@21cn.com), 软件工程师... 现实世界中大量的数据都具有层次结构,常见的例子包括组织机构序列(如公司机构、部队编制、作战编成)、分类体系(如中图分...

    未显示需要 javascript 的文档选项


    级别: 初级

    徐享忠 (xuxz02@21cn.com), 软件工程师

    2005 年 4 月 01 日

    本文将xml与树状控件相结合,提出了一个层次数据管理的解决方案,在多个项目当中得到了复用,是关系模型的必要而有益的补充。

    引言

    现实世界中大量的数据都具有层次结构,常见的例子包括组织机构序列(如公司机构、部队编制、作战编成)、分类体系(如中图分类法、装备体系)、家族谱系等等。因此,层次结构数据的管理,在软件开发过程当中经常会遇到,是个具有共性的问题。

    数据管理是指如何对数据进行分类、组织、编码、存储、检索、控制和维护,是数据处理的中心问题。关系数据库管理系统通过索引、查询优化、事务处理、并发访问控制、触发器、错误恢复等强大的机制,有效地确保了海量数据存取的高效性,保证了数据的完整性和一致性,并提供了数据的可靠性和安全性,从而具有其它数据管理方式无法比拟的优势。因此,在企业计算的环境下,对于数据管理,尤其是对于大规模商业数据的管理,关系数据库占据着主导地位。当前,大量的大型信息系统都是建立在关系数据库平台之上的。然而,在管理层次结构的数据,以及日益普遍的半结构化、非结构化数据方面,关系模型也暴露出了一些固有的不足。


    回页首

    关系模型在管理层次结构数据上的不足

    关系数据库的理论基础是关系理论,它的数据模型是关系模型。在用户看来,一个关系模型的逻辑结构是一张规则的二维表,由行和列组成。随着新的计算机技术的不断涌现,以及数据的分布性、异构性和半结构化特性以及非结构化特性程度的不断加强,关系数据库系统在数据管理上也已经显示出了一些不足:

    现实世界被强制性地映射成为一系列表的集合(即一组二维关系),因此,复杂对象的许多语义,例如,聚合和特化,均被丢弃。 对于现实世界中数据具有的次序语义,必须通过关系表当中额外的附加字段进行描述,以能够索引同属元素的次序(在关系数据库的记录集中,记录的次序是没有意义的。当然,次序没有意义是关系理论所要求的。这样,通过建立索引,搜索记录就变得更为容易,在性能上得到了优化)。并且,要维护这种次序语义也是比较麻烦的。 类似地,对于现实世界中数据具有的层次结构(如父/子、祖先/后代等层次结构),也必须通过关系表当中额外的附加字段进行描述。实际上,也可以把层次结构当作是一种特殊的次序语义。 关系模型要求关系必须是规范化的。为了提高关系模型的规范化程度(目前的最高层次为第五范式),以降低数据冗余度和避免数据的更新(包括插入、修改和删除)异常,必须在设计时(design-time)人为进行关系的分割(即规范化设计);在运行时(run-time)再进行连接(join)。这就增加了系统设计的难度,而且会影响系统的运行性能,这是因为,连接是关系数据库当中最为耗时的操作。因此,需要在数据库的设计时性能和运行时性能之间取得平衡。 一旦数据库模式发生变化,可能需要重新编写接口程序。 每条记录包含固定数目的字段,每个字段占据定长的存储空间。这样在存储叙述性资料时,会浪费空间。此外, 数据库的结构应该具有相对的稳定性,不太容易被改变,数据库结构上的改变(即数据库的重构造,不同于数据库的重组织)可能导致极其高昂的代价,即可扩展性较差。这也在一定程度上说明了为什么数据库的分析和设计具有如此重要作用的原因。这同 xml 在结构上具有的柔性形成了鲜明的对比。

    为此,有必要探讨数据管理的新思路和新方法。xml 所具有的一些独特的优点和功能,使得它在层次结构数据的管理方面崭露头角,并已经引起了多方广泛的关注。


    回页首

    xml 数据模型的特点

    xml 是 w3c 制定的标准,被设计为混合语(lingua franca),以便在用户和程序之间交换信息。它具有一系列优良特性,如可扩展性,简单性,自描述性,结构、内容和表现分开等。因此,xml 在自由软件以及商业软件业界均获得了强有力的支持,从而能够为开发人员提供极大的灵活性。

    从数据建模方面来看,xml 提供了两种手段:dtd 和 xml schema。它们可以使开发人员将他们的思想具体化,为成组具有相同逻辑结构的文档(而不仅仅是单个文档)制定规范。正是通过这两种建模手段,xml 承诺帮助创建更加智能的文档,如提供某种程度的查错功能,易于从中提取出有用的信息,并将它们按照人们的需要展示出来。


    回页首

    xml 数据模型的优点

    xml数据模型本身就是树状模型,一篇格式良好(well-formed)且有效的(validated)xml 文档经过 dom 解析之后,就会在内存当中建立一棵树。因此,对于现实世界中数据具有的次序语义和层次结构,xml 数据模型能够很好且方便地由xml文档解析器予以保持,开发人员不必费什么力气。并且,这种次序语义和层次结构的动态维护也是比较简单的。

    此外,xml 解析器是组件,具有标准的接口,开发人员从而可以避免接口程序的重复开发和分发,以及降低相应的接口程序测试和维护开销。


    回页首

    xml 与树状控件的结合

    xml 是国际标准,树状控件是常用而重要的界面元素,两者在业界均获得了广泛支持;而且,如前所述,xml 数据模型本身就是树状模型,这种结构上的内在相似性,使得两者具有天然的良好的结合性。

    由于在软件开发过程当中经常会遇到层次结构数据的管理,为避免重复劳动和避免重新开发可能引入的错误,从而提高软件开发的效率和质量,削减开发费用和缩短开发周期,笔者利用组件技术,将xml与树状控件相结合,综合应用 ole、用户自绘制等技术,开发了一个组件,在组织机构编码系统、任务空间概念模型(cmms)管理系统等多个项目当中得到了复用,取得了预期效果。

    该组件具有如下特点和功能:

    便于构建树状结构,同时保持数据的次序语义和层次结构 数据源是 xml 文档。 可在 ie 当中快捷地判断数据的次序语义和层次结构是否符合要求。 如果组件加载 xml 文档成功,应用程序便用树状控件显示树状结构;否则,给出错误提示,便于用户修改。 支持持久化(persistence),将用户的修改回存到 xml 文档当中。 以图形化方式,直观地维护层次结构 增加节点,可在指定位置增加子节点或者兄弟节点 删除节点。 修改节点。 节点的快速查找和定位。 与 ole 紧密结合 修改项目时,支持在位编辑(in-place edit)。 修改项目时,支持对特定字符的过滤。 支持以拖-放(drag & drop)方式,在树之间或者树自身完成节点的复制操作或者移动操作。 节点的编码是树状结构与关系数据库结合的关键,为此,该组件提供了十分灵活的编码方式 节点的编码采用可打印字符形式。 编码的长度可任意扩展,允许树有足够的高度(树中各节点的最大层次数目)。 每位码的取值范围大约为100,允许树有足够的度(树中各节点拥有的最大子树数目)。 采用用户自绘制(custom draw)方式,使得树状控件具有强大的表现功能 可直观地调整节点的字体和字号。 可直观地为每个节点设置不同的颜色。 可打印输出树状结构。
    <?xml version='1.0' encoding='gb2312' standalone='yes'?> <a银行总部>s <b1省分行>sa <c1县支行>saa <d1镇分理处>saaa <e1村储蓄所>saaaa </e1村储蓄所> <e2村储蓄所>saaab </e2村储蓄所> <e3村储蓄所>saaac </e3村储蓄所> </d1镇分理处> <d2镇分理处>saab </d2镇分理处> </c1县支行> <c2县支行>sab </c2县支行> </b1省分行> <b2省分行>sb</b2省分行> <b3省分行>sc</b3省分行> <b4省分行>sd</b4省分行> <b5省分行>se</b5省分行> </a银行总部>

    作为对比,清单2给出了 a 银行组织机构序列的示例数据(关系模型数据格式),由此不难发现 xml 文档格式管理层次结构数据的优越性:


    清单2. a银行组织机构序列示例(关系模型数据格式)
    清单2.  a银行组织机构序列示例(关系模型数据格式)

    请注意,上表当中的"是否叶子节点"、"层次"、"上一级编码"、"上二级编码"、"上三级编码"、"上四级编码"等字段均是为了描述数据的层次结构而附加的;同时,上表当中还不得不引入大量的空值(null)。

    a 银行组织机构序列在该组件中的一种表现效果如下图所示:




    回页首

    xml 与关系数据库的结合

    由上述讨论可知,应用 xml 进行数据管理具有特殊的优势,可以有效地弥补关系数据库在层次结构数据的管理上的不足和存在的问题,有着十分广阔的前景。

    当然,这个解决方案并不是完美无缺的,存在以下几个问题。首先,xml 中所有的数据都以字符串进行存储。这样在文档当中搜索或者在必须进行数据类型转换的时候,可能带来额外的时间开销。当数据规模比较大、或者应用程序对时间的要求比较苛刻时,开发人员必须对这种额外的时间开销给以足够的重视。而解决这个问题的唯一途径就是,建立一个典型的应用程序,并对它进行强度测试(stress test)。其次,xml 文档在给人们带来易读性的同时,也具有潜在的安全性隐患。另外,xml 的许多相关标准和技术,还处于草案阶段,没有最终定型,不同技术厂商之间的利益纷争也可能带来比较严重的问题。

    因此,一个自然的想法就是将 xml 与关系数据库结合在一起,以发挥各自的长处,扬长避短。具体来说,就是用 xml 管理小规模的层次结构的数据,而用关系数据库管理大规模的商业数据,两者通过树的节点的编码进行连接。

    例如,在组织机构编码系统提供的组织机构序列的基础上,可进一步利用关系数据库技术完成组织机构的信息采集、查询、统计、维护等功能。


    回页首

    小结

    应用 xml 进行数据管理具有特殊的优势,可以有效地弥补关系数据库在层次结构数据的管理上的不足和存在的问题。但是,xml 技术和关系数据库技术之间并不是相互竞争、相互排挤的关系,而是相互补充和相互促进的关系。实际上,xml 和关系数据库具有很强的互补性,它们好像就是为在一起协作而设计的,将长期共存下去。一个综合的数据管理系统几乎都是需要同时使用 xml 和关系数据库。一个好消息是,几乎所有主要的关系数据库产品都提供了对 xml 的支持。



    参考资料

    王珊等编写的数据库教程"数据库系统原理教程"详细论述了关系数据库在数据管理上的特点和优点,并且着重分析了关系模型在管理层次结构的数据以及日益普遍的半结构化、非结构化数据方面暴露出来的不足。

    徐享忠等撰写的论文"xml 在数据管理上的应用"详细论述了 xml 在数据管理上的可能应用,包括数据的基本存储、数据的归档和备份、中间数据交换格式、数据挖掘和数据表现等多个方面。

    基于 xml 的数据交换在仿真系统中的应用,可参见徐享忠等撰写的论文"基于xml 的数据交换格式在先进分布仿真系统中的应用"。

    xml 的特点、语法规则、组成部分及业界应用实例,可参见simon st. laurent编写的"xml a primer (2nd edition)"。

    michael morrison著的"xml unleashed"详细介绍了在各种开发平台(尤其是c++)上,利用组件技术访问xml各个组成部分(如sax、dom、xslt)的方法。

    e.j.lu等撰写的论文"an empirical study of xml/edi"详细阐述了企业,特别是中小型企业在电子数据交换系统当中采用xml作为解决方案可能带来的机遇和巨大的好处,以及可能存在的一些隐患。


    关于作者

    转载于:https://www.cnblogs.com/kangderui/archive/2009/12/31/1636495.html

    展开全文
  • 提出一种在组织结构上具有固有动态性软件体系结构理论模型——动态树型软件体系结构模型(DTSAM)。在DTSAM定义软件体系结构组织结构下,软件系统演化抽象成为一棵动态树渐增和渐减。其中,所设计渐增和渐...
  • pytorch搭建模型的的五大层次级别(由浅入深)

    千次阅读 多人点赞 2019-05-17 17:48:23
    前言:神经网络搭建本身是一个较为复杂过程,但是现在有非常多、非常人性化开源框架提供给我们使用,但是即便如此,网络搭建也是有多种方法可以选择,本文以pytorch为例子加以说明。 神经网络基本流程...

    前言:神经网络的搭建本身是一个较为复杂的过程,但是现在有非常多的、非常人性化的开源框架提供给我们使用,但是即便如此,网络的搭建也是有多种方法可以选择,本文以pytorch为例子加以说明。

    神经网络的基本流程可以分为两大步骤,即

    网络结构搭建+参数的梯度更新(后者又包括  “前向传播+计算参数的梯度+梯度更新”)

    这其实也是后面pytorch搭建神经网络的一个基本思路

    1 、原始搭建——使用numpy实现

    # -*- coding: utf-8 -*-
    import numpy as np
    
    # N是训练的batch size; D_in 是input输入数据的维度;
    # H是隐藏层的节点数; D_out 输出的维度,即输出节点数.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    # 创建输入、输出数据
    x = np.random.randn(N, D_in)  #(64,1000)
    y = np.random.randn(N, D_out) #(64,10)可以看成是一个10分类问题
    
    # 权值初始化
    w1 = np.random.randn(D_in, H)  #(1000,100),即输入层到隐藏层的权重
    w2 = np.random.randn(H, D_out) #(100,10),即隐藏层到输出层的权重
    
    learning_rate = 1e-6   #学习率
    
    for t in range(500):
        # 第一步:数据的前向传播,计算预测值p_pred
        h = x.dot(w1)
        h_relu = np.maximum(h, 0)
        y_pred = h_relu.dot(w2)
    
        # 第二步:计算计算预测值p_pred与真实值的误差
        loss = np.square(y_pred - y).sum()
        print(t, loss)
    
        # 第三步:反向传播误差,更新两个权值矩阵
        grad_y_pred = 2.0 * (y_pred - y)     #注意:这里的导函数也是自己求的,因为这个地方是很简答的函数表达式
        grad_w2 = h_relu.T.dot(grad_y_pred)
        grad_h_relu = grad_y_pred.dot(w2.T)
        grad_h = grad_h_relu.copy()
        grad_h[h < 0] = 0
        grad_w1 = x.T.dot(grad_h)
    
        # 更新参数
        w1 -= learning_rate * grad_w1
        w2 -= learning_rate * grad_w2

    缺点:

    (1)没办法搭建复杂的网络结构(网络的结构搭建太底层);

    (2)梯度需要自己求导函数,如果函数太复杂,网络太深就很难求了;

    (3)没有办法使用GPU加速

    2、使用torch的Tensor原始实现

    import torch
    
    dtype = torch.float
    device = torch.device("cpu")
    # device = torch.device("cuda:0") # 这里使用CPU,但实际上可以使用GPU
    
    # N是训练的batch size; D_in 是input输入数据的维度;
    # H是隐藏层的节点数; D_out 输出的维度,即输出节点数.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    # 创建输入、输出数据
    x = torch.randn(N, D_in, device=device, dtype=dtype)  #(64,1000)
    y = torch.randn(N, D_out, device=device, dtype=dtype) #(64,10)可以看成是一个10分类问题
    
    # 权值初始化
    w1 = torch.randn(D_in, H, device=device, dtype=dtype) #(1000,100),即输入层到隐藏层的权重
    w2 = torch.randn(H, D_out, device=device, dtype=dtype)#(100,10),即隐藏层到输出层的权重
    
    learning_rate = 1e-6
    
    for t in range(500):
        
        # 第一步:数据的前向传播,计算预测值p_pred
        h = x.mm(w1)
        h_relu = h.clamp(min=0)
        y_pred = h_relu.mm(w2)
    
        # 第二步:计算计算预测值p_pred与真实值的误差
        loss = (y_pred - y).pow(2).sum().item()
        print(t, loss)
    
        # 第三步:反向传播误差,更新两个权值矩阵
        grad_y_pred = 2.0 * (y_pred - y)    #注意:这里的导函数也是自己求的,因为这个地方是很简答的函数表达式
        grad_w2 = h_relu.t().mm(grad_y_pred)
        grad_h_relu = grad_y_pred.mm(w2.t())
        grad_h = grad_h_relu.clone()
        grad_h[h < 0] = 0
        grad_w1 = x.t().mm(grad_h)
    
        # 参数更新(梯度下降法)
        w1 -= learning_rate * grad_w1
        w2 -= learning_rate * grad_w2

    缺点:

    (1)没办法搭建复杂的网络结构(网络的结构搭建太底层);

    (2)梯度需要自己求导函数,如果函数太复杂,网络太深就很难求了;

    解决了GPU计算问题、少了一个缺点。

    3、torch的自动求导autograd

    import torch
    
    dtype = torch.float
    device = torch.device("cpu")
    # device = torch.device("cuda:0") # 这里使用CPU,但实际上可以使用GPU
    
    # N是训练的batch size; D_in 是input输入数据的维度;
    # H是隐藏层的节点数; D_out 输出的维度,即输出节点数.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    # 创建输入、输出数据
    x = torch.randn(N, D_in, device=device, dtype=dtype)  #(64,1000)
    y = torch.randn(N, D_out, device=device, dtype=dtype) #(64,10)可以看成是一个10分类问题
    
    # 权值初始化
    w1 = torch.randn(D_in, H, device=device, dtype=dtype) #(1000,100),即输入层到隐藏层的权重
    w2 = torch.randn(H, D_out, device=device, dtype=dtype)#(100,10),即隐藏层到输出层的权重
    
    learning_rate = 1e-6
    
    for t in range(500):
      
        # 第一步:数据的前向传播,计算预测值p_pred
        y_pred = x.mm(w1).clamp(min=0).mm(w2)
    
        # 第二步:计算计算预测值p_pred与真实值的误差
        loss = (y_pred - y).pow(2).sum()
        print(t, loss.item())
    
        # 第三步:反向传播误差,更新两个权值矩阵,这就是关键了,不再需要自己写出导函数,求导是自动完成的
        loss.backward()  #一步到位、自动求导
    
        # 参数梯度更新
        with torch.no_grad():
            w1 -= learning_rate * w1.grad  #grad属性获取梯度,其实这个地方就是相当于是梯度下降法,优化的过程可以自己定义,因为这里参数很少
            w2 -= learning_rate * w2.grad
    
            求完一次之后将梯度归零
            w1.grad.zero_()
            w2.grad.zero_()

    缺点:

    (1)没办法搭建复杂的网络结构(网络的结构搭建太底层);

    解决了GPU计算问题、而且梯度导数也不用自己求了,少了两个缺点。那现在就只剩一个问题没解决了,那就是怎么快速搭建更复杂、更深层的网络结构。

    (2)上面更新参数w1和w2的过程其实就是一个优化过程,这里是用的就是简单的头下降法,这样做有一个很大的缺点,那就是这里只有两个参数需要优化,所以可以自己写,但是现在的网络有很多的参数需要优化,都自己写的话实在是太麻烦了。于是就有了后面的方法,参见下面

    4、使用pytorch.nn模块,

    可以将它理解为一个较高层次的API封装

    # -*- coding: utf-8 -*-
    import torch
    
    # N是训练的batch size; D_in 是input输入数据的维度;
    # H是隐藏层的节点数; D_out 输出的维度,即输出节点数.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    # 创建输入、输出数据
    x = torch.randn(N, D_in)
    y = torch.randn(N, D_out)
    
    #模型搭建:这是与前面关键的区别,不再需要自己手动进行矩阵相乘,而是这种一步到位的方法
    model = torch.nn.Sequential(
        torch.nn.Linear(D_in, H),
        torch.nn.ReLU(),
        torch.nn.Linear(H, D_out),
    )
    
    #定义损失函数
    loss_fn = torch.nn.MSELoss(reduction='sum')
    
    learning_rate = 1e-4
    
    for t in range(500):
        
        # 第一步:数据的前向传播,计算预测值p_pred
        y_pred = model(x)
    
        # 第二步:计算计算预测值p_pred与真实值的误差
        loss = loss_fn(y_pred, y)
        print(t, loss.item())
    
        # 在反向传播之前,将模型的梯度归零
        model.zero_grad()
    
        # 第三步:反向传播误差,更新两个权值矩阵,这就是关键了,不再需要自己写出导函数,求导是自动完成的
        loss.backward()
    
        #更新参数的梯度
        with torch.no_grad():
            for param in model.parameters():
                param -= learning_rate * param.grad #这其实就是梯度下降法,优化参数,通过循环自动实现,不要再一个一个写了,相较于上面的参数更新方法简单了很多。但是还不够

    总结:

    到这一步,基本解决了前面的三个致命问题,即解决了GPU计算问题、而且梯度导数也不用自己求了,并且可以搭建复杂的网络,不需要自己进行一个一个的矩阵相乘,少了三个缺点。

    使用这里的层次,一些简单的网络类型就没什么问题了,当然我们还可以进一步优化,因为上面我们对loss进行自动求导之后,还需要通过一个循环来对模型的各个参数逐个进行参数的更新,所以下面提供了两个层次方面的优化措施

    5、使用torch.optim来进一步简化训练过程——进一步省略手动的参数更新,更加一步到位

    # -*- coding: utf-8 -*-
    import torch
    
    # N是训练的batch size; D_in 是input输入数据的维度;
    # H是隐藏层的节点数; D_out 输出的维度,即输出节点数.
    N, D_in, H, D_out = 64, 1000, 100, 10
    
    # 创建输入、输出数据
    x = torch.randn(N, D_in)
    y = torch.randn(N, D_out)
    
    #模型搭建:这是与前面关键的区别,不再需要自己手动进行矩阵相乘,而是这种一步到位的方法
    model = torch.nn.Sequential(
        torch.nn.Linear(D_in, H),
        torch.nn.ReLU(),
        torch.nn.Linear(H, D_out),
    )
    
    #定义损失函数
    loss_fn = torch.nn.MSELoss(reduction='sum')
    
    learning_rate = 1e-4
    #构造一个optimizer对象
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    
    for t in range(500):
        
        # 第一步:数据的前向传播,计算预测值p_pred
        y_pred = model(x)
    
        # 第二步:计算计算预测值p_pred与真实值的误差
        loss = loss_fn(y_pred, y)
        print(t, loss.item())
    
        # 在反向传播之前,将模型的梯度归零,这
        optimizer.zero_grad()
    
        # 第三步:反向传播误差
        loss.backward()
    
        # 直接通过梯度一步到位,更新完整个网络的训练参数,一句话优化所有的参数,是不是很牛逼
        optimizer.step()

    这是不是更加简单了?

    如果是使用过keras这样高层次的API,所以到这里应该发现,他们实在是太像了,现在来总结一下使用pytorch搭建神经网路的一般步骤:

    (1)第一步:搭建网络的结构,得到一个model。网络的结构可以是上面这种最简单的序贯模型,当然还可以是多输入-单输出模型、单输入-多输出模型、多输入-多输出模型、跨层连接的模型等,我们好可以自己定义模型,后面再讲。

    (2)第二步:定义损失函数。
    loss = torch.nn.MSELoss(reduction='sum')

    (3)第二步:定义优化方式。构造一个optimizer对象
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

    上面是模型以及模型相关的配置三步走,下面是训练的五步走

    (1)第一步:计算y_pred;

    (2)第二步:根据损失函数计算loss

    (3)第三步:梯度归零,
        optimizer.zero_grad()

    (4)第四步:反向传播误差
        loss.backward()

    (5)更新参数,使用step()
        optimizer.step()

    个人观点:

    深度学习框架最大的地方在于两个点,正是这两个点大大简化了我们自己的实现思路,当然这两个点不在于一层一层的搭建,个人认为最重要的在于以下两个:

    (1)第一,自动求导。设想一下,如果一个如此复杂的“高维度”、“非线性”的函数,需要自己写出求导公式,在进行矩阵运算,这一项就很不现实了。

    (2)第二,参数的优化。即所谓的optimizer的作用,它是每一个参数的更新规则,由于模型参数众多,不可能一个一个来更新,而且没一个更新的原理是重复的,深度学习框架正好提供了一步到位的方法,不管是tensorflow还是pytorch。

    展开全文
  • 【数学建模】1层次分析法模型部分

    千次阅读 2020-11-08 11:45:49
    AHP主要特点是通过建立递阶层次结构,把人类判断转化为若干因素两两之间重要度比较上,从而把难于量化定性判断转化为可操作重要度比较上面。在许多情况下,决策者可以直接使用AHP进行决策,极
  • 前言:神经网络搭建本身是一个较为复杂过程,但是现在有非常多、非常人性化开源框架提供给我们使用,但是即便如此,网络搭建也是有多种方法可以选择,本文以pytorch为例子加以说明。 神经网络基本流程...
  • 层次分析法

    2019-04-12 14:54:43
    建立层次结构模型 构造判别矩阵(正反交矩阵) 层次单排序及其一致性检验 层次总排序及其一致性检验 建立层次结构模型 这里使用一个例子,比如我们目标是选出学校附近最好餐馆,这里我们就会考虑每个餐馆...
  • gt-itm模型生成拓扑结构

    千次阅读 2016-12-12 15:12:41
    终于翻译成中文了,可自己都觉得这译得自己都不太懂.暂时先这样吧 从GT-ITM拓扑产生器产生图表  下载 GT-ITM Topology ...看看在这个叫Daniel Zappala的主页上的例子(实际上这个超链接已经没用).也看看在GT-ITM目录
  • 网络中OSI模型

    2018-12-22 17:41:08
    简单来说就是,当时不同公司用的网络标准不同,总是会有兼容性问题发生,然后这个组织就定义了一套层次结构的网络模型,希望大家都按照这个标准来。 OSI模型的7层模型 图片感觉太高度概括了,我来举个例子:...
  • Relationship Approach)2.3 数据模型的组成要素数据结构数据操作数据完整性约束条件2.4 常用的数据模型2.4.1 层次模型特点层次模型的数据操纵(树的相关操作)层次模型的完整性约束条件层次结构的优缺点例子2.4.2 ...
  • 引入 本文是计算机网络系列的第一篇文章 学东西得先有个全局观 才不会只见树木不见森林 所以本文将先从计算机网络的...搞明白了网络模型的层次结构 从整体上你也就搞懂了"网络"是怎么一回事 例子 下面进入...
  • 在前面的文章中更多介绍的是一些理论性质的东西,一些小伙伴在评论中也说希望有一些具体设计实践的例子,以及对一些问题进行了更加深入的交流讨论,因此准备了这篇文章。这篇文章将更多的介绍如何来进行模型层构建。...
  • 该项目的目的是提供一个高质量个人研究图书馆的例子。 它提供了模块化,持续集成,高测试覆盖率,强调可读性的代码库以及许多脚本,这些脚本使得在这里重现任何实验就像运行一些make命令一样容易。 我还通过实现...
  • 继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂认知过程。以前我们接触复用都是函数复用,继承是类设计层次复用。 例子: 网页 有很多公共部分 导致实现时候有很多重复代码 ...
  • 机器学习 | AHP层次分析法

    千次阅读 多人点赞 2019-05-15 20:39:47
    3 AHP层次分析法的实现3.1 步骤3.2 实际的例子3.2.1 背景3.2.2 Step1 构建层次结构模型3.2.3 Step2 构造成对比较矩阵3.2.4 Step3 一致性检验3.2.5 Step4 确定权重和最优方案3.3 Python实现3.3.1 直接将打分ok的excel...
  • 所谓不同抽象级别,实际上是指同一个物理电路,可以在不同层次上用Verilog语言描述它。 如果从行为和功能角度来描述某一电路模块,就称为行为模块; 如果从电路结构的角度来描述该电路模块,就称为结构模块。 ...
  • 离散与系统模型

    2014-06-11 23:11:05
    第11章 层次结构、互反矩阵与比例标度 1.引言 2.互反成对比较矩阵比例标度 3.标度 4.层次结构--一般考虑 5.一般的层次结构 6.关于冲突与计划应用说明 7.分解与归并或聚类 8.完全层次结构的一致...
  • 这样的例子在实际中相当的常见,比如分析随着时间的推移,企业的层次结构是否变得合理了,还是说上半年企业发展的非常合理,而到了下半年一个企业的层次性开始变差。或者再比如,我们想知道一个新员工是如何融入团体...
  • 建立层次结构模型 构造判断(成对比较)矩阵 第二层A各个因素对目标层Z成对比较矩阵(专家打分法) 说明C2重要性是C1两倍 第三层B各个因素A1,A2……A5成对比较矩阵分别如下: 层次单排序及其...
  • 刚开始对层模式,看起来有些吃力。希望能够依靠笔记帮忙,慢慢进入状态。... 例子 ISO7层模型。 2. 语境 一个需要分解大系统 3. 问题 假设有一个系统,它明显混合了底层与高层问题。 强制条件: 1...
  • 本文档旨在为初学Activiti朋友提供入门级别参考,不会对其原理及其结构进行深层次的探究(更多是因为目前自身理解还不是很透彻),只是为大家理清思路,方便以后更深层次的学习。本文档还有一个重要特点,那...
  • 这一块对我来说是一个新领域,所以刚开始看起来有些吃力。希望能够慢慢进入状态。也许需要依靠笔记帮忙。在我学习中,学习笔记占有很大地位,... 例子 ISO7层模型。 2. 语境 一个需要分解大系统 3. 问...
  • 今天学习资料是这篇文章,写非常详细,有理论有代码,本文是补充一些小细节,可以二者结合看效果更好:...本文结构模型训练算法基于 RNN 语言模型例子代码实现1. 模型和全连接网络区别更细致到向量级连...
  • 存储树形结构是一个很常见的问题,他有好几种解决方案。主要有两种方法:邻接列表模型和改进前序遍历树算法 在本文中,我们将探讨这两种保存层次数据的方法。我将举一个在线食品店树形图的例子。这个食品店通过类别...
  • (4)、模型数据都是以层次结构表示 2、模型索引 (1)、模型索引是将数据与视图分离重要机制 (2)、模型数据使用唯一索引来访问 (3)、QModelIndex是Qt中的模型索引类 A、包含具体数据...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 166
精华内容 66
关键字:

层次结构模型的例子