modelop / hadrian

Implementations of the Portable Format for Analytics (PFA)
Apache License 2.0
130 stars 49 forks source link

[Titus] Neural network "math range error" with Titus, works with Hadrian #45

Open taunometsalu opened 6 years ago

taunometsalu commented 6 years ago

I ported the example of a neural network to aurelius:

library(aurelius)
tm = avro_typemap(
  Layer = avro_record(list(
    weights = avro_array(avro_array(avro_double)),
    bias = avro_array(avro_double)
  ))
)

pfaDocument = pfa_document(
  input = avro_array(avro_double),
  output = avro_double,
  cells = list(neuralnet = pfa_cell(avro_array(tm("Layer")), "[]")),
  action = expression(
    activation <- model.neural.simpleLayers(input, neuralnet, function(x = avro_double -> avro_double) m.link.logit(x)),
    m.link.logit(activation[0])
  )
)

neuralnet = list(
  list(
    weights = list(
      list(-6.0, -8.0),
      list(-25.0, -30.0)
    ),
    bias = list(4.0, 50.0)
  ),
  list(
    weights = list(
      list(-12.0, 30.0)
    ),
    bias = list(-25.0)
  )
)

pfaDocument$cells$neuralnet$init = neuralnet
engine = pfa_engine(pfaDocument)

x = list(
  list(0.0, 0.0),
  list(1.0, 0.0),
  list(0.0, 1.0),
  list(1.0, 1.0)
)
sapply(x, engine$action)

f = "/usr/local/src/gdrive/results/pfa/nnet_example.pfa"
write_pfa(pfaDocument, file = f)

With modified input, the model gives "math range error" with Titus:

x = list(100.0, 0.0)
model = read_pfa(file(f))
engine = pfa_engine(model)
engine$action(x)

However, with Hadrian, it works:

library(jsonlite)
tmp1 = tempfile(fileext = ".json")
tmp2 = tempfile(fileext = ".json")
write(minify(toJSON(x, auto_unbox = TRUE)), file = tmp1)
cmd = paste0("cd /usr/local/src/gdrive/; touch ", tmp2, "; ",
             "java -jar scripts/hadrian/hadrian-standalone-0.8.1-jar-with-dependencies.jar -i json -o json ",
             f, " ", tmp1, " > ", tmp2)
system(cmd)
out = fromJSON(readChar(tmp2, file.info(tmp2)$size), simplifyVector = FALSE)
unlink(tmp1)
unlink(tmp2)
print(out)

The PFA model looks like this:

{
  "input": {
    "type": "array",
    "items": "double"
  },
  "output": "double",
  "action": [
    {
      "let": {
        "activation": {
          "model.neural.simpleLayers": [
            "input",
            {
              "cell": "neuralnet"
            },
            {
              "params": [
                {
                  "x": "double"
                }
              ],
              "ret": "double",
              "do": {
                "m.link.logit": [
                  "x"
                ]
              }
            }
          ]
        }
      }
    },
    {
      "m.link.logit": [
        {
          "attr": "activation",
          "path": [
            0
          ]
        }
      ]
    }
  ],
  "cells": {
    "neuralnet": {
      "type": {
        "type": "array",
        "items": {
          "type": "record",
          "fields": [
            {
              "name": "weights",
              "type": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": "double"
                }
              }
            },
            {
              "name": "bias",
              "type": {
                "type": "array",
                "items": "double"
              }
            }
          ],
          "name": "Record_3"
        }
      },
      "init": [
        {
          "weights": [
            [
              -6,
              -8
            ],
            [
              -25,
              -30
            ]
          ],
          "bias": [
            4,
            50
          ]
        },
        {
          "weights": [
            [
              -12,
              30
            ]
          ],
          "bias": [
            -25
          ]
        }
      ],
      "source": "embedded",
      "shared": false,
      "rollback": false
    }
  }
}

What could be the issue?