Incubator-mxnet: MXNetR: how can i get the shape (dimension) of a certain symbol

Created on 28 Aug 2017  路  2Comments  路  Source: apache/incubator-mxnet

Given data as a symbol, I want to add noise.
This is given: data <- mx.symbol.Variable("data")
How can I do this? noise <- mx.symbol.random_normal(shape=???)
To do this: data_noisy <- data + noise

I've found (but didn't helped)

  • #2763 how can i get the shape of a certain symbol
  • #1090 How to get layer shapes

I've tried:

  1. data <- mx.symbol.random_normal(shape=mx.symbol.infer.shape(data))

Error in symbol$infer.shape(list(...)) : symbol.cc:165: RCheck failed: HasName(kwargs) Need to pass parameters in key=value style.

  1. data <- mx.symbol.random_normal(shape=dim(data))

Error in mx.varg.symbol.random_normal(list(...)) : ./base.h:271: RCheck failed: TYPEOF(val) == INTSXP || TYPEOF(val) == REALSXP Only accept integer vectors or simple types

3.data <- mx.symbol.random_normal(shape=data$infer.shape)

Error in mx.varg.symbol.random_normal(list(...)) : Cannot convert object to an environment: [type=closure; target=ENVSXP].

  1. data <- mx.symbol.random_normal(shape=data$infer.shape())

Error in data$infer.shape() : could not find valid method

  1. data <- mx.symbol.random_normal(shape=mx.symbol.infer.shape(symbol=data, data = mx.symbol.zeros_like(data)))

Error in symbol$infer.shape(list(...)) : Not compatible with requested type: [type=S4; target=integer].

Most helpful comment

There's typically no need to specify shape of data input when building the symbolic network. This will typically will be set at training time when the model is bind and the shapes infered from what the iterator provides as input data. This allows the same network to be trained with different batch sizes.

For the random noise, the shapes can be infered so there's no need to specify it. For example:

data <- mx.symbol.Variable("data")
noise <- mx.symbol.random_normal(loc=0, scale=1, name = "noise")
data_noise <- data + noise
graph.viz(data_noise, shape=c(2:3))

To infer the shape for a given data input shape, you need to pass the required input shapes as a list: data_noise$infer.shape(list(data=2:3)). This provides the shapes of each arguments in the network. To get the output shapes of each operator, you can use: data_noise$get.internals()$infer.shape(list(data=2:3))$out.shapes
Only the data shape is required to get the shapes of the overall network. Other shapes for data can be specified: the same model could be reused if the batch size or number of input features were different.

Graph can confirm: graph.viz(data_noise, shape=c(2:3))
rplot

You can finally validate that the noise layer operates as expected and generates new random noise at each batch iteration:

exec <- mxnet:::mx.symbol.bind(symbol = total, ctx = mx.cpu(), 
                               arg.arrays = list(data=data.array), aux.arrays = NULL,
                               grad.reqs = c("null"))
mx.exec.forward(exec, is.train = T)
exec$outputs
       [,1]       [,2]       [,3]

[1,] -0.9185634 -0.7457144 -1.2080863
[2,] 2.0088325 0.2863084 0.5604595

mx.exec.forward(exec, is.train = T)
exec$outputs
      [,1]       [,2]      [,3]

[1,] 1.8140212 -1.5227430 -2.515245
[2,] 0.9697598 -0.5285375 -1.889090

All 2 comments

There's typically no need to specify shape of data input when building the symbolic network. This will typically will be set at training time when the model is bind and the shapes infered from what the iterator provides as input data. This allows the same network to be trained with different batch sizes.

For the random noise, the shapes can be infered so there's no need to specify it. For example:

data <- mx.symbol.Variable("data")
noise <- mx.symbol.random_normal(loc=0, scale=1, name = "noise")
data_noise <- data + noise
graph.viz(data_noise, shape=c(2:3))

To infer the shape for a given data input shape, you need to pass the required input shapes as a list: data_noise$infer.shape(list(data=2:3)). This provides the shapes of each arguments in the network. To get the output shapes of each operator, you can use: data_noise$get.internals()$infer.shape(list(data=2:3))$out.shapes
Only the data shape is required to get the shapes of the overall network. Other shapes for data can be specified: the same model could be reused if the batch size or number of input features were different.

Graph can confirm: graph.viz(data_noise, shape=c(2:3))
rplot

You can finally validate that the noise layer operates as expected and generates new random noise at each batch iteration:

exec <- mxnet:::mx.symbol.bind(symbol = total, ctx = mx.cpu(), 
                               arg.arrays = list(data=data.array), aux.arrays = NULL,
                               grad.reqs = c("null"))
mx.exec.forward(exec, is.train = T)
exec$outputs
       [,1]       [,2]       [,3]

[1,] -0.9185634 -0.7457144 -1.2080863
[2,] 2.0088325 0.2863084 0.5604595

mx.exec.forward(exec, is.train = T)
exec$outputs
      [,1]       [,2]      [,3]

[1,] 1.8140212 -1.5227430 -2.515245
[2,] 0.9697598 -0.5285375 -1.889090

Made my day. Thanks for the clear and comprehensive answer.
And, in addition, an example how to use mx.symbol.bind().

Was this page helpful?
0 / 5 - 0 ratings

Related issues

phunterlau picture phunterlau  路  3Comments

xzqjack picture xzqjack  路  3Comments

sbodenstein picture sbodenstein  路  3Comments

GuilongZh picture GuilongZh  路  3Comments

luoruisichuan picture luoruisichuan  路  3Comments