pycharm에서 tensorflow-cpu로 사용하기 위해서는 다음의 코드를 추가해야함(아마 그럴것.. 나는 주피터에서 돌려서)

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

 

 

categorical_crossentropy를 손실함수로 사용했을 때의 (대략적인) CNN 신경망 코드

import tensorflow as tf
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets.fashion_mnist import load_data
from tensorflow.keras.models import Sequential, save_model, load_model
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D

# Fashion-MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape(-1,28,28,1)
x_test = x_test.reshape(-1,28,28,1)

# 원핫인코딩 (one-hot encoding) 처리 (categorical_crossentropy를 사용하기 때문)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# train/valid 분류
from sklearn.model_selection import train_test_split
x_train , x_val , y_train , y_val = train_test_split(x_train, y_train, test_size=0.3,random_state=777)

# 모델 생성
model = Sequential([
  Conv2D(64, kernel_size=(5,5),input_shape=x_train.shape[1:], activation='relu'),
  MaxPooling2D(pool_size=(2, 2), padding='same'),
  Dropout(0.2),
  Flatten(),
  Dense(128, activation='relu'),
  Dense(128, activation='relu'),
  Dense(32, activation='relu'),
  Dropout(0.2),
  Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 모델 학습
hist = model.fit(x_train, y_train, batch_size=100 ,epochs=20, validation_data=(x_val ,y_val))
print(model.evaluate(x_test,  y_test, verbose=1))

# 정확도 시각화
import matplotlib.pyplot as plt
# print(hist.history)

plt.plot(hist.history['accuracy'],'b-', label='training')
plt.plot(hist.history['val_accuracy'],'r:' , label='validation')
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# 손실값 시각화
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# 모델 저장
save_model(model,"c:\\data\\fashion_mnist.h5")

# 모델 불러오기
model2 = load_model("c:\\data\\fashion_mnist.h5")

# test 데이터를 사용해 불러온 모델 성능 평가
result = model2.evaluate(x_test,y_test)
print(dict(zip(model.metrics_names, result)))

# sklearn accuracy_score를 사용하여 모델 정확도 평가
from sklearn.metrics import accuracy_score
print(accuracy_score(model2.predict_classes(x_test), np.argmax(y_test,axis=1)))

 

categorical_crossentropy는 다중 분류 손실함수로 one-hot encoding 클래스를 사용한다. 따라서 출력값이 one-hot encoding된 결과로 나오고 정답(label)과 비교하며 학습을 진행하거나 정확도를 알아내기 위해서는 정답(label)도 one-hot encoding된 형태여야 한다. 따라서 위의 코드 구현에서 정답(y_train, y_test)에 대해 one-hot encoding을 하였다.

 

 

 

sparse_categorical_crossentropy를 손실함수로 사용했을 때의 완전연결신경망 코드

import tensorflow as tf
from tensorflow.keras.datasets.fashion_mnist import load_data
from tensorflow.keras.models import Sequential, save_model, load_model
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D

# Fashion-MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = load_data()

# 데이터 정규화
x_train, x_test = x_train / 255.0, x_test / 255.0

# sparse_categorical_crossentropy를 손실함수로 사용하기 때문에 one-hot encoding 사용 안함



# train 데이터 분리 (train/valid)
from sklearn.model_selection import train_test_split
x_train , x_val , y_train , y_val = train_test_split(x_train, y_train, test_size=0.3,random_state=777)

# 신경망 모델 생성
model = Sequential([
  Flatten(input_shape=(28, 28)),
  Dense(128, activation='relu'),
  Dense(128, activation='relu'),
  Dense(32, activation='relu'),
  Dropout(0.2),
  Dense(10, activation='softmax')
])

# 학습할 때 사용할 옵티마이저, 손실함수, 기준에 대한 정보
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['sparse_categorical_accuracy'])

# 모델 학습
hist = model.fit(x_train, y_train, batch_size=64, epochs=20, validation_data=(x_val ,y_val))

# 학습 시각화
import matplotlib.pyplot as plt
# print(hist.history) # hist에 어떤 데이터가 있는지 확인할 수 있음
plt.plot(hist.history['sparse_categorical_accuracy'],'b-', label='training')
plt.plot(hist.history['val_sparse_categorical_accuracy'],'r:' , label='validation')
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Valid'], loc='upper left')
plt.show()

# 학습 손실 값과 검증 손실 값 시각화
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Valid'], loc='upper left')
plt.show()

# 구현한 model의 파라미터들 h5 파일로 저장
save_model(model, "c:\\data\\fashion_mnist2.h5")

# 모델 성능 평가
model2 = load_model("c:\\data\\fashion_mnist2.h5")
print(model2.evaluate(x_test,y_test,verbose=0))

# sklearn의 accuracy_score를 사용하여 정확도 확인
from sklearn.metrics import accuracy_score
print(accuracy_score(model2.predict_classes(x_test), y_test))

 

sparse_categorical_crossentropy 또한 다중 분류 손실함수로, categorical_crossentropy와 동일하지만 integer type 클래스라는 것이 다르다. 결론적으로 sparse_categorical_crossentropy는 정답(label)이 one-hot encoding 형태가 아니어도 된다.

 

sparse_categorical_crossentropy를 사용해서 모델을 학습시키고 이 학습된 모델을 불러와서 정확도를 측정하기 위해서는 metrics가 sparse_categorical_accuracy여야 한다. 안그러면 불러온 모델로 evaluate을 하면 정확도가 엉망으로 나온다...^^ (이걸로 개고생함) 만약 실수로 metrics를 sparse_categorical_accuracy로 안하고 그냥 accuracy로 했다면 evaluate으로 정확도를 평가하지말고 sklearn의 accuracy_score로 확인해야 제대로 값이 나온다는 것을 추가적으로 꼭꼭 알길 바란다.

 

 

 

h5 파일이 어떻게 구성되어 있는지 확인하는 파이썬 코드

import h5py
filename = "c:\\data\\fashion_mnist.h5"

def read_hdf5(path):

    weights = {}

    keys = []
    with h5py.File(path, 'r') as f: # open file
        f.visit(keys.append) # append all keys to list
        for key in keys:
            if ':' in key: # contains data if ':' in key
                print(f[key].name)
                weights[f[key].name] = f[key].value
    return weights

read_hdf5(filename)

 

 

 

 

 

+

 

 

 

 

 

Keras Callbacks

 

Callbacks - Keras Documentation

Usage of callbacks 콜백은 학습 과정의 특정 단계에서 적용할 함수의 세트입니다. 학습 과정 중 콜백을 사용해서 모델의 내적 상태와 통계자료를 확인 할 수 있습니다. 콜백의 리스트는 (키워드 인수

keras.io

 

추가적으로 모델 학습시, keras의 callback 기능으로 최적의 모델을 만들 수 있다. 이에 대한 부분은 위의 kears 링크를 참고하는 것이 빠르다.

 

from tensorflow.keras.datasets import fashion_mnist

# Fashion_MNIST 데이터 불러오기
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()

import matplotlib.pyplot as plt
import numpy as np

# 정규화, 4차원으로 데이터를 만들어줌
x_train = np.reshape(x_train / 255, (-1, 28, 28, 1))
x_test = np.reshape(x_test / 255, (-1, 28, 28, 1))

from tensorflow.keras.utils import to_categorical
# one-hot encoding
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

from sklearn.model_selection import train_test_split
# train / valid 분리
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size = 0.3, random_state = 777)

print('Fashion-MNIST ready~')

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten

model = Sequential([
    # 항상 모델의 첫 번째 층은 입력의 형태를 명시해주어야함
    Conv2D(filters = 16, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu', input_shape = (28, 28, 1)),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),  
    Conv2D(filters = 32, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu'),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),
    Conv2D(filters = 64, kernel_size = 3, strides = (1, 1), padding = 'same', activation = 'relu'),
    MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'same'),
    Flatten(), # 완전연결층에 들어가기 전 데이터 펼치기
    Dense(64, activation = 'relu'),
    Dense(10, activation = 'softmax') # 10개의 출력을 가지는 신경망
])

model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['acc'])

# kears callbacks 사용
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

filepath = 'c:\\data\\fashion.hdf5'

# ModelCheckpoint : 학습 과정을 모니터링하다가 val_loss가 가장 작을 때 모델의 가중치를 저장
# EarlyStopping : 모니터링하는 평가지표에서 성능 향상이 일어나지 않는 경우
# (patience=5 면 향상이 일어나지 않는 경우 5번까지는 참아줌) 학습 중단
callbacks = [ ModelCheckpoint( filepath = filepath , monitor = 'val_loss' , verbose=1, save_best_only=True ),
            EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')]

model.fit(x_train, y_train, batch_size = 32 , validation_data=(x_val , y_val) , epochs=10, callbacks=callbacks )
model.summary() # 모델의 구조 확인

 

 

 

 

 

wine.csv
0.01MB

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 분류를 위한 nnet 신경망 패키지 설치
install.packages("nnet")
library(nnet)
 
# 이원교차표를 보기 위함
library(gmodels)
 
wine <- read.csv("c:/data/wine.csv",header=T,stringsAsFactors = T)
 
# 확인
head(wine)
str(wine)
 
# scale 함수를 사용한 정규화 (평균 0, 표존편차 1)
wine.scale <- cbind(wine[1], scale(wine[-1]))
summary(wine.scale)
 
size <- nrow(wine.scale) # 178
 
# shuffle
set.seed(100)
index <- c(sample(1:size, size * 0.7))
 
# train(70%) / test(30%)
train <- wine.scale[index, ]
test <- wine.scale[-index, ]
 
# 분류를 위한 신경망 모델 생성
model.nnet2 <- nnet(Type~., data = train, size = 2, decay = 5e-04, maxit = 200)
#                                         number of units in the hidden layer.
#                                                   parameter for weight decay. Default 0. (가중치 감소)
#                                                                  maximum number of iterations. Default 100 (반복)
 
# 분류결과 확인
predicted <- predict(model.nnet2, test, type = "class")
predicted
 
# 모델 평가를 위한 Confusion Matrix
# 참고 : https://yamalab.tistory.com/50
actual <- test$Type
model.confusion.matrix <- table(actual, predicted)
 
# 모델 평가
<- CrossTable(model.confusion.matrix)
x$prop.tbl[1]+x$prop.tbl[5]+x$prop.tbl[9# 0.9444444
 
cs

 

 

 

 

concrete.csv
0.04MB

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 신경망을 이용하여 콘크리트 강도 예측하기
concrete <- read.csv('c:/data/concrete.csv')
 
# 예측하고자 하는 결과가 정규분포를 띄는지 확인한다.
# 만약 정규분포를 띈다면 예측 결과가 좋게 나올 수 있다는 것을 알 수 있다.
hist(concrete$strength)
 
# 결측치 확인
colSums(is.na(concrete))
 
# 정규화 함수
normalize <- function(x) {
  return ( (x-min(x)) / (max(x) - min(x) ) )
}
 
# 데이터 정규화하기
concrete_norm <- as.data.frame(lapply(concrete,normalize))
 
# 0~1 사이로 데이터가 바꼈는지 확인
summary(concrete_norm$strength)
# 기존 데이터와 비교
summary(concrete$strength)
 
# train(75%) / test(27%)
nrow(concrete_norm) * 0.75 # 772.5
concrete_train <- concrete_norm[1:773, ]
concrete_test <- concrete_norm[774:1030, ]
 
# 신경망 패키지 설치
install.packages("neuralnet")
library(neuralnet)
 
# 모델 생성
concrete_model <- neuralnet(formula=strength ~ cement + slag + ash +water +superplastic + coarseagg + fineagg + age,
                            data =concrete_train)
 
# 신경망 모델 시각화
plot(concrete_model)
 
# 예측
model_results <- compute(concrete_model, concrete_test[1:8])
predicted_strength <- model_results$net.result
 
# 상관관계 확인
cor(predicted_strength, concrete_test$strength) # 0.806285848
cs

 

 

시각화

 

 

 

 

 

 

모델 성능 개선

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 모델 성능 개선 은닉층(hidden) 생성
concrete_model2 <- neuralnet(formula=strength ~ cement + slag + ash +
                               water +superplastic + coarseagg + fineagg + age,
                             data =concrete_train , hidden=c(5,2))
 
# 은닉층을 설정해 생성한 신경망 모델 시각화
plot(concrete_model2)
 
# 예측
model_results <- compute(concrete_model2, concrete_test[1:8])
predicted_strength2 <- model_results$net.result
 
# 상관관계 확인
cor(predicted_strength2, concrete_test$strength)
cs

 

hidden=c(5,2) 첫번째 은닉층 5개 / 두번째 은닉층 2개

 

 

 

 

 

 

Perceptron (퍼셉트론)

 

퍼셉트론은 딥러닝에서 사용된다. 이것은 인간의 뉴런을 본 떠 만들었다. 퍼셉트론은 다수의 신호(Input)를 입력받아서 하나의 신호(Output)를 출력한다. 이는 뉴런이 전기신호를 내보내 정보를 전달하는 것과 비슷하게 동작한다. 퍼셉트론의 Weight(가중치)는 뉴런끼리 서로의 신호를 전달하는 것과 같은 역할을 한다.

 

 

 

 

Weight(가중치)는 각각의 입력신호에 부여되어 입력신호와의 계산을 하고 신호의 총합이 정해진 임계값(θ; theta,세타)을 넘었을 때 1을 출력한다. (이를 뉴련의 활성화activation 으로도 표현) 넘지 못하면 0 또는 -1을 출력한다. 결론적으로 우리는 딥러닝을 통해 Weight(가중치)의 값을 조정함으로서 원하는 모델을 만들어내고자 한다.

 

+) 추가적으로 편향(Bias)에 대해 설명하자면 편향은 학습 데이터가 가중치와 계산되어 넘어야 하는 임계점으로, 이 값이 높으면 높을수록 분류의 기준이 엄격하고 낮을수록 한계점이 낮아져 데이터의 허용 범위가 넓어진다. Bias가 높을수록 모델이 간단해지는 경향이 있고 (변수가 적고 일반화됨) 과소적합(Underfitting : 모델이 너무 단순해서 데이터의 내재된 구조를 학습하지 못하는 현상)이 발생할 수 있다. 반대로 편향이 낮을수록 모델이 복잡해지고 오버피팅(Overfitting)이 발생할 수 있으며 필요없는 노이즈가 포함될 가능성이 높아진다.

 

Bias 값이 클 경우 모델이 간단해지는 경향
Underfitting 발생
Bias 값이 작을 경우 모델이 복잡해지는 경향
Overfitting 발생

 

편향에 대한 이러한 내용은 여기를 참고하면 좋은데, 이러한 내용은 편향과 분산의 트레이드오프 관계라고 한다.

(근데 이 트레이드오프가 머신러닝, 특히 회귀 쪽의 개념이기 때문에 이 트레이드오프가 신경망에서도 해당되는지에 대해서는 사실 정확하게 모르겠다... 어차피 신경망의 편향은 학습을 통해 자체적으로 갱신되는 파라미터이기 때문에 노란색 밑줄 정도로만 이해해도 충분하다고 생각한다. 그럼 왜 쓴건데)

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

24.07.06 ChatGPT 내용 추가

과적합(overfitting)은 모델이 학습 데이터에 너무 잘 맞아서, 새로운 데이터(테스트 데이터)에 대해서는 성능이 떨어지는 현상을 말합니다.

모델이 학습 데이터의 노이즈까지 학습해버리면, 일반화(generalization) 능력이 떨어집니다.

 

편향과 분산

  1. 편향 (Bias):
    • 모델이 실제 데이터의 패턴을 단순화해서 나타내는 정도를 의미합니다.
    • 높은 편향: 모델이 지나치게 단순해서 데이터의 복잡한 패턴을 잘 잡아내지 못하는 경우.
    • 예: 선형 회귀 모델이 비선형 데이터에 적합하려 할 때.
  2. 분산 (Variance):
    • 모델이 학습 데이터의 변동에 얼마나 민감하게 반응하는지를 나타냅니다.
    • 높은 분산: 모델이 학습 데이터의 작은 변동에도 지나치게 민감하게 반응하여 과적합되는 경우.
    • 예: 복잡한 다항 회귀 모델이 학습 데이터에 지나치게 잘 맞추는 경우.

 

편향, 분산, 과적합의 상관관계 표

낮은 분산 적절한 모델 미적합 (Underfitting)
높은 분산 과적합 (Overfitting) 적절한 모델

 

  • 낮은 편향 - 낮은 분산: 이상적인 상황으로, 모델이 학습 데이터와 테스트 데이터 모두에서 좋은 성능을 보입니다.
  • 낮은 편향 - 높은 분산: 과적합(overfitting)이 발생하는 상황으로, 모델이 학습 데이터에 너무 잘 맞춰져서 테스트 데이터에서 성능이 떨어집니다.
  • 높은 편향 - 낮은 분산: 미적합(underfitting)이 발생하는 상황으로, 모델이 너무 단순해서 학습 데이터와 테스트 데이터 모두에서 성능이 낮습니다.
  • 높은 편향 - 높은 분산: 이는 드물지만, 모델이 복잡하면서도 데이터의 패턴을 잘 학습하지 못하는 경우입니다. 이 경우 모델이 학습 데이터와 테스트 데이터 모두에서 성능이 낮습니다.

 

예시

  1. 선형 회귀 (높은 편향, 낮은 분산):
    • 선형 회귀 모델은 비선형 데이터에서 높은 편향으로 인해 패턴을 제대로 잡아내지 못합니다. 그러나 분산은 낮아서 데이터 변동에 민감하게 반응하지 않습니다.
  2. 복잡한 다항 회귀 (낮은 편향, 높은 분산):
    • 복잡한 다항 회귀 모델은 낮은 편향으로 인해 데이터의 복잡한 패턴을 잘 잡아내지만, 높은 분산으로 인해 과적합이 발생할 수 있습니다.

 

요약

  • 편향 (Bias): 모델이 단순해서 데이터의 패턴을 잘 잡아내지 못하는 경우.
  • 분산 (Variance): 모델이 학습 데이터의 변동에 민감하게 반응하여 과적합되는 경우.
  • 과적합 (Overfitting): 모델이 학습 데이터에 너무 잘 맞아서 테스트 데이터에서 성능이 떨어지는 현상.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

퍼셉트론은 AND, OR , NAND, XOR 게이트 등으로 구성되어있다. 그냥 디지털논리회로와 비슷하다고 보면 되겠다. 입력값에 따라 원하는 출력값을 만들어내기 위해 이런 저런 단순한 게이트들을 이용하여 원하는 결과를 도출해낸다. 하지만 단층 퍼셉트론은 원하는 결과를 모두 도출해낼 수는 없다. 예를 들어 내가 0부터 9까지 차례대로 나타내는 프로그램을 만든다고 가정하자. 딱 하나의 게이트로는 절대 이런 프로그램을 만들어낼 수 없다. 하지만 여러 개의 게이트를 사용할 수 있다면 어떻게될까? 당연히 가능할 것이다. 이렇게 단층 퍼셉트론으로 불가능한 것을 하기 위해 우리는 다층 퍼셉트론을 사용한다.

 

단층 퍼셉트론을 쉽게 이해할 수 있는 예제가 있는 블로그를 남겨두겠다. 다들 참고하길 바란다.

'인공지능 > 인공지능 이론' 카테고리의 다른 글

15. 항등함수와 Softmax 함수  (2) 2020.08.03
14. 다층퍼셉트론 / Sigmoid / ReLU  (0) 2020.07.01
12. Clustering  (0) 2019.09.13
11. 차원의 저주 / PCA  (0) 2019.09.13
10. ROC Curve  (1) 2019.09.12

+ Recent posts