Giter Site home page Giter Site logo

thoughtworksinc / deeplearning.scala Goto Github PK

View Code? Open in Web Editor NEW
764.0 77.0 87.0 8.18 MB

A simple library for creating complex neural networks

Home Page: http://deeplearning.thoughtworks.school/

License: Apache License 2.0

Scala 100.00%
automatic-differentiation deep-neural-networks deep-learning scala neural-network functional-programming symbolic-computation dsl domain-specific-language machine-learning

deeplearning.scala's Introduction

DeepLearning.scala ThoughtWorks

Join the chat at https://gitter.im/ThoughtWorksInc/DeepLearning.scala Build Status Latest version Scaladoc

DeepLearning.scala is a simple library for creating complex neural networks from object-oriented and functional programming constructs.

  • DeepLearning.scala runs on JVM, can be used either in standalone JVM applications or a Jupyter Notebooks.
  • DeepLearning.scala is expressive. Various types of neural network layers can be created by composing map, reduce or other higher order functions.
  • DeepLearning.scala supports plugins. There are various plugins providing algorithms, models, hyperparameters or other features.
  • All the above features are statically type checked.

Features

Differentiable programming

Like other deep learning toolkits, DeepLearning.scala allows you to build neural networks from mathematical formulas. It supports floats, doubles, GPU-accelerated N-dimensional arrays, and calculates derivatives of the weights in the formulas.

Dynamic neural networks

Unlike some other deep learning toolkits, the structure of neural networks in DeepLearning.scala is dynamically determined during running. Our neural networks are programs. All Scala features, including functions, expressions and control flows, are available in neural networks.

For example:

def ordinaryScalaFunction(a: INDArray): Boolean = {
  a.signnum.sumT > math.random
}

def myDynamicNeuralNetwork(input: INDArray) = INDArrayLayer(monadic[Do] {
  val outputOfLayer1 = layer1(input).forward.each
  if (ordinaryScalaFunction(outputOfLayer1.data)) {
    dynamicallySelectedLayer2(outputOfLayer1).forward.each
  } else {
    dynamicallySelectedLayer3(outputOfLayer1).forward.each
  }
})

The above neural network will go into different subnetworks according to an ordinary Scala function.

With the ability of creating dynamic neural networks, regular programmers are able to build complex neural networks from simple code. You write code almost as usual, the only difference being that code based on DeepLearning.scala is differentiable, which enables such code to evolve by modifying its parameters continuously.

Functional programming

DeepLearning.scala 2.0 is based on Monads, which are composable, thus a complex layer can be built from primitive operators or higher order functions like map/reduce. Along with the Monad, we provide an Applicative type class, to perform multiple calculations in parallel.

For example, the previous example can be rewritten in higher-order function style as following:

def myDynamicNeuralNetwork(input: INDArray) = INDArrayLayer {
  layer1(input).forward.flatMap { outputOfLayer1 =>
    if (ordinaryScalaFunction(outputOfLayer1.data)) {
      dynamicallySelectedLayer2(outputOfLayer1).forward
    } else {
      dynamicallySelectedLayer3(outputOfLayer1).forward
    }
  }
}

The key construct in DeepLearning.scala 2.0 is the dependent type class DeepLearning, which witnesses a differentiable expression. In other words, given the DeepLearning type class instance, you can activate the deep learning ability of any type.

Object-oriented programming

The code base of DeepLearning.scala 2.0 is organized according to Dependent Object Type calculus (DOT). All features are provided as mixin-able plugins. A plugin is able to change APIs and behaviors of all DeepLearning.scala types. This approach not only resolves expression problem, but also gives plugins the additional ability of virtually depending on other plugins.

For example, when a plugin author is creating the Adagrad optimizer plugin, he does not have to explicitly call functions related to learning rate. However, once a plugin user enables both the Adagrad plugin and the FixedLearningRate plugin, then computation in FixedLearningRate will get called eventually when the Adagrad optimization is executed.

Roadmap

v2.0

Version 2.0 is the current version with all of the above features.

v3.0

  • Support element-wise map/reduce and other higher-order functions on GPU.
  • Support distributed models and distributed training on Spark.

Links

Acknowledgements

DeepLearning.scala is sponsored by ThoughtWorks.

DeepLearning.scala is heavily inspired by my colleague @MarisaKirisame. Originally, we worked together on a prototype of a deep learning framework, and eventually split our work into this project and DeepDarkFantasy. Other contributors can be found at here.

