from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
import numpy as np
import tensorflow as tf
from pandas import read_csv
np.random.seed(3)
tf.random.set_seed(3)
target = 'https://raw.githubusercontent.com/gilbutITbook/006958/master/deeplearning/dataset/ThoraricSurgery.csv'
dataframe = read_csv(target, engine='python').values
X = dataframe[:,0:17]
Y = dataframe[:,17]
model = Sequential()
model.add(Dense(30, input_dim=17, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(X,Y,epochs=100,batch_size=10)
model = Sequential()
: 모델 생성model.add(Dense())
: 모델 내부 계층 구성model.compile()
: 모델 컴파일(컴퓨터가 인식가능하게 컴파일)model.fit()
: 모델 실행(학습)model = Sequential()
model.add(Dense(30, input_dim=17, activation='relu'))
model.add(Dense(1, activation='sigmoid')) # 2개의 층으로 구성됨
Sequential()
: 입력층, 은닉층, 출력층을 순차적으로 구성할 수 있는 모델 객체model.add()
: model을 추가하고 add를 통해 라인을 추가하면 새로운 층 구성됨Dense()
: 가중합과 활성화 함수 동작을 담당하는 계층(노드) ➡️ 입력층, 은닉층, 출력층과 같이 신경망 모델의 각 계층의 기능을 수행하는 클래스Dense(30)
: 해당 층에 30개의 노드를 만들겠다Dense(30, input_dim=17)
: 데이터에서 17개의 값을 받아 은닉층의 30개의 노드로 보냄activation
: 활성화 함수model.add(Dense(1, activation='sigmoid'))
: 출력층의 결과는 1개이므로 노드 개수 1.model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
loss='mean_squared_error'
: 오차함수 지정(평균제곱오차 : 수렴하기까지 속도가 많이 걸림) ➡️ 교차 엔트로피 계열 함수optimizer='adam'
: 최적화방법, W는 각 층별의 가중치w의 집합metrics=['accuracy']
: 모델이 컴파일될 때 모델 수행 결과를 나타나게 함
- 평균제곱계열
- 1️⃣ mean_squared_error(평균 제곱 오차) : mean(square(yt - yo)
- yt: 실제값, yo : 예측값
- 2️⃣ mean_absolute_error(평균 절대 오차) : mean(abs(yt - yo)
- 실제값과 예측값 간 차이의 절대값 평균
- 3️⃣ mean_absolute_percentage_error(평균 절대 백분율 오차) : mean(abs(yt-yo)/abs(yt))
- 절대값 오차를 절댓값으로 나눈 후 평균
- 4️⃣ mean_squared_logarithmic_error(평균 제곱 로그 오차) : mean(square((log(yo)+1) - log(yt)+1)))
- 실제 값과 예측 값에 로그를 적용한 값의 차이를 제곱한 값의 평균
- 교차 엔트로피 계열
- 1️⃣ categorical_crossentropy(범주형 교차 엔트로피) : 일반형 분류
- 2️⃣ binary_crossentropy(이항 교차 엔트로피) : 두 개의 클래스 중에서 예측
model.fit(X,Y,epochs=100,batch_size=10)
데이터 형태
- 데이터 : 470개의 환자에게서 17개의 정보 정리
- 정보 = 속성
- 생존여부 = 클래스
- 각 환자의 정보 = 샘플
import pandas as pd
df = pd.read_csv('pima-indians-diabetes.csv', names = ['pregnant', 'plasma', 'pressure', 'thickness', 'insulin', 'BMI', 'pedigree', 'age', 'class'])
df.head(5)
df.info()
df.describe()
df.
pd.read_csv()
: csv 데이터 불러오기. df.head(5)
: 데이터의 첫 다섯 줄 불러오기df.info()
: 데이터의 전반적인 정보 추출df.describe()
: 정보별 특징 ➡️ 정보별 샘플 수(count), 평균(mean), 표준편차(std), 최솟값(min), 백분위 수로 25%, 50%, 75%에 해당하는 값 그리고 최댓값(max)이 정리df[['pregnant', 'class']]
: 데이터 일부 컬럼만 추출df[['pregnant', 'class']].groupby(['pregnant'], as_index=False).mean().sort_values(by='pregnant', ascending=True)
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize = (12,12))
sns.heatmap(df.corr(), linewidths=0.1, vmax=0.5, cmap=plt.cm.gist_heat, linecolor='white', annot=True)
plt.show()
➡️ class 항목은 pregnant ~ age까지의 상관도를 숫자로 나타냄 : plasma가 가장 연관성이 높음을 확인 가능
plt.figure(figsize = (12,12))
: 그래프 크기 결정sns.heatmap()
: 두 항목씩 짝 지은 후 각각 어떤 패턴으로 변화하는지 관찰하는 함수 ➡️ 전혀 다른 패턴으로 변화 시 0, 서로 비슷한 패턴으로 변화 시 1로 가까워짐grid = sns.FacetGrid(df, col='class')
grid.map(plt.hist, 'plasma', bins=10)
plt.show()
➡️ 가장 연관성이 높은 plasma와 class 항목의 관계도만 따로 그래프로 표현
seed 설정
np.random.seed(seed) tf.random.set_seed(seed)
- random() : 컴퓨터 내 내장된 랜덤 테이블 중 하나를 표로 보여줌
- seed : 랜덤 테이블 어떤 것을 불러올 것인지 결정 ➡️ seed값이 같으면 똑같은 랜덤 값 출력
✔️ 일정한 결과값을 얻기 위해서는 넘파이 seed값과 텐서플로 seed값 모두 설정해야 함
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
import numpy as np
import tensorflow as tf
np.random.seed(3)
tf.random.set_seed(3)
dataset = np.loadtxt('pima-indians-diabetes.csv', delimiter=",")
X = dataset[:, 0:8]
Y = dataset[:, 8]
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X,Y,epochs=200,batch_size=10)
print("\n Accuracy: %.4f" % (model.evaluate(X, Y)[1]))
- 다중분류 : 여러 개의 답 중 하나 고르는 분류
- 이진분류(이항분류)와는 다르게 활성화 함수를 softmax로 사용
- 샘플 수 : 150
- 속성 : 4
- 정보 1 : 꽃받침 길이 (sepal length, 단위: cm)
- 정보 2 : 꽃받침 너비 (sepal width, 단위: cm)
- 정보 3 : 꽃잎 길이 (petal length, 단위: cm)
- 정보 4 : 꽃잎 너비 (petal width, 단위: cm)
- 클래스 : Iris-setosa, Iris-versicolor, Iris-virginica
import pandas as pd
df = pd.read_csv('iris.csv')
df.head()
import seaborn as sns
import matplotlib.pyplot as plt
sns.pairplot(df, hue='Species')
plt.show()
dataset = df.values
X = dataset[:, :4].astype(float)
Y_obj = dataset[:, 4]
from sklearn.preprocessing import LabelEncoder
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
LabelEncoder()
: 문자열을 숫자로 바꿔주려면 클래스 이름을 숫자 형태로 바꿔주면 됨from tensorflow.keras import utils
import tensorflow as tf
Y_encoded = tf.keras.utils.to_categorical(Y)
to_categorical(Y)
: 여러 개의 Y값을 0과 1로만 이루어진 형태로 변경해줌(원핫인코딩)from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential()
model.add(Dense(16, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))
- 소프트맥스 함수 원리
- 총합이 1인 형태로 바꾸어서 계산해주는 함수
- 합계를 1로 바꾸면 큰 값이 더 두드러지게 나타나고 작은 값은 더 작아짐
- 교차 엔트로피를 지나 [1, 0, 0], 즉, 하나만 1이고 나머지는 0인 원-핫 인코딩 값으로 변하게 됨
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.preprocessing import LabelEncoder
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
# seed 값 설정
np.random.seed(3)
tf.random.set_seed(3)
# 데이터 입력
df = pd.read_csv('iris.csv')
# 데이터 분류
dataset = df.values
X = dataset[:,:-1].astype(float)
Y_obj = dataset[:,-1]
print(X)
# 문자열을 숫자로 변환
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
Y_encoded = tf.keras.utils.to_categorical(Y)
print(Y_encoded)
# 모델의 설정
model = Sequential()
model.add(Dense(16, input_dim=5, activation='relu'))
model.add(Dense(3, activation='softmax'))
# 모델 컴파일
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 모델 실행
model.fit(X, Y_encoded, epochs=50, batch_size=1)
# 결과 출력
print('\n Accuracy: %.4f' % (model.evaluate(X, Y_encoded)[1]))
import pandas as pd
df = pd.read_csv('sonar.csv', header=None)
df.info()
from keras.models import Sequential
from keras.layers.core import Dense
from sklearn.preprocessing import LabelEncoder
import pandas as pd
import numpy as np
import tensorflow as tf
np.random.seed(3)
tf.random.set_seed(3)
df = pd.read_csv('sonar.csv', header=None)
dataset = df.values
X = dataset[:, :60]
Y_obj = dataset[:, 60]
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
model = Sequential()
model.add(Dense(24, input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(X, Y, epochs=200, batch_size=5)
print("\n Accuracy: %.4f" % (model.evaluate(X, Y)[1]))
➡️ 정확도 : 100% 나옴 why???
- 과적합(overfitting)
- 모델이 학습 데이터셋 안에서는 일정 수준 이상의 예측 정확도를 보이지만, 새로운 데이터에 적용하면 잘 맞지 않음
- 새로운 데이터에 적용하면 해당 선을 이용해서 정확히 두 그룹으로 나누지 못함
- 너무 층이 많거나 변수가 복잡해서 발생 / 테스트셋과 학습셋이 중복될 때 발생하기도 함
- 학습데이터셋과 테스트데이터셋을 완전히 구분한 다음 학습과 동시에 테스트 병행하는 방법
- 모델 : 학습데이터로 학습을 진행 후 학습 결과 저장
- 모델은 다른 셋에 적용할 경우 학습 단계에서 각인된 그대로 동작함
➡️ 테스트셋으로 정확도를 측정해 학습률 확인- 이후 좋은 모델이 만들어졌다면 실생활에 대입
- 학습셋만 가지고 평가할 경우
- 층을 더하거나 에포크 값을 높여 실행 횟수를 높이면 정확도 올라감
- 학습이 깊어져 학습셋 내부의 성공률은 높아져도 테스트셋에는 효과 없음 ➡️ 과적합
- 학습을 진행해도 테스트 결과가 좋아지지 않는 지점에서 학습 중단
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=3)
model = Sequential()
model.add(Dense(24, input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=130, batch_size=5)
model.evaluate(X_test, Y_test)[1]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=3)
: 테스트 셋의 비율은 전체 데이터의 30%from keras.models import Sequential, load_model
model.save('my_model.h5')#모델 컴퓨터에 저장
del model #모델 삭제
model = load_model('my_model.h5') #모델 불러오기
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, Y_test)[1]))
- 데이터셋을 여러개로 나누어 하나씩 테스트셋으로 사용하고 나머지를 모두 합하여 학습셋으로 사용하는 방법
- 데이터를 100% 테스트셋으로 사용 가능함
ex) 5겹 교차 검증(5-fold cross validation)
from keras.models import Sequential
from keras.layers.core import Dense
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
import numpy
import pandas as pd
import tensorflow as tf
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(seed)
df = pd.read_csv('sonar.csv', header=None)
dataset = df.values
X = dataset[:,0:60]
Y_obj = dataset[:,60]
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
n = 10
skf = StratifiedKFold(n_splits=n, shuffle=True, random_state=seed)
accuracy = []
# 빈 accuracy 배열
accuracy = []
# 모델의 설정, 컴파일, 실행
for train, test in skf.split(X, Y):
model = Sequential()
model.add(Dense(24, input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(X[train], Y[train], epochs=100, batch_size=5)
k_accuracy = "%.4f" % (model.evaluate(X[test], Y[test])[1])
accuracy.append(k_accuracy)
print("\n %.f fold accuracy:" % n, accuracy)
# 10 fold accuracy: ['0.7143', '0.9048', '0.7619', '0.9048', '0.8095', '0.8571', '0.8571', '0.8571', '0.9500', '0.8500']
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.model_selection import train_test_split
seed = 1234
df = pd.read_csv('../data/wine.csv', header=None)
df = df.sample(frac=1)
df_values = df.values
X = df_values[:, :-1].astype(float)
Y = df_values[:, -1]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=seed)
model = Sequential()
model.add(Dense(30, input_dim=12, activation='relu'))
model.add(Dense(12, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=200, batch_size=10)
result = model.evaluate(X_test, Y_test, verbose=0)
print(result)
#[0.06677131354808807, 0.9753845930099487]
- save() : 모델 저장
- load_model() : 모델 재사용
import os.path
folderpath = '../data/model/' # 모델 저장하는 폴더
if not os.path.exists(folderpath): # 위 폴더가 존재하지 않는다면
os.mkdir(folderpath) # 해당 폴더를 만듦
from tensorflow.keras.callbacks import ModelCheckpoint
modelname="{epoch:02d}-{val_loss:.4f}.hdf5" #에포크 횟수와 테스트 오차값을 이용해 파일 이름 생성하기
modelpath = folderpath + modelname
checkpointer = ModelCheckpoint(
filepath=modelpath,
monitor='val_loss',
verbose=1,
save_best_only=True)
model.fit(X, Y, validation_split=0.2, epochs=200, batch_size=200, verbose=0, callbacks=[checkpointer])
epoch_loop = 2000
batch_cnt = 300
history = model.fit(X, Y, validation_split=0.33, epochs=epoch_loop, batch_size=batch_cnt)
import numpy as np
import matplotlib.pyplot as plt
x_len = np.arange(epoch_loop)
plt.plot(x_len, history.history['val_loss']) # 테스트셋으로 실험 결과의 오차값 저장
plt.plot(x_len, history.history['accuracy']) # 학습셋으로 측정한 정확도 값 저장
plt.show()
from tensorflow.keras.callbacks import EarlyStopping
es_callback = EarlyStopping(monitor='val_loss', patience=100)
history = model.fit(X, Y, validation_split=0.2, epochs=200, batch_size=200, verbose=0,
callbacks=[checkpointer, es_callback])
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
import numpy
import pandas as pd
import tensorflow as tf
df = pd.read_csv('housing.csv', delim_whitespace=True, header=None)
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(3)
dataset = df.values
X = dataset[:,0:13]
Y = dataset[:,13]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=seed)
model = Sequential()
model.add(Dense(30, input_dim=13, activation='relu'))
model.add(Dense(6, activation='relu'))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(X_train, Y_train, epochs=200, batch_size=10)
Y_pred = model.predict(X_test).flatten()
for i in range(10):
label = Y_test[i]
pred = Y_pred[i]
print("실제가격: {:.3f}, 예상가격: {:.3f}".format(label, pred))