💡머신러닝 vs 딥러닝
머신러닝 : 인간이 직접 특징을 도출할 수 있게 설계해서 예측값 출력
딥러닝 : 인공지능 스스로 일정 범주의 데이터를 바탕으로 공통된 특징을 도출하고, 그 특징으로 예측값 출력
🤔28x28 픽셀 이미지로 학습을 하는데 왜 입력에 784개가 들어갈까?
🤔Fully Connected Network 에는 1차원형태로 네트워크에 데이터를 주입해야 하는데 어떻게 비정형 데이터(표형태가 아니라 이미지, 음성, 텍스트 등)를 잘 다룰까?
🤔활성함수로 sigmoid 의 단점은?
🤔dropout이란?
기울기 소실은 역전파 과정에서 발생하는 문제. 역전파도 딥러닝 학습과정 중 일부임. 다층 퍼셉트론의 학습에 사용되는 통계적 기법
역전파 과정은 검산과정이라고 생각하기. 순전파 때 적용한 활성화함수의 결과를 검산하여 오차를 줄여주는 과정이기 때문에 역전파 과정에서는 따로 활성화함수를 사용하는 과정이 아님
오차를 최소화하기 위한 역전파 과정에서 미분 기법을 이용하게 됨.
하지만 활성화함수를 sigmoid와 tanh 함수로 설정하게 되면 미분과정에서 기울기가 0으로 수렴하게 됨. 따라서 점점 기울기가 사라지고 이에 따른 가중치와 편향 도출이 어려워지는 문제가 발생함
# 255로 나눈 이유? => 0~1 사이 값으로 정규화하기 위해
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
tf.keras.Sequential
모델
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)), # 1차원 벡터 형태로 만들기. 입력층 생성
tf.keras.layers.Dense(units=128, activation='relu'), # 은닉층 생성
tf.keras.layers.Dropout(0.2), # 노드 제거(과적합 방지). 노드 개수 * 0.2만큼 제거
tf.keras.layers.Dense(10, activation='softmax') # 출력층 생성
])
# optimizer(최적화 함수) : 오차(손실함수)가 최소가 되는 지점을 찾기 위해 가중치를 갱신하는 알고리즘. 기울기, 뱡향, learning rate를 고려
# loss : 손실율 측정
# metrics : 평가지표
model.compile(optimizer='adam', # 최적화 함수
loss='sparse_categorical_crossentropy', # loss function. 손실 함수
metrics=['accuracy']) # 모델 평가지표
cross entropy : 손실함수 중 하나로 분류 결과의 품질을 측정
# 첫 번째 이미지에 대한 예측값
predictions = model(x_train[:1]).numpy()
predictions
>>array([[0.30874717, 0.05911743, 0.07364181, 0.07375877, 0.07602702,
0.07852488, 0.09194738, 0.08101318, 0.05992001, 0.09730238]],
dtype=float32)
np.argmax
: 가장 큰 값의 인덱스를 반환smax = tf.nn.softmax(predictions).numpy()
smax, f"softmax는 다 더했을 때 1이 됩니다 : {np.sum(smax)}", f"정답 클래스 : {np.argmax(smax)}"
>>(array([[0.12288869, 0.09574126, 0.09714198, 0.09715334, 0.09737397,
0.09761749, 0.0989366 , 0.0978607 , 0.09581812, 0.09946782]],
dtype=float32), 'softmax는 다 더했을 때 1이 됩니다 : 1.0', '정답 클래스 : 0')
Model.evaluate
메서드는 일반적으로 Validation dataset 또는 Test dataset에서 모델 성능을 확인함model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test, verbose=2)
probability_model = tf.keras.Sequential([
model,
tf.keras.layers.Softmax()
])
y_pred = probability_model(x_test[:5])
y_pred
>> <tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[0.08533683, 0.08533683, 0.08533683, 0.08533751, 0.08533683,
0.08533683, 0.08533683, 0.23196772, 0.08533684, 0.08533685],
[0.08533674, 0.08533674, 0.23196921, 0.08533674, 0.08533674,
0.08533674, 0.08533674, 0.08533674, 0.08533677, 0.08533674],
[0.0853398 , 0.23192093, 0.08534036, 0.08533988, 0.08533984,
0.0853398 , 0.08533981, 0.08535478, 0.08534498, 0.0853398 ],
[0.23195776, 0.08533748, 0.08533873, 0.08533748, 0.08533748,
0.08533756, 0.0853411 , 0.08533749, 0.08533748, 0.08533748],
[0.08535367, 0.08535367, 0.08535367, 0.08535367, 0.23170134,
0.08535367, 0.08535367, 0.08535435, 0.08535367, 0.08546865]],
dtype=float32)>
# 원본 데이터의 min-max
train_images[0].min(), train_images[0].max()
>> (0, 255)
# 스케일링
train_images = train_images / 255.0
test_images = test_images / 255.0
# 시각화
plt.figure()
plt.imshow(train_images[0]) # sns.heatmap과 유사
plt.colorbar()
plt.grid(False)
plt.show()
# 스케일링 이후 min-max
train_images[0].min(), train_images[0].max()
>> (0.0, 1.0)
# Grab an image from the test dataset.
img = test_images[1]
print(img.shape)
>> (28, 28)
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))
print(img.shape)
>> (1, 28, 28)
💡Loss function
loss 값을 보고 label 이 어떤 형태인지 알 수 있음. label 값이 binary, one-hot, oridinal encoding 이 되어있냐에 따라 loss 값을 지정해야 함.
🤔옵티마이저를 사용하는 이유?
1) 다른 데이터에 적용한다면 층 구성을 어떻게 할것인가? -> 입력-은닉-출력층으로 구성됨.
2) 예측하고자 하는 값이 분류(이진, 멀티클래스), 회귀인지에 따라 출력층 구성, loss 설정이 달라짐. 예제를 몇 개 연습해 보면서 익히기.
3) 분류, 회귀에 따라 측정 지표 정하기
4) 활성화함수는 relu 를 사용, optimizer 로는 adam 을 사용하면 baseline 정도의 스코어가 나옴
5) fit 을 할 때 epoch 를 통해 여러 번 학습을 진행하는데 이 때, epoch 수가 많을 수록 대체적으로 좋은 성능을 내지만 과적합(오버피팅)이 될 수도 있음.
6) epoch 수가 너무 적다면 과소적합(언더피팅)이 될 수도 있음.
이진 분류는 하나의 출력층에서 더 높은 확률로 이진분류로 나눌 수 있음
💡실습
binary_crossentropy
사용# tf.keras.models.Sequential 로 입력-히든-출력(sigmoid) 레이어로 구성
input_shape = X.shape[1]
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
# 모델 컴파일
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
# 에폭이 끝날 때마다 점을 표시해서 진행상황 표시
class PrintDot(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs):
if epoch % 100 == 0:
print('')
else:
print('.', end='')
# var_loss 기준으로 값이 나아지지 않으면 멈춤
early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
# 학습
history = model.fit(X_train, y_train, epochs=100, validation_split=0.2, callbacks=[early_stop, PrintDot()])
tf.keras.callbacks.EarlyStopping
🤔딥러닝 과정에서 부분적인 오차를 최저 오차로 인식하여 더이상 학습을 진행하지 않는 경우?