How bind to names in MXNET mx.io.internal.arrayiter() output?

677 views Asked by At

I rewrote an example available here (link to data in document) https://github.com/dmlc/mxnet/blob/master/example/recommenders/demo1-MF.ipynb

library(mxnet)


DF <- read.delim("./data/ml-100k/u.data", header=F)
names(DF) <- c("user", "item", "score", "time")

max_user<- max(DF$user)
max_item <- max(DF$item)

DF_mat_x <- data.matrix(t(sapply(DF[,1:2], as.numeric)))
DF_y <- DF[,3]

mx.io.arrayiter(DF_mat_x, t(data.matrix(data.frame(score=DF_y))))


k <- 64


## model
user <- mx.symbol.Variable("user")
item <- mx.symbol.Variable("item")
score <- mx.symbol.Variable("label")
## user feature lookup
user1 <- mx.symbol.Embedding(data=user, input_dim = max_user, output_dim = k, name="user1") 
## item feature lookup
item1 <- mx.symbol.Embedding(data=item, input_dim = max_item, output_dim = k, name="item1")
## predict by the inner product, which is elementwise product and then sum
pred <- user1 * item1
pred1 <- mx.symbol.sum_axis(pred, axis = 1, name="pred1")
pred2 <- mx.symbol.Flatten(pred1, name="pred2")
## loss layer
pred3 <- mx.symbol.LinearRegressionOutput(data=pred2, label=score, name="pred3")


devices <- mx.cpu()
mx.set.seed(123)


mx.model.FeedForward.create(pred3, X =  mx.io.arrayiter(data=DF_mat_x,   label=t(data.matrix(data.frame(score=DF_y)))),
                            ctx=devices, num.round=10, array.batch.size=10,
                            verbose=T, #array.layout="rowmajor",
                            initializer=mx.init.uniform(0.07),  learning.rate=0.07,
                            eval.metric=mx.metric.rmse, momentum = 0.9,
                            epoch.end.callback=mx.callback.log.train.metric(1))

Get error

[19:28:45] /root/mxnet/dmlc-core/include/dmlc/logging.h:235: [19:28:45]  src/symbol/symbol.cc:155: Symbol.InferShapeKeyword argument name data not  found.
Candidate arguments:
    [0]user
    [1]user1_weight
    [2]item
    [3]item1_weight
    [4]label

Error in symbol$infer.shape(list(...)) : basic_string::resize
> traceback()
6: stop(list(message = "basic_string::resize", call =   symbol$infer.shape(list(...)), 
       cppstack = NULL))
5: .External(list(name = "CppMethod__invoke_notvoid", address = <pointer: 0x11caef0>, 
       dll = list(name = "Rcpp", path = "/usr/local/lib/R/site-library/Rcpp/libs/Rcpp.so", 
           dynamicLookup = TRUE, handle = <pointer: 0x1404520>, 
           info = <pointer: 0x7f348a598d80>), numParameters = -1L), 
       <pointer: 0x3835820>, <pointer: 0x3836540>, .pointer, ...)
4: symbol$infer.shape(list(...))
3: mx.symbol.infer.shape(symbol, data = input.shape)
2: mx.model.init.params(symbol, input.shape, initializer, mx.cpu())
1: mx.model.FeedForward.create(pred3, X = mx.io.arrayiter(data = DF_mat_x, 
        label = t(data.matrix(data.frame(score = DF_y)))), ctx = devices, 
        num.round = 10, array.batch.size = 10, verbose = T, initializer = mx.init.uniform(0.07), 
       learning.rate = 0.07, eval.metric = mx.metric.rmse, momentum = 0.9, 
       epoch.end.callback = mx.callback.log.train.metric(1))

Manually I get data one labels

