Trait/Object

com.thoughtworks.deeplearning

Layer

Related Docs: object Layer | package deeplearning

Permalink

trait Layer extends AnyRef

一个Layer表示一个神经网络。每个Layer可以作为子网络被包含在其它Layer中,构成更复杂的神经网络。Layer的嵌套结构可以用来表示数学公式或粗粒度神经网络结构。 当神经网络被编写完成后,其中大部分元素都是占位符,当网络开始训练时数据才真正进入到网络。

Layer 的树结构
val myLayer: Layer.Aux[Tape.Aux[Double, Double], Tape.Aux[Double, Double]] = {
  Times(
    Plus(
      Literal(1.0),
      Identity[Double, Double]()
    ),
    Weight(2.0)
  )
}

以上代码等价的数学公式可以用Symbolic写作:(1.0 + x) * 2.0.toWeight2.0.toWeight表示一个变量,其初始值是2,在神经网络迭代时,其值会更新。 TimesPlus都是 case class, 因此myLayer是一个case class构成的嵌套结构的树。TimesPlus都是占位符。

Weight是一个包含权重的Layer,初始值是2.0Identity是一个输入和输出相同的Layer,它会将输入原样返回。Identity在这里是Input的占位符。 Literal是一个包含常量的Layer

迭代

网络每次训练称为一个迭代,分为forwardbackward两个阶段,构成一次完整的反向传播流程。

forward

Layer.Aux[A,B]中调用forward时,A是输入类型,B是输出类型,AB都是Tape。下面开始逐段解释代码:

例如:

val inputTape: Tape.Aux[Double, Double] = Literal(a)
val outputTape = myLayer.forward(inputTape)

当调用myLayer.forward(inputData)时,首先调用Timesforward,其伪代码如下:

final case class Times(operand1: Layer, operand2: Layer) extends Layer {
  def forward(inputData: Tape): Output = {
    val upstream1 = operand1.forward(input)
    val upstream2 = operand2.forward(input)
    new Output(upstream1, upstream2)//这里忽略具体实现,而关注递归细节
  }
  final class Output(upstream1: Tape, upstream2: Tape) extends Tape { ... }
}

myLayer.operand1Plus,myLayer.operand2Weight,因此,upstream1upstream2分别是operand1operand2 forward 的结果。

以此类推,Plusforward代码与Timesforward类似,当调用Plusforward时,operand1Literaloperand2Identity,这时会各自调用LiteralIdentityforward

当调用Identityforward时会原样返回输入, Identityforward的伪代码如下:

def forward(inputTape: Tape.Aux[Double, Double]) = inputTape

所以Input即 数学公式(1.0 + x) * 2.0.toWeight 中的x,这样Input就被传递给了神经网络。

myLayer.forward的返回值outputTapeTape类型,所以最终会生成一棵Tape构成的树,结构和myLayer一样。 因此,通过层层传播 myLayer.forward(inputTape)最终被Identity原样返回,组合进新生成的Tape树。

outputTape 的包含forward 的计算结果,计算结果可以用来 backward 比如:

try {
  val loss = outputTape.value
  outputTape.backward(loss)
  loss
} finally {
  outputTape.close()
}

outputTape.value 是数学公式 (1.0 + x) * 2.0.toWeight 的计算结果。

backward

outputTape.backwardTimes.Outputbackward ,伪代码如下:

case class Times(operand1: Layer, operand2: Layer) extends Layer {
  def forward = ...
  class Output(upstream1, upstream2) extends Tape {
    private def upstreamDelta1(outputDelta: Double) = ???
    private def upstreamDelta2(outputDelta: Double) = ???
    override protected def backward(outputDelta: Double): Unit = {
      upstream1.backward(upstreamDelta1(outputDelta))
      upstream2.backward(upstreamDelta2(outputDelta))
    }
  }
}

outputTape.upstream1outputTape.upstream2分别是operand1operand2 forward 的结果。然后outputTape.upstream1outputTape.upstream2分别进行backward

以此类推,Plusbackward代码与Timesbackward类似,当调用Plusbackward时,upstream1upstream2分别是LiteralIdentity forward的结果,这时会各自调用upstream1upstream2backward

Weightbackward时会更新自己,参考updateDouble

Aux & Symbolic API

Layer.Aux[A,B]表示Input的类型是AOutput的类型是BTape.Aux[C,D]表示Data的类型是CDelta的类型是DLayer.AuxType.Aux可以组合起来使用,比如Layer.Aux[Tape.Aux[A,B],Tape.Aux[C,D]]可以用来表示一个layer的输入类型是一个Tape,这个Tape的数据类型为Adelta类型为Blayer的输出类型是一个Tape,这个Tape的数据类型为Cdelta类型为D

Aux是一种实现了type refinement的设计模式,可以用来限制类型参数的范围。

通常我们不会手写Aux类型,因为我们可以使用Symbolic实现同样的功能,例如在用于符号方法内部变量和返回值时:Layer.Aux[Tape.Aux[INDArray, INDArray], Tape.Aux[INDArray, INDArrayINDArray @Symbolic 是等价的,所以我们经常使用Symbolic来替代Aux的写法。

See also

Symbolic

Backpropagation

type refinement

aux pattern evolution

aux pattern

Linear Supertypes
AnyRef, Any
Type Hierarchy
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Layer
  2. AnyRef
  3. Any
Implicitly
  1. by any2stringadd
  2. by StringFormat
  3. by Ensuring
  4. by ArrowAssoc
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. abstract type Input <: Tape

    Permalink
  2. abstract type Output <: Tape

    Permalink

Abstract Value Members

  1. abstract def forward(input: Input): Output

    Permalink

Concrete Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. def +(other: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to any2stringadd[Layer] performed by method any2stringadd in scala.Predef.
    Definition Classes
    any2stringadd
  4. def ->[B](y: B): (Layer, B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to ArrowAssoc[Layer] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc
    Annotations
    @inline()
  5. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  6. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  7. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  8. def ensuring(cond: (Layer) ⇒ Boolean, msg: ⇒ Any): Layer

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to Ensuring[Layer] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  9. def ensuring(cond: (Layer) ⇒ Boolean): Layer

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to Ensuring[Layer] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  10. def ensuring(cond: Boolean, msg: ⇒ Any): Layer

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to Ensuring[Layer] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  11. def ensuring(cond: Boolean): Layer

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to Ensuring[Layer] performed by method Ensuring in scala.Predef.
    Definition Classes
    Ensuring
  12. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  13. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  14. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  15. def formatted(fmtstr: String): String

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to StringFormat[Layer] performed by method StringFormat in scala.Predef.
    Definition Classes
    StringFormat
    Annotations
    @inline()
  16. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  17. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  18. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  19. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  20. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  21. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  22. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  23. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  24. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  25. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  26. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  27. def [B](y: B): (Layer, B)

    Permalink
    Implicit information
    This member is added by an implicit conversion from Layer to ArrowAssoc[Layer] performed by method ArrowAssoc in scala.Predef.
    Definition Classes
    ArrowAssoc

Inherited from AnyRef

Inherited from Any

Inherited by implicit conversion any2stringadd from Layer to any2stringadd[Layer]

Inherited by implicit conversion StringFormat from Layer to StringFormat[Layer]

Inherited by implicit conversion Ensuring from Layer to Ensuring[Layer]

Inherited by implicit conversion ArrowAssoc from Layer to ArrowAssoc[Layer]

Ungrouped