难以理解 mxnet nn 所需的矩阵布局

Difficulty understanding required matrix layout for mxnet nn

得到一个数据框,其中 2:37 列作为变量,第一列作为二元响应变量。

mx.set.seed(1234)
train.x = data.matrix(A3n.df[,2:37])
train.y = A3n.df[,1]

data <- mx.symbol.Variable("data")
fc1 <- mx.symbol.FullyConnected(data, name="fc1", num_hidden=12)
act1 <- mx.symbol.Activation(fc1, name="relu1", act_type="relu")
fc2 <- mx.symbol.FullyConnected(act1, name="fc2", num_hidden=1)
logoutput <- mx.symbol.LogisticRegressionOutput(fc2, name="logoutput")

A1.MXmodel <- mx.model.FeedForward.create(logoutput, X=train.x, y=train.y,
                                     ctx=mx.gpu(), num.round=1000, array.batch.size=100,
                                     learning.rate=0.01, momentum=0.9,  eval.metric=mx.metric.accuracy,
                                     initializer=mx.init.uniform(0.07),
                                     epoch.end.callback=mx.callback.log.train.metric(100))

导致错误:

Error in mx.io.internal.arrayiter(as.array(data), as.array(label), unif.rnds,  : 
  io.cc:50: Seems X, y was passed in a Row major way, MXNetR adopts a column major convention.
Please pass in transpose of X instead

就在几天前,我使用了:

train.x <- t(train.x)

修复了错误并产生了低到令人信服的错误率,但今天,它接近 .50,没有学习。我也尝试将 array.layout 切换为 rowmajor/colmajor 没有效果。

[16] Train-accuracy=0.460714285714286
[17] Train-accuracy=0.460714285714286
[18] Train-accuracy=0.460714285714286
[19] Train-accuracy=0.460714285714286
[20] Train-accuracy=0.460714285714286
[993] Train-accuracy=0.460714285714286
[994] Train-accuracy=0.460714285714286
[995] Train-accuracy=0.460714285714286
[996] Train-accuracy=0.460714285714286
[997] Train-accuracy=0.460714285714286
[998] Train-accuracy=0.460714285714286
[999] Train-accuracy=0.460714285714286
[1000] Train-accuracy=0.460714285714286

在 mx.model.FeedForward.create 的调用中需要做一些更改才能使其正常工作:

  1. 从 train.x
  2. 移除转置
  3. 去掉eval.metric=mx.metric.accuracy(如果想看训练进度,可以替换成eval.metric=mx.metric.rmse)
  4. (可选)设置 array.layout = "rowmajor" 以指示您的示例在行中,特征在列中。 Mxnet 足够聪明,可以自动检测它,但它会删除输出中的讨厌消息

最终调用将如下所示:

A1.MXmodel <- mx.model.FeedForward.create(logoutput, X=train.x, y=train.y,
                                      ctx=mx.gpu(), num.round=1000, array.batch.size=100,
                                      learning.rate=0.01, momentum=0.9,
                                      initializer=mx.init.uniform(0.07),
                                      eval.metric=mx.metric.rmse,
                                      array.layout = "rowmajor",
                                      epoch.end.callback=mx.callback.log.train.metric(100))

问题是作为评估指标的准确性不能与逻辑回归符号的输出一起使用。如果您查看 the example on how Accuracy is calculated(抱歉,仅 python),您会注意到每个子数组中的元素数应等于 类 的数量。但是 LogisticRegressionOuput 只产生 1 个输出,因此它不能直接与 Accuracy 指标一起使用。

如果您仍想使用准确性指标,则需要:

  1. 设置fs2的隐藏单元数为2(类的个数)

    fc2 <- mx.symbol.FullyConnected(act1, name="fc2", num_hidden=2)

  2. 使用SoftmaxOutput作为最后一层:

    logoutput <- mx.symbol.SoftmaxOutput(fc2, name="logoutput")

SoftmaxOutput 产生 2 个输出,等于隐藏层中的单元数,因此可以正确计算精度。

干杯。