2017-02-21 11 views
0

두 개의 코드가 동일한 모델을 생성하지 않는 이유를 실제로 이해하려고합니다. 첫 번째 신경망 (NN1)을 만들기 위해 Caret 패키지의 train 함수에서 교차 유효성 검사 (아래 코드)를 사용하여 최상의 매개 변수를 찾습니다. package's vignette의 2 페이지는 "최적의 매개 변수 세트를 사용하여 모든 학습 데이터에 최종 모델을 맞추기"를 제안합니다.Caret에서 생산 된 모델이 왜 동일하지 않습니까?

그래서 아래 코드에서 NN1은 크기가 5이고 부패가 0.1 인 최상의 매개 변수를 가진 전체 교육 세트를 반영 할 것으로 기대합니다.

내 계획은이 단계의 매개 변수를 사용하여 결합 된 교육 및 테스트 데이터를 사용하여 생산에 투입 할 모델을 만드는 것이 었습니다. 이 프로덕션 모델을 만들기 전에 train의 출력을 제대로 사용하고 있는지 확인하려고했습니다.

그래서 열차 기능이있는 두 번째 모델 (NN2)을 만들었지 만 without tuning. 대신 매개 변수 size = 5 및 decay = 0.1을 지정했습니다. 동일한 데이터, 동일한 매개 변수 (및 동일한 시드)로 동일한 모델을 기대했지만 그렇지 않았습니다. 왜이 모델들은 동일하지 않습니까? 여기

# Create some data 
library(caret) 
set.seed(2) 
xy<-data.frame(Response=factor(sample(c("Y","N"),534,replace = TRUE,prob=c(0.5,0.5))), 
       GradeGroup=factor(sample(c("G1","G2","G3"),534,replace=TRUE,prob=c(0.4,0.3,0.3))), 
       Sibling=sample(c(TRUE,FALSE),534,replace=TRUE,prob=c(0.3,0.7)), 
       Dist=rnorm(534)) 

xyTrain <- xy[1:360,] 
xyTest <- xy[361:534,] 

# Create NN1 using cross-validation 
tc <- trainControl(method="cv", number = 10, savePredictions = TRUE, classProbs = TRUE) 
set.seed(2) 
NN1 <- train(Response~.,data=xyTrain, 
      method="nnet", 
      trControl=tc, 
      verbose=FALSE, 
      metric="Accuracy") 

# Create NN2 using parameters from NN1 
fitControl <- trainControl(method="none", classProbs = TRUE) 
set.seed(2) 
NN2 <- train(Response~.,data=xyTrain, 
      method="nnet", 
      trControl=fitControl, 
      verbose=FALSE, 
      tuneGrid=data.frame(size=NN1$bestTune[[1]],decay=NN1$bestTune[[2]]), 
      metric="Accuracy") 

는 결과이다

> # Parameters of NN1 
> NN1$bestTune 
    size decay 
1 1  0 
> 
> # Code to show results of NN1 and NN2 differ 
> testFitted <- data.frame(fitNN1=NN1$finalModel$fitted.values, 
+       fitNN2=NN2$finalModel$fitted.values) 
> 
> testPred<-data.frame(predNN1=predict(NN1,xyTest,type="prob")$Y, 
+      predNN2=predict(NN2,xyTest,type="prob")$Y) 
> # Fitted values are different 
> head(testFitted) 
     fitNN1 fitNN2 
X1 0.4824096 0.4834579 
X2 0.4673498 0.4705441 
X3 0.4509407 0.4498603 
X4 0.4510129 0.4498710 
X5 0.4690963 0.4753655 
X6 0.4509160 0.4498539 
> # Predictions on test set are different 
> head(testPred) 
    predNN1 predNN2 
1 0.4763952 0.4784981 
2 0.4509160 0.4498539 
3 0.5281298 0.5276355 
4 0.4512930 0.4498993 
5 0.4741959 0.4804776 
6 0.4509335 0.4498589 
> 
> # Accuracy of predictions are different 
> sum(predict(NN1,xyTest,type="raw")==xyTest$Response)/nrow(xyTest) 
[1] 0.4655172 
> sum(predict(NN2,xyTest,type="raw")==xyTest$Response)/nrow(xyTest) 
[1] 0.4597701 
> 
> # Summary of models 
> summary(NN1) 
a 4-1-1 network with 7 weights 
options were - entropy fitting 
b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
-8.38 6.58 5.51 -9.50 1.06 
b->o h1->o 
-0.20 1.39 
> summary(NN2) 
a 4-1-1 network with 7 weights 
options were - entropy fitting 
b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
10.94 -8.27 -7.36 8.50 -0.76 
b->o h1->o 
3.15 -3.35 

답변

1

나는이 임의의 씨앗과 관련이있다 생각합니다. 교차 유효성 검사를 수행 할 때 시작 시드 (set.seed(2))의 많은 모델을 피팅합니다. 최종 모델은 동일한 매개 변수에 맞지만 최종 모델이 교차 유효성 검사 안에 들어있는 시드는 사용자가 직접 매개 변수를 사용하여 최종 모델을 맞추려고 할 때와 동일하지 않습니다. 매 뉴얼 네트워크 호출 (nnet)의 가중치가 매번 무작위로 생성되기 때문에 여기에서 확인하십시오.

+0

이 의미가 있습니다. nnet 패키지의 'Wts' 매개 변수는 초기 매개 변수 벡터입니다. 그것이 누락되면 그것은 무작위로 선택됩니다. 케럿에서 nnet 함수의 시드를 설정하는 방법이 있습니까? 나는 신경망에 대한 전문가가 아니며 초기 가중치 (몇 가지, 어떤 값의 범위)를 지정해야하는지 거의 알지 못합니다. 이 [게시물] (http://stackoverflow.com/questions/13773275/specifying-initial-weights-for-nnet-in-r-programming-neural-network) 아이디어를 제공하는 것 같다. 아마도 Caret를 통해 nnet에 초기 가중치를 전달할 수 있습니다. – rmacey

+0

'Wts' 매개 변수를'train' 함수에 직접 전달할 수 있다고 생각합니다. 그러나 항상 동일한 가중치를 사용하는 것에 대해서는주의해야합니다. 나는 일어나고있는 일을 너 자신에게 증명하기 위해서만 이것을 할 것이다. – cdeterman