R中的MXNET中的CNN图像识别输出标量而不是类

时间:2017-08-07 20:53:29

标签: r conv-neural-network image-recognition mxnet

我正在尝试使用CNN中的mxnet包来尝试根据图像预测标量输出(在我的情况下等待时间)。

然而,当我这样做时,我得到相同的结果输出(它预测相同的数字,这可能只是所有结果的平均值)。如何让它正确预测标量输出。

我的图像已经过预处理,通过灰度化并转换为下面的像素格式并将其缩放到28 x 28(我也尝试过不同尺寸但没有效果)。

我基本上使用图像来预测等待时间,这就是为什么我的train_y是以秒为单位的当前等待时间。使用这种方法时,将我的train_y作为当前等待时间(以秒为单位),算法只预测相同的数字。

然而,当我通过猜测最大值(20000)将train_y变换为[0,1]时,CNN会输出不同的数字,但是当再次通过乘以20000来缩放这些数字时,我似乎得到了预测负数和数字太偏斜,给模型带来不良结果。负数尤其没有意义,因为我所有的train_y都是正面的,因为我处理的是时间,所以没有负数这样的东西

我也通过测试从0.05,0.01,0.001,0.0001,0.00001等测试学习率,直到2e-8,对模型没有影响。我也玩过初始化器

我也通过将其从0.9改为0.95而对模型没有影响而动摇了。

这是我可重现的代码:

set.seed(0)

df <- data.frame(replicate(784,runif(7538)))
df$waittime <- 1000*runif(7538)


training_index <- createDataPartition(df$waittime, p = .9, times = 1)
training_index <- unlist(training_index)

train_set <- df[training_index,]
dim(train_set)
test_set <- df[-training_index,]
dim(test_set)


## Fix train and test datasets
train_data <- data.matrix(train_set)
train_x <- t(train_data[, -785])
train_y <- train_data[,785]
train_array <- train_x
dim(train_array) <- c(28, 28, 1, ncol(train_array))


test_data <- data.matrix(test_set)
test_x <- t(test_set[,-785])
test_y <- test_set[,785]
test_array <- test_x
dim(test_array) <- c(28, 28, 1, ncol(test_x))




library(mxnet)
## Model
mx_data <- mx.symbol.Variable('data')
## 1st convolutional layer 5x5 kernel and 20 filters.
conv_1 <- mx.symbol.Convolution(data = mx_data, kernel = c(5, 5), num_filter = 20)
tanh_1 <- mx.symbol.Activation(data = conv_1, act_type = "tanh")
pool_1 <- mx.symbol.Pooling(data = tanh_1, pool_type = "max", kernel = c(2, 2), stride = c(2,2 ))
## 2nd convolutional layer 5x5 kernel and 50 filters.
conv_2 <- mx.symbol.Convolution(data = pool_1, kernel = c(5,5), num_filter = 50)
tanh_2 <- mx.symbol.Activation(data = conv_2, act_type = "tanh")
pool_2 <- mx.symbol.Pooling(data = tanh_2, pool_type = "max", kernel = c(2, 2), stride = c(2, 2))
## 1st fully connected layer
flat <- mx.symbol.Flatten(data = pool_2)
fcl_1 <- mx.symbol.FullyConnected(data = flat, num_hidden = 500)
tanh_3 <- mx.symbol.Activation(data = fcl_1, act_type = "tanh")
## 2nd fully connected layer
fcl_2 <- mx.symbol.FullyConnected(data = tanh_3, num_hidden = 1)
## Output
#NN_model <- mx.symbol.SoftmaxOutput(data = fcl_2)
label <- mx.symbol.Variable("label")
#NN_model <- mx.symbol.MakeLoss(mx.symbol.square(mx.symbol.Reshape(fcl_2, shape = 0) - label))
NN_model <- mx.symbol.LinearRegressionOutput(fcl_2)




#Didn't work well, predicted same number continuously regardless of image
## Train on samples
model <- mx.model.FeedForward.create(NN_model, X = train_array, y = train_y,
                                     #                                     ctx = device,
                                     num.round = 30,
                                     array.batch.size = 100,
                                    # initializer=mx.init.uniform(0.002),
initializer = mx.init.Xavier(factor_type = "in", magnitude = 2.34), 
                                     learning.rate = 0.00001,
                                     momentum = 0.9,
                                     wd = 0.00001,
                                     eval.metric = mx.metric.rmse)
                                     #epoch.end.callback = #mx.callback.log.train.metric(100))



pred <- predict(model, test_array)
#gives the same numeric output 
#or when train_y is scaled to [0,1] gives very poor responses and negative numbers

1 个答案:

答案 0 :(得分:1)

我运行你的例子,我认为模型本身很好。我通过用来自the official Kaggle tutorial的MNIST输入替换你的输入来检查。

在使用MNIST train.array上的训练参数训练模型后,我在MNIST test.array上运行预测并获得良好的结果分布。

如果我使用MNIST训练的模型和你的test_array数据,我仍然可以得到很好的预测分布。

但是,只要我在您随机生成的train_array上训练您的模型并尝试预测test_array或MNIST test.array的结果,我就会对所有项目进行非常相似的预测 - 差异仅在点后第3个数字后开始。

我只能假设网络在白噪声(随机生成的数据)中找不到任何模式。我可以通过设置重量衰减参数(wd)来增大差异,比如wd = 10,但这肯定是一个坏主意。

如果您的输入数据与示例中的输入数据不同,请仔细查看其预处理 - 可能存在错误。