microsoft/CNTK-R

trouble with op_reduce_sum()

Closed this issue · 3 comments

Hi,
This is a rewording of CNTK issue @2492 I opened, but was directed here.

I am trying to write my first R program to forecast time series, along the lines of my previous Python programs. So, I have a number of time series of varying length. Each point of each time series has been preprocessed to an input vector of length 6 and an output vector of similar length (INPUT_SIZE and OUPUT_SIZE respectively).
I want to code my own loss function sMAPE (see https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error) .
So I declare
input_var <- seq_input_variable(INPUT_SIZE, name = "input")
output_var <- seq_input_variable(OUTPUT_SIZE, name = "label")
I create my network, e.g.
r=Recurrence(LSTM(STATE_SIZE))(input_var)
r=Dense(OUTPUT_SIZE, activation=op_softplus)(r)
z=op_minus(r,1)
Now, I am writing sMAPE:
a=op_element_divide(op_abs(op_minus(z,output_var)), op_plus(op_abs(output_var),op_abs(z)))
loss=op_reduce_sum(a)
and the last line fails, with
"AttributeError: 'Variable' object has no attribute 'is_static_axis'"

Very similar code works with Python. (It is attached listed in CNTK issue @2492).
seq_reduce_sum is not a good replacement, the result is
Composite(input: Sequence[Tensor[6]], label: Sequence[Tensor[6]]) -> Tensor[6]
while in Python, after execution o.reduce_sum() I am getting
Output('ElementTimes4266_Output_0', [#, *], []) and this works with an optimizer.

Regards,
Slawek

@slaweks17 very sorry for the late reply!
Could you try again with the latest? There was a typo in the op_reduce_sum.

@slaweks17 you can define the smape similarly to how you would in python:

smape_loss <- function(z, t) {
  
  loss <- op_reduce_mean(op_abs(t - z)/(t + z))
  loss
  
}

linear_layer <- function(input_var, output_dim) {
  
  input_var <- nrow(input_var)
  times_p <- op_parameter(shape = c(input_dim, output_dim))
  bias_p <- op_parameter(shape = output_dim)
  t <- op_times(input_var, times_p)
  
  bias_p + t
  
}

r <- Recurrence(LSTM(hidden_layer_dim1,
                     use_peepholes = LSTM_PEEP,
                     enable_self_stabilization = STABILIZE))(input_var)

z <- linear_layer(r, output_dim)
loss <- smape_loss(z, label)

Hi,
I followed you advice, although I had to use op_minus and op_plus instead of - and + respectively, and there was no error when calling this function below.
sMAPELoss<-function (z, output_var){
loss <- op_reduce_mean(op_element_divide(op_abs(op_minus(z,output_var)),op_plus(output_var,z)))
loss
}
But strangely, if I change op_reduce_mean() to op_reduce_sum(), I am getting the same
AttributeError: 'Variable' object has no attribute 'is_static_axis'

Anyway, thank you, I can live with mean, even if sum is a bit better. I have not tested this comprehensively, as I do not work with NNs at the moment, but I will within next few weeks.
I guess the issue can be closed in the meantime.

Regards,
Slawek