1

I am implementing a neural network in MXNetR. I attempted to customize my loss function to compute the correlation between my output vector and the targeting vector. Below is my code:

Below is my code:

# Generate testing data
train.x = matrix(data = rexp(200, rate = 10), nrow = 120, ncol = 6380)
test.x = matrix(data = rexp(200, rate = 10), nrow = 60, ncol = 6380)
train.y = matrix(data = rexp(200, rate = 10), nrow = 120, ncol = 319)
test.y = matrix(data = rexp(200, rate = 10), nrow = 60, ncol = 319)

# Reshape testing data
train.array <-train.x
dim(train.array) <-c(20,319,1,ncol(train.x))
test.array<-test.x
dim(test.array) <-c (20,319,1,ncol(test.x))

# Define the input data
data <- mx.symbol.Variable("data")

# Define the first fully connected layer
fc1 <- mx.symbol.FullyConnected(data, num_hidden = 100)
act.fun <- mx.symbol.Activation(fc1, act_type = "relu") # create a hidden layer with Rectified Linear Unit as its activation function.
output <<- mx.symbol.FullyConnected(act.fun, num_hidden = 319)

# Customize loss function
label <- mx.symbol.Variable("label")

output_mean <- mx.symbol.mean(output)
label_mean <- mx.symbol.mean(label)

output_delta <-mx.symbol.broadcast_sub(output, output_mean)
label_delta <- mx.symbol.broadcast_sub(label, label_mean)

output_sqr <-mx.symbol.square(output_delta)
label_sqr <- mx.symbol.square(label_delta)

output_sd <- mx.symbol.sqrt(mx.symbol.sum(output_delta))
label_sd <- mx.symbol.sqrt(mx.symbol.sum(label_delta))

numerator <- mx.symbol.sum(output_delta * label_delta)
denominator <- output_sd * label_sd

lro <- mx.symbol.MakeLoss(numerator/denominator)

# Generate a new model
model <- mx.model.FeedForward.create(symbol=lro, X=train.array, y=train.y, 
                                 num.round=5000, array.batch.size=1, optimizer = "adam",
                                 learning.rate = 0.0003, eval.metric = mx.metric.rmse,
                                 epoch.end.callback = mx.callback.log.train.metric(20, logger))

And I got this error:

Error in mx.model.init.params(symbol, input.shape, initializer, mx.cpu()) : 
Not enough information to get shapes

I tried to wrap the whole correlation formula in MXNet:

lro2 <- mx.symbol.MakeLoss(
    mx.symbol.negative((mx.symbol.sum(output * label) -
    (mx.symbol.sum(output) * mx.symbol.sum(label))) /
    mx.symbol.sqrt((mx.symbol.sum(mx.symbol.square(output)) -
    ((mx.symbol.sum(output)) * (mx.symbol.sum(output)))) *
    (mx.symbol.sum(mx.symbol.square(label)) - ((mx.symbol.sum(label)) * (mx.symbol.sum(label))))))
)

I can compile with this version, but my model runs very slowly and the code is apparently not very readable. I wonder if there is any way to implement get around the error and implement the first version as I described above.

nnguyen24
  • 21
  • 1
  • 4

1 Answers1

0

MXNet performs shape inference to determine the required shape of the model parameters (weights and biases) in order to allocate memory, and the first time this is done is when the model parameters are initialized.

Somewhere in your symbol you have a shape that can't be inferred from the neighbors, and I suspect it may be the broadcast_sub which you removed in the inline definition. It's hard to diagnose the exact issue due to the error in the reshape. You could also try working with NDArray to test the logic and then convert back to using Symbol.

If you're looking to batch samples, you should change the array.batch.size parameter of mx.model.FeedForward.create rather than reshaping your data into batches.

Thom Lane
  • 993
  • 9
  • 9