Getting errors while using neuralnet function

2019-07-11 19:38发布

问题:

I tried neural net in R on Boston data set available.

data("Boston",package="MASS") 
data <- Boston

Retaining only those variable we want to use:

keeps <- c("crim", "indus", "nox", "rm" , "age", "dis", "tax" ,"ptratio", "lstat" ,"medv" ) 
data <- data[keeps]

In this case the formula is stored in an R object called f. The response variable medv is to be “regressed” against the remaining nine attributes. I have done it as below:

f <- medv ~ crim + indus + nox + rm + age + dis + tax + ptratio + lstat

To set up train sample 400 of the 506 rows of data without replacement is collected using the sample method:

set.seed(2016) 
n = nrow(data) 
train <- sample(1:n, 400, FALSE)

neuralnet function of R is fitted.

 fit<- neuralnet(f, data = data[train ,], hidden=c(10 ,12 ,20), 
             algorithm = "rprop+", err.fct = "sse", act.fct = "logistic", 
             threshold =0.1, linear.output=TRUE)

But warning message is displayed as algorithm not converging.

Warning message: algorithm did not converge in 1 of 1 repetition(s) within the stepmax

Tried Prediction using compute,

 pred <- compute(fit,data[-train, 1:9])

Following error msg is displayed

Error in nrow[w] * ncol[w] : non-numeric argument to binary operator
In addition: Warning message:
In is.na(weights) : is.na() applied to non-(list or vector) of type 'NULL'

Why the error is coming up and how to recover from it for prediction. I want to use the neuralnet function on that data set.

回答1:

When neuralnet doesn't converge, the resulting neural network is not complete. You can tell by calling attributes(fit)$names. When training converges, it will look like this:

 [1] "call"                "response"            "covariate"           "model.list"          "err.fct"  
 [6] "act.fct"             "linear.output"       "data"                "net.result"          "weights"  
[11] "startweights"        "generalized.weights" "result.matrix"

When it doesn't, some attributes will not be defined:

[1] "call"          "response"      "covariate"     "model.list"    "err.fct"       "act.fct"       "linear.output"
[8] "data"   

That explains why compute doesn't work.

When training doesn't converge, the first possible solution could be to increase stepmax (default 100000). You can also add lifesign = "full", to get better insight into the training process.

Also, looking at your code, I would say three layers with 10, 12 and 20 neurons is too much. I would start with one layer with the same number of neurons as the number of inputs, in your case 9.

EDIT:

With scaling (remember to scale both training and test data, and to 'de-scale' compute results), it converges much faster. Also note that I reduced the number of layers and neurons, and still lowered the error threshold.

data("Boston",package="MASS") 
data <- Boston

keeps <- c("crim", "indus", "nox", "rm" , "age", "dis", "tax" ,"ptratio", "lstat" ,"medv" ) 
data <- data[keeps]

f <- medv ~ crim + indus + nox + rm + age + dis + tax + ptratio + lstat

set.seed(2016) 
n = nrow(data) 
train <- sample(1:n, 400, FALSE)

# Scale data. Scaling parameters are stored in this matrix for later.
scaledData <- scale(data)

fit<- neuralnet::neuralnet(f, data = scaledData[train ,], hidden=9, 
                algorithm = "rprop+", err.fct = "sse", act.fct = "logistic", 
                threshold = 0.01, linear.output=TRUE, lifesign = "full")

pred <- neuralnet::compute(fit,scaledData[-train, 1:9])

scaledResults <- pred$net.result * attr(scaledData, "scaled:scale")["medv"] 
                                 + attr(scaledData, "scaled:center")["medv"]

cleanOutput <- data.frame(Actual = data$medv[-train], 
                          Prediction = scaledResults, 
                          diff = abs(scaledResults - data$medv[-train]))

# Show some results
summary(cleanOutput)


回答2:

The problem seems to be in your argument linear.output = TRUE.

With your data, but changing the code a bit (not defining the formula and adding some explanatory comments):

library(neuralnet)               
fit <- neuralnet(formula = medv ~ crim + indus + nox + rm + age + dis + tax + ptratio + lstat,
                 data = data[train,],
                 hidden=c(10, 12, 20),   # number of vertices (neurons) in each hidden layer
                 algorithm = "rprop+",   # resilient backprop with weight backtracking,
                 err.fct = "sse",        # calculates error based on the sum of squared errors
                 act.fct = "logistic",  # smoothing the cross product of neurons and weights with logistic function
                 threshold = 0.1,        # of the partial derivatives for error function, stopping
                 linear.output=FALSE)     # act.fct applied to output neurons

print(net)

Call: neuralnet(formula = medv ~ crim + indus + nox + rm + age + dis +     tax + ptratio + lstat, data = data[train, ], hidden = c(10,     12, 20), threshold = 0.1, rep = 10, algorithm = "rprop+",     err.fct = "sse", act.fct = "logistic", linear.output = FALSE)

10 repetitions were calculated.

         Error Reached Threshold Steps
1  108955.0318     0.03436116236     4
5  108955.0339     0.01391790099     8
3  108955.0341     0.02193379592     3
9  108955.0371     0.01705056758     6
8  108955.0398     0.01983134293     8
4  108955.0450     0.02500006437     5
6  108955.0569     0.03689097762     5
7  108955.0677     0.04765829189     5
2  108955.0705     0.05052776877     5
10 108955.1103     0.09031966778     7
10 108955.1103     0.09031966778     7

# now compute will work
pred <- compute(fit, data[-train, 1:9])