# 인공신경망
# 인공신경망에서 학습이라는 결국 가중치를 업데이트것입니다
# 가중치=중요도를 의미합니다

# install.packages("NeuralNetTools")

# install.packages("nnet")

library(nnet)   # 신경망 학습
library(NeuralNetTools)   # 시각화 도구
library(ggplot2)  # 시각화

# 2. 데이터 준비
data(iris)
iris$Species <- as.factor(iris$Species)


# 3. 모델 학습
set.seed(123)
model_ann <- nnet(Species ~ ., 
                  data = iris, 
                  size = 5,        # 은닉 노드 5개
                  decay = 0.01,    # 가중치 감소
                  maxit = 200)     # 반복 횟수
## # weights:  43
## initial  value 230.660979 
## iter  10 value 45.785846
## iter  20 value 12.827392
## iter  30 value 11.256300
## iter  40 value 9.650528
## iter  50 value 9.291849
## iter  60 value 9.136495
## iter  70 value 9.103158
## iter  80 value 9.050192
## iter  90 value 9.019544
## iter 100 value 9.000070
## iter 110 value 8.986564
## iter 120 value 8.980150
## iter 130 value 8.976378
## iter 140 value 8.975640
## iter 150 value 8.975430
## iter 160 value 8.975414
## final  value 8.975413 
## converged
# 은닉층 노드 수
# 은닉 노드 수가 많을수록 복잡한 패턴 학습 가능
# 너무 크면 과적합(overfitting) 위험
# 가중치 감소율 (L2 정규화)
# 값이 클수록 모델이 단순해짐 (가중치가 0에 가까워짐)
# 너무 작으면 과적합 위험, 너무 크면 과소적합 가능

# maxit = 200 : 최대 반복(Epoch) 수
# 충분한 반복이 필요하나, 너무 크면 수렴 속도 느려질 수 있음


# 4. 모델 요약
summary(model_ann)
## a 4-5-3 network with 43 weights
## options were - softmax modelling  decay=0.01
##  b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
##  -1.48  -1.41   3.00   0.49   0.49 
##  b->h2 i1->h2 i2->h2 i3->h2 i4->h2 
##   5.51   0.16   1.68  -1.15  -3.33 
##  b->h3 i1->h3 i2->h3 i3->h3 i4->h3 
##   0.31   0.53   1.15  -2.16  -0.97 
##  b->h4 i1->h4 i2->h4 i3->h4 i4->h4 
##  -3.71  -1.00  -1.92   2.42   2.40 
##  b->h5 i1->h5 i2->h5 i3->h5 i4->h5 
##  -0.30  -0.53  -1.14   2.16   0.97 
##  b->o1 h1->o1 h2->o1 h3->o1 h4->o1 h5->o1 
##   0.15   0.33   1.27   3.88  -1.44  -3.72 
##  b->o2 h1->o2 h2->o2 h3->o2 h4->o2 h5->o2 
##  -0.02  -2.56   4.40  -3.57  -3.29   3.55 
##  b->o3 h1->o3 h2->o3 h3->o3 h4->o3 h5->o3 
##  -0.14   2.23  -5.67  -0.31   4.74   0.17
#  4-5-3 network with 43 weights
# 4개의 입력 노드, 5개의 은닉 노드, 3개의 출력 노드 (클래스가 3개라서)
# 43 weights : 가중치(weight)와 바이어스(bias)의 총합
# 역전파로 업데이트되는 모든 파라미터 수가 43개라는 의미입니다
# softmax modelling 다중 클래스 분류용 softmax 함수 사용

# 5. 신경망 구조 시각화
plotnet(model_ann)

# plotnet(model_ann) 그림에서 나타나는 간선(edge) 하나하나는 
# 결국 모델 내 학습되는 가중치(weight)를 의미합니다.
# 입력 → 은닉(4입력 + 1바이어스) × 5 은닉 노드=25개
# 은닉 → 출력   (5 은닉 + 1바이어스) × 3 출력 노드    18개

# 가중치와 편향 확인
# 1. 입력값 정의 (예: 3개의 입력)
inputs <- c(2.0, 1.5, 0.5)

# 2. 가중치 정의
weights <- c(0.4, -0.7, 0.2)

# 3. 바이어스 (bias)
bias <- 0.1

# 4. 가중합 계산: Σ(x * w) + b
weighted_sum <- sum(inputs * weights) + bias
weighted_sum
## [1] -0.05
# 5. 활성화 함수 적용 (예: sigmoid 함수)
sigmoid <- function(x) {
  1 / (1 + exp(-x))
}

output <- sigmoid(weighted_sum)
output
## [1] 0.4875026