> X <- mx.io.arrayiter(data=DF_mat_x, label=t(data.matrix(data.frame(score=DF_y))))
> Z <- mxnet:::mx.model.init.iter(X, NULL, batch.size = 120, is.train = TRUE)
> Z$iter.next()
[1] TRUE
> Z$value()
$data
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
[1,]  196  186   22  244  166  298  115  253  305     6    62   286   200   210
[2,]  242  302  377   51  346  474  265  465  451    86   257  1014   222    40
     [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
[1,]   224   303   122   194   291   234   119   167   299   291   308    95
[2,]    29   785   387   274  1042  1184   392   486   144   118     1   546
     [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
[1,]    38   102    63   160    50   301   225   290    97   157   181   278
[2,]    95   768   277   234   246    98   193    88   194   274  1081   603
     [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
[1,]   276     7    10   284   201   276   287   246   242   249    99   178
[2,]   796    32    16   304   979   564   327   201  1137   241     4   332
     [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
[1,]   251    81   260    25    59    72    87   290    42   292   115    20
[2,]   100   432   322   181   196   679   384   143   423   515    20   288
     [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74]
[1,]   201    13   246   138   167    60    57   223   189   243    92   246
[2,]   219   526   919    26   232   427   304   274   512    15  1049   416
     [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86]
[1,]   194   241   178   254   293   127   225   299   225   276   291   222
[2,]   165   690   248  1444     5   229   237   229   480    54   144   366
     [,87] [,88] [,89] [,90] [,91] [,92] [,93] [,94] [,95] [,96] [,97] [,98]
[1,]   267    42    11    95     8   162    87   279   145   119    62    62
[2,]   518   403   111   625   338    25  1016   154   275  1153   498   382
     [,99] [,100] [,101] [,102] [,103] [,104] [,105] [,106] [,107] [,108]
[1,]    28    135     32     90    286    293    216    166    250    271
[2,]   209     23    294    382    208    685    144    328    496    132
     [,109] [,110] [,111] [,112] [,113] [,114] [,115] [,116] [,117] [,118]
[1,]    160    265    198     42    168    110     58     90    271     62
[2,]    174    118    498     96    151    307    144    648    346     21
     [,119] [,120] [,121] [,122] [,123] [,124] [,125] [,126] [,127] [,128]
[1,]    279    237     94    128    298     44    264    194     72    222
[2,]    832    514    789    485    317    195    200    385    195    750

$label
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]     [,14]
  [1,]    3    3    1    2    1    4    2    5    3     3     2     5       5     3
    [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
[1,]     3     3     5     2     4     2     4     4     4     2     4     2
    [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
[1,]     5     2     4     5     3     4     4     4     3     4     1     5
     [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
[1,]     1     4     4     4     2     3     5     5     5     5     5     3
    [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
[1,]     4     2     4     5     5     2     4     5     5     4     3     1
     [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74]
[1,]     4     3     4     5     1     5     5     4     4     3     1     3
     [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86]
[1,]     4     2     4     3     3     5     5     3     5     3     5     4
     [,87] [,88] [,89] [,90] [,91] [,92] [,93] [,94] [,95] [,96] [,97] [,98]
[1,]     5     3     4     4     4     4     4     5     2     5     4     3
     [,99] [,100] [,101] [,102] [,103] [,104] [,105] [,106] [,107] [,108]
[1,]     4      4      3      5      4      3      4      5      4      5
     [,109] [,110] [,111] [,112] [,113] [,114] [,115] [,116] [,117] [,118]
[1,]      5      4      3      5      5      4      4      4      4      3
     [,119] [,120] [,121] [,122] [,123] [,124] [,125] [,126] [,127] [,128]
[1,]      3      4      4      3      4      5      5      2      5      5

And the model does not see the data

Original example uses

    user = mx.nd.array(user)
    item = mx.nd.array(item)
    score = mx.nd.array(score)
    return mx.io.NDArrayIter(data={'user':user,'item':item},label={'score':score}, 
                             batch_size=batch_size, shuffle=True)

How do it properly in R?

UPDATE

New network

data <- mx.symbol.Variable("data")
user <- mx.symbol.transpose(mx.symbol.slice_axis(data=data, axis=0,    begin=1, end=2, name="user"))
item <- mx.symbol.transpose(mx.symbol.slice_axis(data=data, axis=0, begin=0, end=1, name="item"))
score <- mx.symbol.Variable("label")
## user feature lookup
user1 <- mx.symbol.Embedding(data=user, input_dim = max_user, output_dim = k, name="user1")
## item feature lookup
item1 <- mx.symbol.Embedding(data=item, input_dim = max_item, output_dim = k, name="item1")
## predict by the inner product, which is elementwise product and then sum
pred <- user1 * item1
pred1 <- mx.symbol.sum_axis(pred, axis = 1, name="pred1")
pred2 <- mx.symbol.Flatten(pred1, name="pred2")
## loss layer
pred3 <- mx.symbol.LinearRegressionOutput(data=pred2, label=score, name="pred3")


X.train.iter <- mx.io.arrayiter(data=DF_mat_x,   label=t(data.matrix(data.frame(score=DF_y))))

mx.model.FeedForward.create(pred3, X = X.train.iter ,
                            ctx=devices, num.round=10, array.batch.size=10,
                            verbose=T, #array.layout="colmajor",
                            initializer=mx.init.uniform(0.07), learning.rate=0.07,
                            eval.metric=mx.metric.rmse, momentum = 0.9,
                          epoch.end.callback=mx.callback.log.train.metric(1))

Error

 Start training with 1 devices
[22:43:54] /root/mxnet/dmlc-core/include/dmlc/logging.h:235: [22:43:54]  src/ndarray/ndarray.cc:231: Check failed: from.shape() == to->shape() operands shape mismatch
Error in exec$update.arg.arrays(arg.arrays, match.name, skip.null) : 
  basic_string::resize
 traceback()
6: stop(list(message = "basic_string::resize", call =  exec$update.arg.arrays(arg.arrays, 
       match.name, skip.null), cppstack = NULL))
5: .External(list(name = "CppMethod__invoke_void", address = <pointer: 0x18be2c0>, 
       dll = list(name = "Rcpp", path = "/usr/local/lib/R/site-library/Rcpp/libs/Rcpp.so", 
           dynamicLookup = TRUE, handle = <pointer: 0x2a27840>, 
           info = <pointer: 0x7f021bba2d80>), numParameters = -1L), 
   <pointer: 0x3c71d10>, <pointer: 0x3c61310>, .pointer, ...)
4: exec$update.arg.arrays(arg.arrays, match.name, skip.null)
3: mx.exec.update.arg.arrays(train.execs[[i]], s, match.name = TRUE)
2: mx.model.train(symbol, ctx, input.shape, params$arg.params, params$aux.params, 
       begin.round, num.round, optimizer = optimizer, train.data = X, 
       eval.data = eval.data, metric = eval.metric, epoch.end.callback = epoch.end.callback, 
       batch.end.callback = batch.end.callback, kvstore = kvstore, 
   verbose = verbose)
1: mx.model.FeedForward.create(pred3, X = X.train.iter, ctx = devices, 
       num.round = 10, array.batch.size = 10, verbose = T, initializer = mx.init.uniform(0.07), 
       learning.rate = 0.07, eval.metric = mx.metric.rmse, momentum = 0.9, 
       epoch.end.callback = mx.callback.log.train.metric(1))

Model is created, but does not work.

1

There are 1 answers

2
lynguyen On BEST ANSWER

The error

src/symbol/symbol.cc:155: Symbol.InferShapeKeyword argument name data not  found. Candidate arguments:
[0]user
[1]user1_weight
[2]item
[3]item1_weight
[4]label

shows that the symbol shape inference in the R code is trying to reference a variable called "data" but only the variables listed above (which you used in your net) are available. See this line: https://github.com/dmlc/mxnet/blob/master/R-package/R/model.R#L264

The Python example uses a subclassed iterator so the symbol variables can be named anything without resulting in the error that you got.

I posted a new issue to change that here: https://github.com/dmlc/mxnet/issues/4462