Related projects

  • Shapeless provides a solid foundation for type-level programming used in DeepLearning.scala.
  • Scalaz and Algebra provides type classes used in DeepLearning.scala.
  • ThoughtWorks Each provides async/await-like syntax. You may want to use it to control your training process in an imperative style.
  • nd4j provides numerical computing used in DeepLearning.scala 2.0.
  • Compute.scala provides numerical computing used in DeepLearning.scala 3.0.
  • RAII.scala, future.scala and tryt.scala provides monadic asynchronous resource management used in DeepLearning.scala.
  • Plugins of DeepLearning.scala are based on Factory and other dependent type classes in feature.scala.
  • Import.scala is a Scala compiler plugin that enables magic imports. You may need it in those sbt project use DeepLearning.scala plugin hosted on Github Gist.
  • DeepLearning.scala can run in Jupyter Scala or Ammonite.
  • The unit tests of DeepLearning.scala are written in ScalaTest and example.scala syntax.
  • Some type classes in DeepLearning.scala are created by simulacrum's @typeclass annotation.

deeplearning.scala's People

Contributors

atry avatar bucry avatar gdemelo avatar gitter-badger avatar izhangzhihao avatar jvliwanag avatar marisakirisame avatar matt-liu avatar nightscape avatar revysr avatar scala-steward avatar sksamuel avatar terrorjack avatar tw-data-china-go-cd avatar xingd avatar zxiy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deeplearning.scala's Issues

TryT

Use TryT instead of EitherT in RAII.scala

  • remove RAIITask

  • ResourceFactoryT

  • ResourceFactoryTSpec

  • remove sde-raii & sde-raii-Spec

  • Shared

  • SharedSpec

Support RAII

So that we can avoid too many try/finally statements when constructing a complicated layer.

compile error in scala version 2.12

    def toLayerTest(implicit from: From[Double]##T) = {
      1.0.toLayer
      Seq(1.0).toLayer
      Seq(1.0.toLayer).toLayer
      Seq(1.toLayer).toLayer
      Seq(1).toLayer
    }

error:

[error] DeepLearning.scala/src/test/scala/com/thoughtworks/deeplearning/SeqSpec.scala:38: value toLayer is not a member of Double
[error]       1.0.toLayer
[error]           ^
[error] DeepLearning.scala/src/test/scala/com/thoughtworks/deeplearning/SeqSpec.scala:39: value toLayer is not a member of Seq[Double]
[error]       Seq(1.0).toLayer
[error]                ^
[error] DeepLearning.scala/src/test/scala/com/thoughtworks/deeplearning/SeqSpec.scala:40: value toLayer is not a member of Double
[error]       Seq(1.0.toLayer).toLayer
[error]               ^
[error] DeepLearning.scala/src/test/scala/com/thoughtworks/deeplearning/SeqSpec.scala:41: value toLayer is not a member of Int
[error]       Seq(1.toLayer).toLayer
[error]             ^
[error] DeepLearning.scala/src/test/scala/com/thoughtworks/deeplearning/SeqSpec.scala:42: value toLayer is not a member of Seq[Int]
[error]       Seq(1).toLayer
[error]              ^
[error] 5 errors found

Use `Do` instead of `RAIITask`

  • Tape

  • ToTapeTask

  • TapeTaskFactory

  • TapeTask

  • differentiable-float

  • differentiable-float-Spec

  • DifferentiableKernel

  • DifferentiableKernelSpec

Optimizers for OpenCL buffer

  • PendingBuffer should borrow OpenCL.Buffer and OpenCL.Event
  • Weight should store OpenCL.Buffer and OpenCL.Event, not PendingBuffer
  • Weight.data should duplicate OpenCL.Buffer and OpenCL.Event
  • A simple optimizer

General LA, Data Flow and Reactive Programming

For what you are implementing for deep learning with a bit more flexibility perhaps you can make this a such that it can also be used to code application logic in LA / Data Flow / Reactive paradigms. Is it possible to give this flexibility?

Abstract GPU AST

At the moment, DslExpression and DslType only works for OpenCL. We should create abstract types in order to support other compute platform, e.g. CUDA

Website

  • website template
  • CI
  • Homepage
  • Documentation
    • Tutorials in Jupyter Notebook format
    • Contribution Guideline
    • Scaladoc
      • Directory Structure and import guidelines
      • Each concept: Batch, Layer, Symbolic, Poly, XxxOps
      • Utility methods: train, predict, compose,withOutputDataHook
      • translate

https://thoughtworksinc.github.io/DeepLearning.scala

