ASAC 빅데이터 분석가 7기/ASAC 일일 기록

ASAC 빅데이터 분석가 과정 49일차 (25.02.19)

junslee 2025. 2. 19. 10:04

8_dl

1_code

4_ResNet

ref : https://arxiv.org/pdf/1512.03385

 

  • ResNet
    - VGG / Inception v1: 2014년도 1등, 2등 ---> 대략 5~6% error
    2등 vgg를 더 선호를 했고, Inception :  추후 버전업
    : Conv을 어떻게 적층을 할까
    : 어떻게 하면  Conv에 대한 연산을 효율적을 해서 deep
    : 대략 20층 정도 내외
    - 2015년도 에러 3.% : 이제 끝(사람보다 잘하네) Wow!

  • 생각의 출발점
    --> 작년 대회의 수상한 모델들을 보니...
    목적이나 컨셉이 deep하게 Conv을 쌓아보자
    --> 그래!! 진짜 deep하게 해볼까?? (20층 내외가 아니라 정말로 더 deep)

  • 일반적으로 deep한 구조 ---> F(X)의 모델을 복잡한 모델 ---> OverFit
    ==> Conv 도 deep하면 F(X)가 복잡하고 ---> OverFit
    But) 위의 실험 결과를 보면 : 해보니 ---> UnderFit

  • 나의 세계관이 무너지는 현상
    ==> Deep하면 Gradient Vanshing 현상 실질적으로 네트워크 구조는 복잡해도
    실제 weight들이 제대로 학습이 안 됨
    이 현상에 대해서 : Degradation Problem : Deep하면 성능이 떨어지더라(UF)
    ==> 고민 : 일반적으로 어떻게 진짜 50층 이상 잘 학습을 시킬까

  • 해결책의 핵심적인 내용이 아래 그림
    ==> 아직도 사용하는 구조에서 차용하는 방식 중 하나

  • ==> MS에서는 중간에 Conv한 결과 + 원천이 되는 소스랑 합쳐서 사용하자
    다음 단계로 넘겨봅시다
    .Ws 기능 : 행렬을 합치다 보면,,모양이 안 맞으니

  • 위의 수식에 대해서 다시 고민!
    ==> 위의 수식 누구의 관점인가? in ---- out 바라보자!
    중간 함수 : F(x) ( 본류) , X ( 상류에 대한 샛길 )
    최종 인/아웃 : H(X)
    ==> H(X) = F(X) + X ===> F(X) = H(X) - X
    ==> 학습은 본류에 대한 F(X)를 잘 찾아봅시다!
    ==> Deep하게 하려고 하면,,,마지막에 몰아서 확! 하지 말고,,,
    매일 매일 매일 조금씩 꾸준히 하자!
    소소한 변화들을 쌓아서 큰 결과를 가지고 오자
    학습을 한 블락단위에서 아주 많은 변화를 할 필요가 없음

  • 구조적인 부분에서 인사이트 : 기존에 주로 사용하는 적층 방식을 분류
    + 특정 레이어와 특정 레이어를 연결
    ==> 특정 정보가 소실되는 문제를 방지
    : 향후 모델 구조에서 많이 차용을 한다. U-Net

  • 34층에 대해서 모델의 구조와 실제 설계 내용을 바탕으로
    중간에 연결하는 부분에 실질적으로 어떻게 돌아가는지 그림으로 그려보자

  • 참고) 50층 이상의 초~~고층은 설계를 조금 다르게 하는 것이 좋습니다!!!!
    => 실험적인 결과!!!  1*1 사용을 해서 처리를 하는 부분!!!

  • 조금씩 바꾸고,,,다른 모델과 조금 결합을 하고
    ==> 실험의 영역!
    구조가 바뀌는 것들이고,,, 누가 하지 않은 경우들이 많이 있음!
    ===> 주제는 동일한 논문들인데,,,,구조가 다르고,,그에 따라서 성능도 다르다!
    논문/학회
    실험의 영역이 좀 있다보니까.....중국에서 미친 논문찍어 냄!
    양적으로 중국에서 출판이 많이 되고 있음
    but 큰 모델/ 큰 전환은 잘 안 나옴!!! --> 서비스 퀄리티!! + 상업화!
    ==> 모델의 최적화 적인 부분!!미국 빅테크 중심!! )
    ===> 회사 입장에서는 이러한 부분을 최적화를 할 수 있는 실험 인력
    ( 생산쪽 + 선형 연구 )
    ( AI쪽에서도 실험 + 선행 연구!!! ==> 실험을 하면서 어찌 해결할까! )
    장점 : 본인들 참조하는 논문이 거의 최신이여서,,내가 조금 바꾸면,,다시 갱신
         : 실적 만들기가 용이 함!!! 노가다를 좀 해야 함

