flatten
해주면 공간적 특성을 잘 살리지 못함 → 이러한 문제 해결합성곱 필터(Convolution Filter)가 슬라이딩하며 이미지 부분부분을 읽어나감
합성곱 필터를 통해 좌측 상단부터 슬라이딩 시작
코너 값들이 반영이 덜 되고 feature map이 줄어드는 단점
↓ 극복
패딩(Padding)
이미지 외부를 특정 값으로 둘러싸서 처리해주는 방식
주로 제로-패딩(Zero-padding, 0으로 둘러싸주는 방식)이 많이 사용됨
연산되어 나오는 Feature map의 크기(=output)를 조절하고 실제 이미지 값을 충분히 활용하기 위해 사용
Nlp 에서의 padding 과 구분
스트라이드(Stride)
필터 크기, 패딩, 스트라이드에 따른 Feature map 크기 변화
- : 입력되는 이미지의 크기(=피처 수)
- : 출력되는 이미지의 크기(=피처 수)
- : 합성곱에 사용되는 커널(=필터)의 크기
- : 합성곱에 적용한 패딩 값
- : 합성곱에 적용한 스트라이드 값
소수점으로 나올 땐 버려지는 값이 생길 수도 있음 → 정보 손실 有 → 주의 필요
풀링(Pooling)
가로, 세로 방향의 공간을 줄이기 위해 수행
풀링 층은 학습해야 할 가중치(=필터)가 없고 채널 수(=필터 개수)가 변하지 않음
과적합 방지
최대 풀링(Max pooling) : 정해진 범위 내에서 가장 큰 값을 꺼내오는 방식
평균 풀링(Average pooling) : 정해진 범위 내에 있는 모든 요소의 평균을 가져오는 방식
완전 연결 신경망(Fully Connected Layer)
model.add(Conv2D(32, (3,3), padding = 'same', activation='relu'))
# 32 : 필터 수, (3,3) : 필터 크기
# padding = '' : 'valid'(default) or 'same', padding = 'same' 이고 strides = 1 이면 인풋 크기와 아웃풋 크기가 동일해짐, strides = 2 일때 모서리 부분에서 일부분만 데이터가 있을 경우 valid면 해당 데이터는 버려지고, same의 경우 데이터가 없는 부분에만 zero-padding이 생겨 데이터 손실 방지해줌
model.add(Flatten())
# 단지 Dense layer에 연결해주기 위한 용도로 대신 GlobalAveragepooling2D() 사용하기도 함
freeze
)한 채로 진행되기 때문에 빠르게 좋은 결과 얻을 수 있음FCN(Fully Convolutional Networks)
21
의미 : 분류 클래스 수Transpose Convolution
적용U-net
2
의미 : 분류 클래스 수전체 이미지에서 레이블에 맞는 객체를 찾아내는 Task
자율주행을 위한 인공지능 기술로 사용
IoU(Intersection over Union)
객체 탐지 모델
Bounding box를 어떻게 쳐주냐에 따라 two stage, one stage로 나뉨
Two stage detector
One stage detector
AutoEncoder는 잠재 벡터를 잘 얻기 위한 방법
입력 데이터를 저차원의 벡터로 압축한 뒤 원래 크기의 데이터로 복원하는 신경망
Latent(잠재) 벡터
- 원본 데이터보다 차원이 작으면서도 원본 데이터의 특징을 잘 보존하고 있는 벡터
- 잠재 벡터의 크기는 원본 데이터보다 작기만 하면 ok → 사용자 지정
Encoder
Decoder
인코더에서 차원을 줄였는 데 다시 디코더로 차원을 늘려주는 이유
→ 특징 보존이 끝이 아니라 특징이 잘 보존 되었는지 확인하기 위함
활용
예제 1 → 비지도학습
Latent_Dim = 64 # 잠재 벡터의 차원 수 정의
class Autoencoder(Model):
def __init__(self, latent_dim):
super(Autoencoder, self).__init__()
self.latent_dim = latent_dim
self.encoder = tf.keras.Sequential([
layers.Flatten(), # MNIST 데이터 사용해서 flatten
layers.Dense(latent_dim, activation='relu'), # 잠재벡터 차원으로 축소
])
self.decoder = tf.keras.Sequential([
layers.Dense(784, activation='sigmoid'), # 원본 데이터 차원수로 확대
layers.Reshape((28,28)) # flatten 한거 다시 복구
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
model = Autoencoder(Latent_Dim)
model.compile(optimizer='adam', loss='mse')
model.fit(x_train, x_train, epochs=10, shuffle=True, validation_data=(x_test, x_test))
예제 2 : DAE(Denoising AutoEncoder) → 안개가 있는 환경에서 사람인지 안개인지 확인
Conv2D
사용 → Convolutional AutoEncoder
# Random Noise 추가
noise_factor = 0.2 # 0.2, 0.25 가 성능이 가장 좋음
x_train_noisy = x_train + noise_factor * tf.random.normal(shape=x_train.shape)
x_test_noisy = x_test + noise_factor * tf.random.normal(shape=x_test.shape)
x_train_noisy = tf.clip_by_value(x_train_noisy, clip_value_min=0., clip_value_max=1.)
x_test_noisy = tf.clip_by_value(x_test_noisy, clip_value_min=0., clip_value_max=1.)
#DAE 모델 구축
class Denoise(Model):
def __init__(self):
super(Denoise, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(16, (3,3), activation='relu', padding='same', strides=2),
layers.Conv2D(8, (3,3), activation='relu', padding='same', strides=2)])
self.decoder = tf.keras.Sequential([
layers.Conv2DTranspose(8, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2DTranspose(16, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2D(1, kernel_size=(3,3), activation='sigmoid', padding='same')])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
model = Denoise()
model.compile(optimizer='adam', loss='mse')
# 입력데이터는 noise 있는 데이터, 타겟데이터는 원본 이미지
model.fit(x_train.noisy, x_train, epochs=10, shuffle=True, validation_data=(x_text_noisy, x_test))
Dropout
으로 Noise
처럼 사용 가능
예제 3 : 이상치 탐지 → 산불 감지
AutoEncoder는 특정 데이터의 중요 특징, 즉 잠재 벡터를 바탕으로 다시 원본 데이터로 복원할 때에 발생하는 오류, 즉 복원 오류(Reconstruction Error) 를 최소화 하도록 훈련
정상 데이터로만 훈련한 뒤에 비정상 데이터셋을 복원한다면 복원 오류가 커짐
복원 오류가 특정한 임계값을 초과하는 경우 해당 데이터를 비정상으로 판단 할 수 있음
임계값 = 정상데이터셋에 대한 복원 오류 평균 + 표준편차
# 정상 데이터셋과 비정상 데이터셋 분리
# 모델 학습 시에는 데이터셋에서 레이블이 '1' 로 지정된 정상 데이터만 사용
train_label = train_label.astype(bool)
test_label = test_label.astype(bool)
normal_train_data = train_data[train_label]
normal_test_data = test_data[test_label]
anomalous_train_data = train_data[~train_label]
anomalous_test_data = test_data[~test_label]
# AutoEncoder 모델 구축
# 학습 시에는 정상데이터만 사용해야 함
class AnomalyDetector(Model):
def __init__(self):
super(AnomalyDetector, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Dense(32, activation="relu"),
layers.Dense(16, activation="relu"),
layers.Dense(8, activation="relu")])
self.decoder = tf.keras.Sequential([
layers.Dense(16, activation="relu"),
layers.Dense(32, activation="relu"),
layers.Dense(140, activation="sigmoid")]) # 마지막 층은 원본 데이터의 차원 수와 동일하게 맞추어줍니다.
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
model = AnomalyDetector()
model.compile(optimizer='adam', loss='mae')
model.fit(normal_train_data, normal_train_data, epochs=20, batch_size=512, validation_data(test_data, test_data), shuffle=True)
# 이상치로 분류하는 함수
def predict(model, data, threshold):
reconstructions = model(data)
loss = tf.keras.losses.mae(reconstructions, data)
return tf.math.less(loss, threshold)
MinMaxScaling 방식의 정규화
- 표준화 방법 중 하나로 각 특성의 단위를 맞춰줌, 데이터를 0-1 사이로 맞춤
- 이상치에 굉장히 예민하기 때문에 예제에서처럼 이상치 탐지가 목적인 경우에 사용
Standard Scaler
- 이상치가 있어도 괜찮음
이상치 탐지 이유
- 정상 데이터셋에서도 이상치가 있지만 정상/비정상에서도 특정한 애들을 구별해서 더 집중하기 위함
- 1종 오류, 2종 오류 분류
- 평가지표에
Accuracy
뿐만 아니라Recall
과Precision
도 함께 봄
Manifold
- AutoEncoder는 데이터가 펴져있는 공간상에서 데이터의 매니폴드를 찾아내어 학습하는 과정
- 매니폴드는 고차원 공간에서 데이터가 이루는 저차원의 공간을 의미, ex. Swiss-roll
- 매니폴드 학습은 매니폴드 공간을 찾는 것을 의미
https://deepinsight.tistory.com/124
G
ernerator)D
iscriminator)Convolution Layer로 이루어짐
손실함수
real_loss
와 fake_loss
를 더한 값real_loss
: 전체가 1인 행렬과 real_output
을 비교fake_loss
: 전체가 0인 행렬과 fake_output
을 비교fake_output
을 비교 Pix2Pix
는 train 셋을 구성할 때 레이블에 해당하는 데이터를 무조건 짝지어 주어야 함