Compile neural networks to OpenCL

  • Generate non-differentiable OpenCL code for a minimal AST
  • Utilities to release OpenCL contexts, command queues and buffers
  • Utilities to create OpenCL contexts and command queues
  • Create a OpenCL version of neural network for a AST (#9), which creates a buffer and it does not reference to other buffers
  • Create a OpenCL version of neural network for a AST that references to other buffers

Type infer error at implement of Poly1 in differentiable-indarray

That should compile

    implicit def optimizer: Optimizer = new LearningRate {
      def currentLearningRate() = 1
    }

    val weight: Do[Borrowing[Tape.Aux[INDArray, INDArray]]]   = (Nd4j.ones(4, 4) * 10).toWeight

    def myNetwork(input: INDArray) : Do[Borrowing[Tape.Aux[INDArray, INDArray]]] = {
      abs(weight)
    }

but actually not:

Error:(429, 11) type mismatch;
 found   : weight.type (with underlying type com.thoughtworks.raii.asynchronous.Do[com.thoughtworks.raii.ownership.Borrowing[com.thoughtworks.deeplearning.Tape.Aux[org.nd4j.linalg.api.ndarray.INDArray,org.nd4j.linalg.api.ndarray.INDArray]]])
 required: com.thoughtworks.deeplearning.PolyFunctions.abs.ProductCase.Aux[shapeless.HNil,?]
    (which expands to)  shapeless.poly.Case[com.thoughtworks.deeplearning.PolyFunctions.abs.type,shapeless.HNil]{type Result = ?}
      abs(weight)

a workaround:

    implicit def optimizer: Optimizer = new LearningRate {
      def currentLearningRate() = 1
    }

    val weight: Do[Borrowing[Tape.Aux[INDArray, INDArray]]]   = (Nd4j.ones(4, 4) * 10).toWeight

    def myNetwork(input: INDArray)  = {
      abs(weight)
    }

or :

    implicit def optimizer: Optimizer = new LearningRate {
      def currentLearningRate() = 1
    }

    val weight: Do[Borrowing[Tape.Aux[INDArray, INDArray]]]   = (Nd4j.ones(4, 4) * 10).toWeight

    def myNetwork(input: INDArray) : Do[Borrowing[Tape.Aux[INDArray, INDArray]]] = {
      val result = abs(weight)
      result
    }

possible solution:

add

def abs(a: AnyRef)(implicit c: abs.Case[a.type]): c.Result = c[a.type](a)

to PolyFunctions, and make Do be a type Do[A] <:AnyRef

Package structure

  • deeplearning

    • package
      • implicit cases
    • Tape
    • Lift
    • tapefactories
    • math
    • logs
    • differentiable
      • package
        • type Float
        • type Double = Do[_ <: Tape.Aux[scala.Double, scala.Double]] / type Double = Do[Tape.Aux[scala.Double, scala.Double]]
        • type Any = Do[_ <: Tape.Aux[scala.Any, scala.Nothing]]
      • Any
        • AnyOps
          • predict
          • train
      • Float
      • Double
      • INDArray
  • raii

    • resourcet
      • ResourceT
      • Releasable
    • sharedops
      • SharedOps
    • future
      • Do
    • sde
      • raii
      • do
  • tryt

remove CovariantT
remove EitherTNondeterminism
remove FreeTParallelApplicative
remvoe KleisliParallelApplicative

More than async

We are implementing asynchronous computing in DeepLearning.scala 2.0.
However, in order to maximize the throughput, we need on-device computing graph instead of CPU driven asynchronous computing.

In DeepLearning.scala 3.0, we will implement applicative-based computing graph, avoiding flatMap or map. We will keep a proper number of kernel for an on-device command queue, e.g. 3 kernels. Most of the on-CPU Futures await for command queue available, instead of awaiting for result.

  • Counting the load of command queue
  • Make tuples of Buffer and Event

Do

  • DoInstance
  • DoExtractor
  • Implicit methods

DifferentiableNDArray

  • Weight
  • Optimizer
  • Ops
  • PolyMethods & PolyFunctions
  • convolutionOps
  • Test
  • SemigroupTapeTaskFactory

isTrainable should be avoided

backward, forceBackward and rawBackward seems too messy.

We should remove forceBackward and isTrainable from public API.

Type inference error

下面可以编译通过且正确运行:

package testPackage

import com.thoughtworks.deeplearning.DifferentiableINDArray._
import com.thoughtworks.deeplearning.DifferentiableAny._
import com.thoughtworks.deeplearning.Lift._
import com.thoughtworks.deeplearning.Poly.MathFunctions._
import com.thoughtworks.deeplearning.Poly.MathOps
import org.nd4j.linalg.api.ndarray.INDArray
import org.nd4s.Implicits._
import shapeless._

object Bug extends App {
  def layer(implicit x: From[INDArray] ##T): To[INDArray] ##T = {
    val result: To[INDArray] ##T = exp(x).withOutputDataHook { x: INDArray =>
      println(x)
    }
    result / result.sum(1)
  }

  layer.train(
    Array(Array(1, 2, 3, 4),
          Array(1, 2, 3, 4),
          Array(1, 2, 3, 4),
          Array(1, 2, 3, 4)).toNDArray)
}

result后面的类型去掉后会报错:

Error:(17, 21) value sum is not a member of com.thoughtworks.deeplearning.Layer.Aux[com.thoughtworks.deeplearning.Layer.Batch{type Data <: org.nd4j.linalg.api.ndarray.INDArray; type Delta >: org.nd4j.linalg.api.ndarray.INDArray},com.thoughtworks.deeplearning.Layer.Batch.Aux[this.Data,com.thoughtworks.deeplearning.DifferentiableINDArray.INDArrayPlaceholder.Delta]]
    result / result.sum(1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.