1_code

5_AE

  • 이미지 데이터!!
    1) 가장 초기 : DNN ----> CNN
    : 일반적인 NN에 전통적인 kernel+filter 도입!!
    : C-P(3*3, 5*5, 7*7, 11*11 etc)
    ==> 1세대

    2) VGG : 위로 적층을 하자!! 작은 사이즈 여러번!!! CCP,CCCP
    3) Inception : 다양한 필터 사이즈로 종합자!!!Conv1, Conv3, Conv5, 원본MP
    : 향후 개선에서 핵심 1*n, n*1 ==> N * N 효율!!
    4) ResNet : 2/3번처럼 쌓는다고 만능이 아니다!!!
    : 중간 중간에 값을 뽑아서 bypass 시키자!!!
    : 본류 + 원천 값 ==> 100층 이상 쌓아도 성능이 좋은
    초~~고층 설계 방식을 제안!!
    ....
    ==> 2세대

    5) +++ NLP Transformer +++ ViT
    ==> 최근에는 이 부분을 중심으로 Block 단위로 설계!!
    ==> 3세대
  • AutoEncoder : AE
    ===> 모델의 기본적인 구조 "대칭형"을 사용을 함!!

    기존 : 이미지 ----> 분류/회귀
    new  : 이미지 ----> 이미지 ( in/out에 대한 자유도/제약을 풀었음!!)

    입력 : 인코더
    출력 : 디코더
    한글 ---->  utf8인코딩 ---> 숫자값 ---> utf8디코딩 ----> 한글

    전통적인 AE ( 이 자체로는 거의 사용하지 않음,,,구조 차용!!!)
    - 고차원의 데이터를 축소하는 과정/목적에서도 사용할 수 있음..
    - 이미지 복원, 저해상도---> 고해상도, 노이즈 제거 etc
    ==> 기존의 근원에 대한 정보 : 벡터
    ------------------------------------------------
    ==> 새로운 시각 : 근원에 대한 정보 ---> 확률 분포!!!(생성형)
    VAE ----> 생성쪽이 확~~~ ==> Diffusion
    : 기존의 값을 바라보고 값을 줄이는 loss (MSE,CE etc)
    : 확률분포 적용---> 확률유사도 KL-Divergence
    ( 으아;;;;;;효율적으로 할 것인가!!!! Stable Diffusion )
    가우시안 분포 기본으로 함!!! + 연산이 많아요;;;

  • 목적 : 이미지를 넣어서,,,,동일한 이미지를 출력하는 모델!!

    ===> 저해상도 이미지 input --- 고해상도 이미지 output
    (다음 시간에 하면서 u-net 구조도 같이..)

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
mnist = tf.keras.datasets.mnist
mnist
<module 'keras.api.datasets.mnist' from '/usr/local/lib/python3.11/dist-packages/keras/api/datasets/mnist/__init__.py'>add코드add텍스트
(train_X, train_y), (test_X, test_y) = mnist.load_data()
print(train_X.shape)
print(train_y.shape)
print(test_X.shape)
print(test_y.shape)

# 정규화
train_X = train_X/255.0
test_X = test_X/255.0
# 이미지 1장 체크
plt.imshow(train_X[0], cmap="gray")
plt.colorbar()
print(train_y[0])


  • 모델의 구조 : AE의 가장 기본적인 구조 Dense 중심구현!
    ==> 입력 데이터 : 1장 샘플로 생각!

    (28,28) --> 784개의 픽셀/노드 수 Flatten
    -- 인코더(Dense) ==> 근원적인 64개의 값
    -- 디코더(Dense)
    --> 784개  픽셀/노드 값!
    reshape 2D : (28,28) 이미지 확인!

  • 인코더 : 입력으로 받은 784개 정보 --> 근원 64개로 변환하는 과정
    디코더 : 근원적은/줄여진 정보 64개 --> 784개로 복원
    ==> 구조를 대칭형으로 설계를 하겠죠!

