我正在使用neuralnet
程序包R
預測手寫數字。正在使用MNIST database進行該算法的訓練和測試。下面是R
代碼我使用:在R中使用'neuralnet'時出現意外輸出
# Importing the data into R
path <- "path_to_data_folder/MNIST_database_of_handwritten_digits/" # Data can be downloaded from: http://yann.lecun.com/exdb/mnist/
to.read = file(paste0(path, "train-images-idx3-ubyte"), "rb")
to.read_Label = file(paste0(path, "train-labels-idx1-ubyte"), "rb")
magicNumber <- readBin(to.read, integer(), n=1, endian="big")
magicNumber_Label <- readBin(to.read_Label, integer(), n=1, endian="big")
numberOfImages <- readBin(to.read, integer(), n=1, endian="big")
numberOfImages_Label <- readBin(to.read_Label, integer(), n=1, endian="big")
rowPixels <- readBin(to.read, integer(), n=1, endian="big")
columnPixels <- readBin(to.read, integer(), n=1, endian="big")
# image(1:rowPixels, 1:columnPixels, matrix(readBin(to.read, integer(), n=(rowPixels*columnPixels), size=1, endian="big"), rowPixels, columnPixels)[,columnPixels:1], col=gray((0:255)/255))
trainDigits <- NULL
trainDigits <- vector(mode="list", length=numberOfImages)
for(i in 1:numberOfImages)
trainDigits[[i]] <- as.vector(matrix(readBin(to.read, integer(), n=(rowPixels*columnPixels), size=1, endian="big"), rowPixels, columnPixels)[,columnPixels:1])
trainDigits <- t(data.frame(trainDigits)) # Takes a minute
trainDigits <- data.frame(trainDigits, row.names=NULL)
# i <- 1 # Specify the image number to visualize the image
# image(1:rowPixels, 1:columnPixels, matrix(trainDigits[i,], rowPixels, columnPixels), col=gray((0:255)/255))
trainDigits_Label <- NULL
for(i in 1:numberOfImages_Label)
trainDigits_Label <- c(trainDigits_Label, readBin(to.read_Label, integer(), n=1, size=1, endian="big"))
# appending the labels to the training data
trainDigits <- cbind(trainDigits, trainDigits_Label)
#################### Modelling ####################
library(neuralnet)
# Considering only 500 rows for training due to time and memory constraints
myNnet <- neuralnet(formula = as.formula(paste0("trainDigits_Label ~ ", paste0("X",1:(ncol(trainDigits)-1), collapse="+"))),
data = trainDigits[1:500,], hidden = 10, algorithm='rprop+', learningrate=0.01)
#################### Test Data ####################
to.read_test = file(paste0(path, "t10k-images-idx3-ubyte"), "rb")
to.read_Label_test = file(paste0(path, "t10k-labels-idx1-ubyte"), "rb")
magicNumber <- readBin(to.read_test, integer(), n=1, endian="big")
magicNumber_Label <- readBin(to.read_Label_test, integer(), n=1, endian="big")
numberOfImages_test <- readBin(to.read_test, integer(), n=1, endian="big")
numberOfImages_Label_test <- readBin(to.read_Label_test, integer(), n=1, endian="big")
rowPixels <- readBin(to.read_test, integer(), n=1, endian="big")
columnPixels <- readBin(to.read_test, integer(), n=1, endian="big")
testDigits <- NULL
testDigits <- vector(mode="list", length=numberOfImages_test)
for(i in 1:numberOfImages_test)
testDigits[[i]] <- as.vector(matrix(readBin(to.read_test, integer(), n=(rowPixels*columnPixels), size=1, endian="big"), rowPixels, columnPixels)[,columnPixels:1])
testDigits <- t(data.frame(testDigits)) # Takes a minute
testDigits <- data.frame(testDigits, row.names=NULL)
testDigits_Label <- NULL
for(i in 1:numberOfImages_Label_test)
testDigits_Label <- c(testDigits_Label, readBin(to.read_Label_test, integer(), n=1, size=1, endian="big"))
#################### 'neuralnet' Predictions ####################
predictOut <- compute(myNnet, testDigits)
table(round(predictOut$net.result), testDigits_Label)
#################### Random Forest ####################
# Cross-validating NN results with Random Forest
library(randomForest)
myRF <- randomForest(x=trainDigits[,-ncol(trainDigits)], y=as.factor(trainDigits_Label), ntree=100)
predRF <- predict(myRF, newdata=testDigits)
table(predRF, testDigits_Label) # Confusion Matrix
sum(diag(table(predRF, testDigits_Label)))/sum(table(predRF, testDigits_Label)) # % of correct predictions
有60000幅訓練圖像(28倍* 28像素的圖像)以及0到9的分佈(幾乎)間的整個數據集相等的數字。與上面僅使用500個圖像的'建模'部分不同,我使用整個訓練數據集來訓練一個myNnet
模型(28 * 28 = 784個輸入和10個輸出),然後預測測試數據集中10,000個圖像的輸出。 (由於內存限制,我在隱藏層中只使用了10個神經元)。
我用預測獲得的結果很奇怪:輸出是一種高斯分佈,其中大部分時間是預測4, 4中的0或9減少(種類)成指數。你可以看到下面的混淆矩陣(我四捨五入的輸出,因爲他們不是整數):
> table(round(predictOut$net.result), testDigits_Label)
testDigits_Label
0 1 2 3 4 5 6 7 8 9
-2 1 1 4 1 1 3 0 4 1 2
-1 8 17 12 9 7 8 8 12 7 10
0 38 50 44 45 35 28 36 40 30 39
1 77 105 86 80 71 69 68 75 67 77
2 116 163 126 129 101 97 111 101 99 117
3 159 205 196 174 142 140 153 159 168 130
4 216 223 212 183 178 170 177 169 181 196
5 159 188 150 183 183 157 174 176 172 155
6 119 111 129 125 143 124 144 147 129 149
7 59 53 52 60 74 52 51 91 76 77
8 22 14 18 14 32 36 28 38 35 41
9 6 5 3 7 15 8 8 16 9 16
我想一定有什麼錯我的做法,所以我使用randomForest
包R
試圖預測。但是,randomForest
工作正常,給出了超過95%的準確性。這裏是randomForest
預測的混淆矩陣:
> table(predRF, testDigits_Label)
testDigits_Label
predRF 0 1 2 3 4 5 6 7 8 9
0 967 0 6 1 1 7 11 2 5 5
1 0 1123 0 0 0 1 3 7 0 5
2 1 2 974 9 3 1 3 25 4 2
3 0 3 5 963 0 21 0 0 9 10
4 0 0 12 0 940 1 4 2 7 15
5 4 0 2 16 0 832 6 0 11 4
6 6 5 5 0 7 11 929 0 3 2
7 1 1 14 7 2 2 0 979 4 6
8 1 1 12 7 5 11 2 1 917 10
9 0 0 2 7 24 5 0 12 14 950
問題1:那麼,爲什麼有這個數據集的這種奇怪的行爲
neuralnet
誰能請解釋一下嗎? (順便說一句,當我檢查時,neuralnet
與iris
數據集正常工作)。- 編輯:我想我明白當使用
neuralnet
爲高斯樣的輸出分佈的原因。當使用neuralnet
時,每個輸出類(這裏有10個類)只有一個輸出節點(或者它是神經元?)而不是節點。因此,在計算用於反向傳播的delta delta時,該算法計算'期望輸出'與'計算輸出'之間的差異,對於所有實例的聚合,對於輸出爲4或5. 因此,權重將在反向傳播過程中進行調整,以使輸出誤差最小化。這可能是由neuralnet
給出的高斯類型輸出的原因。
- 編輯:我想我明白當使用
問題2:同時,我想知道如何糾正的
neuralnet
此行爲,並獲得與randomForest
結果看齊預測。
見[此示例](http://www.parallelr.com/r-dnn-並行加速度/)DNN的本地R與MNIST數據集。 – Patric