# 입력 데이터를 정리 : ( 60000,28,28)
# --> (60000,28*28) = (60000,784)
train_X = train_X.reshape( -1,28*28)
test_X = test_X.reshape( -1,28*28)
print(train_X.shape, test_X.shape)
(60000, 784) (10000, 784) add코드add텍스트
from tensorflow.keras.layers import Dense, Input

# 모델의 구조
model = tf.keras.Sequential(
    [
        Input(shape=(28*28,)),
        Dense(units=784, activation="relu"), # 인코더

        Dense(units=64, activation="relu"), # --> 근원이 되는 벡터

        Dense(units=784, activation="relu") # 디코더
    ]
)
model.compile(
    optimizer=tf.optimizers.Adam(),
    loss =""
)
# loss --> 목적성과 데이터의 특성/ in/out
# ==> 픽셀값 input  ------~~~ ------- 픽셀값 output
#     (0~1)                             (0~1)
# 숫자값들에 대한 비교!!!==>회귀쪽의 기준 mse를 취하겠습니다!!
model.summary()

model.fit(train_X, train_X, epochs=20, batch_size=256)

 

# Test 진행을 하려고 함!!!
random_index = [100, 1000,5000,8887]
plt.figure(figsize=(4,8))
for idx in range(4):
    # 그림의 왼쪽 : test할 이미지 입력
    plt.subplot(4,2, idx*2+1)
    select_idx = random_index[idx]
    plt.imshow( test_X[select_idx].reshape(28,28), cmap="gray")

    # 그림의 오른쪽 : test이미지의 모델 결과
    plt.subplot(4,2, idx*2+2)
    # ---> 1장 : (784,) 1D vector --> test set (10000,784) 2D
    #      모델 : batch를 고려한 1개 샘플 보다 높은 차원으로 입력!
    #      (784,)1D ---> 2D(데이터셋)--> (1,784) (784,1)X --> 앞쪽으로 차원 확장
    # ==> 모양을 만들어야 함!!!! reshape // np.expand_dims
    test_sample = np.expand_dims( test_X[select_idx], axis=0)
    #test_sample = test_X[select_idx] #1D --> 에러 발생!!!
    # test_sample : (1,784)
    img = model.predict( test_sample ) # ==> 1D vecctor
    plt.imshow( img.reshape(28,28), cmap="gray") # 1D --> 2D
# **** 참고) 어제 사용한  concat은 채널 중심으로 확장 : axis=-1
#            샘플 수로 확장 : axis= 0 맨 앞
# : reshape, np.expand_dims, hstck, vstack etc : 모양을 변경!!

  • 인코더/디코더 모듈에
    ==> 이미지데이터인데,,,,무시하고, 픽셀값 중심으로 바라봐서
    일반적인  Dense구성!!
    ==> 이미지 데이터 :
    Conv (인코더) 큰 이미지 --> 작은 특징들
    -------------------------------- 분류 ------------------
    ConvT(디코더) 작은 특징 --> 원래 크기로 확장

# ==> 이미지 데이터의 특성을 활용하기 위해서 Conv2D
# 1. 줄이는 과정 : 특징 생성 // 근원적인 벡터/값 Conv2D
# 2. 확대   과정 : 특징 기반으로 원본을 복원하는 과정 :Covn2DTranspose

# (60000,28,28)--> 앞 (60000,784)
# ====> 데이터 셋 : (60000,28,28,1)
train_X = train_X.reshape(-1, 28,28,1)
test_X = test_X.reshape(-1, 28,28,1)
print(train_X.shape)
(60000, 28, 28, 1) add코드add텍스트

from tensorflow.keras.layers import Conv2D, Flatten, Conv2DTranspose
model = tf.keras.Sequential(
    [
        # 입력 : (28,28,1)
        Input(shape=(28,28,1)),

        # 인코더 파트
        Conv2D( kernel_size=2, filters=32, strides=(2,2),
               activation="relu"),
        # --> (14,14,32)
        Conv2D( kernel_size=2, filters=64, strides=(2,2),
               activation="relu"),
        # --> (7,7, 64)
        ###############################################
        # 3차원 FM --> 1D 차원을 축소!!!
        Flatten(), # (3136,) 1D
        #----------------------------------------------
        # 1장 이미지에 대한 근원 벡터 : 64개 -> 1D
        Dense( units=64, activation="relu"),
        # (64,)
        # ---------------------------------------------
        Dense(units=7*7*64, activation="relu"), # (3136,) 1D
        tf.keras.layers.Reshape( target_shape=(7,7,64)), # (7,7,64) 3D
        # ---> Conv2D : 모양중심으로, 채널은 니가 알아서,,
        #      Conv2DTranspose : 채널 중심,,,,모양은 니가 알아서..
        Conv2DTranspose( filters=32, kernel_size=2, strides=(2,2),
                        activation="relu"), # (14,14,32)
        Conv2DTranspose( filters=1, kernel_size=2, strides=(2,2),
                        activation="sigmoid")
    ]
)
model.summary()

model.compile(
    optimizer=tf.keras.optimizers.Adam(),
    loss="mse"
)
model.fit(train_X, train_X,epochs=20, batch_size=512)

 

# Test 진행을 하려고 함!!!
random_index = [100, 1000,5000,8887]
plt.figure(figsize=(4,8))
for idx in range(4):
    plt.subplot(4,2, idx*2+1)
    select_idx = random_index[idx]
    # (28,28,1) ----> (28,28)
    plt.imshow( test_X[select_idx].reshape(28,28), cmap="gray")

    plt.subplot(4,2, idx*2+2)
    # (28,28,1) 3D ---> (1,28,28,1) 4D
    test_sample = np.expand_dims( test_X[select_idx], axis=0)
    img = model.predict( test_sample ) # ==> 4D Tensor
    plt.imshow( img.reshape(28,28), cmap="gray") # 3D --> 2D
    # (28,28,1) ---> (28,28)

  • 그러면,,,,Conv의 결과가 0이 나오게 되면,,
    ConvTranspoe : 0픽셀이 확대!!!!!
    왜 Conv 결과가 0이 나타나냐 : Af--> Relu
    ===> AF : elu
model = tf.keras.Sequential(
    [
        # 입력 : (28,28,1)
        Input(shape=(28,28,1)),

        # 인코더 파트
        Conv2D( kernel_size=2, filters=32, strides=(2,2),
               activation="elu"),
        # --> (14,14,32)
        Conv2D( kernel_size=2, filters=64, strides=(2,2),
               activation="elu"),
        # --> (7,7, 64)
        ###############################################
        # 3차원 FM --> 1D 차원을 축소!!!
        Flatten(), # (3136,) 1D
        #----------------------------------------------
        # 1장 이미지에 대한 근원 벡터 : 64개 -> 1D
        Dense( units=64, activation="elu"),
        # (64,)
        # ---------------------------------------------
        Dense(units=7*7*64, activation="elu"), # (3136,) 1D
        tf.keras.layers.Reshape( target_shape=(7,7,64)), # (7,7,64) 3D
        # ---> Conv2D : 모양중심으로, 채널은 니가 알아서,,
        #      Conv2DTranspose : 채널 중심,,,,모양은 니가 알아서..
        Conv2DTranspose( filters=32, kernel_size=2, strides=(2,2),
                        activation="elu"), # (14,14,32)
        Conv2DTranspose( filters=1, kernel_size=2, strides=(2,2),
                        activation="sigmoid")
    ]
)
model.compile(
    optimizer=tf.keras.optimizers.Adam(),
    loss="mse"
)
model.fit(train_X, train_X,epochs=20, batch_size=512)

# Test 진행을 하려고 함!!!
random_index = [100, 1000,5000,8887]
plt.figure(figsize=(4,8))
for idx in range(4):
    plt.subplot(4,2, idx*2+1)
    select_idx = random_index[idx]
    # (28,28,1) ----> (28,28)
    plt.imshow( test_X[select_idx].reshape(28,28), cmap="gray")

    plt.subplot(4,2, idx*2+2)
    # (28,28,1) 3D ---> (1,28,28,1) 4D
    test_sample = np.expand_dims( test_X[select_idx], axis=0)
    img = model.predict( test_sample ) # ==> 4D Tensor
    plt.imshow( img.reshape(28,28), cmap="gray") # 3D --> 2D
    # (28,28,1) ---> (28,28)


다음시간

 

제안1) deep 한 Conv으로 해보면 어떨까!!!!!
제안2) padding = "same" --> Pooling : 살짝 구조 변경!!
제안3) 조금 더 큰 size
---> 실험을 하실 수 있어야 함!!!


조별 프로젝트

=> 구체적으로 체크! (잘 되는지, 안되는지 체크)

=> 코드를 돌릴 세팅(버전, 환경 etc)

// 이번주 결정/테스트 해야 진행 될 것