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

ASAC 빅데이터 분석가 과정 48일차 (25.02.18)

junslee 2025. 2. 18. 09:28

8_dl

1_code

3_inception

1_Inception_기본내용

Inception Net 에 대해서.


ILSVRC 2014년도 대회에서 우승을 한 모델
1등 : 구글 Inception Net / 구글넷
2등 : VGG Net
=> 우리가 대회에서 1등을 했는데
정작 실제 업계 종사자들이 주로 vgg를 더 많이 사용하더라
=> 약간 엇;
vgg 기존 CNN을 그냥 증축이 핵심! 이해가 어렵지 않음
구조도 기존과 거의 유사함! : 직관적이고 + 용이하고 + 이해도 쉽다
: 성능도 2등이지만 괜찮다


VGG : Conv-Pool 기본 구조
=> 큰 kernel size를 사용하는 것 보다는 작은 거 여러번 CCP,CCCP
=> 레이어들을 적층하는 구조를 가지고 Deep 가겠다!( 수즉 증축)
GoogleNet : Conv-Pool 기본 구조
=> 좋은 재료가 있어야 좋은 결과가 나온다!
좋은 재료 : 1*1, 3*3, 5*5, pool 다양한 측면을 바탕으로 FM쌓자
=> 다양한 측면으로 바라본 FM을 여러번 다양하게 바라보면서
deep 쌓자!!!
--- deep하면 모델이 너무 커지는데: 효율화를 할 것인가
: 1*1 conv을 잘 활용하자!


4개 기능 역할
1*1 : 채널들의 특징을 탐색
3*3 : 작은 크기의 특징들을 추출
5*5 : 조금 큰 크기의 특징들을 추출
3*3 P : 있는 상태에서 중요 정보를 추출
=> 1개 입력에 대해서 다각도록 특징을 추출


입력 그대로 다양한 특징을 처리하려고 하니 연산이 많다;
=> 조절을 좀 해보자

 Inception의 핵심 : 1*1 Conv의 역할 머리에 그림이 그려지셔야 한다.

--> 위의 그림은 중간에 나오는 FM을 바탕으로 분류를 해보는 보조 분류기에 대한 그림을 나타내는 것 
--> 앞에서 산수할 떄 이 부분은 제외를 하고 계산을 하였습니다


2014년도에 오면서 성능이 에러가 10% 안쪽으로 올라오면서
==> 사람의 인식을 넘어서는구나
==> 2등과 1등의 성능이 별로 차이가 안 나고 좀 더 심플하고, 직관적인 VGG를 사람들이 선호를 하였습니다
==> Upgrade

 

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


개선사항1) Conv을 어떻게 효율화 할까!!!

--> Fig4에서 5*5 : 좀 효율적으로 어떻게 할까!
v1) 1*1 사용해서 좀 Channel을 줄여서 효율적으로 개선을 했다!!
v2) 그래도....여전히 이 부분을 개선할 수 있을것 같다!!!!
==> VGG 기본 큰거 Conv = 작은거 Conv * 작은거Conv *
==> 5*5 Conv == 3*3Conv  3*3Conv

===> 다른 논문/아이디어를 참조를 해서
본인의 모델에서 개선 사항을 찾아낸 것!!
: 큰 5*5를 3*3 2개로 30프로 정도 효율화 하자!!!

 ===> v1의 모듈의 구조를 다 무엇으로 1*1, 3*3의 조합으로 다 변경!!!!
Fig5

v2 ) 3*3 ===> (1*3) * (3*1) 으로 변형을 해서 연산의 효율/모델의 파라미터 : 30프로 감소!!

==> 더더더더 Deep 하게 쌓아도 모델이 커지는 효과는 어느 정도 방지를 함

==> Conv을 어떻게 할까에 대한 여러 연구를 함


개선사항2) Conv+Pool  vs Pool + Conv + 보조 분류기 etc

 

 

최종 정리
GoogleNet의 핵심은 FM을 다양한 애들이 한 결과들로 구성을 하겠다
+++ Conv(다양한 크기:1*1, 3*3, 5*5) + Pool
===> 효율화 : 3*3, 5*5 : n * n ---> (1*n) ( n*1 )
n^2   ---> 2n
: 5*5 큰 것을 3*3 작은거 여러번 ( vgg )
N * N ===> [n*n] [n*n]....
===> (1*n)(n*1), (1*n)(n*1)

효율적으로 Deep하게 쌓아가 봅시다!!! 초기에 어떻게 할 것인가
초기 모델을 deep 하게 잘 못하던 부분을 deep 하면서 성능이 사람 정도로 올라오더라
2013~ 2015년
더 큰 모델로 발전하게 되는 디딤돌!

 

+++ ResNet + U-Net
===> 아직도 사용하는 기본적인 구조 & 아이디어

 

+++ Transformer : ViT(기본 블록으로....)
===> ViT기본 블록으로 하고, 다른 기능의 블록, 전체 구조는 U-Net, ResNet 아이디..
조립에 대한 기본 구성 중 하나로 진행을 한다.


2_inceptionNet

  • Inception Net : V1

from tensorflow.keras.models import Model
# --> 내가 custom모델을 TF 하나의 모델로 엮어주는
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Dropout
# ----------
from tensorflow.keras.layers import Concatenate

# inception Block 에 대한 함수!!!
def Inception_block(input_layer, f1,f2_conv1, f2_conv3,f3_conv1, f3_conv5,f4):
    # Input : 전 레이어의 모양을 받을려고 함!!!
    # f1 : 1*1 ==> 표 #1*1
    # f2_conv1 : 1*1 ==> 3*3 앞에 ==> 표 #3*3 reduce
    # f2_conv3 : 3*3 ==> 표 #3*3
    # f3_conv1 : 1*1 ==> 5*5 앞에 ==> 표 #5*5 reduce
    # f3_conv5 : 5*5 ==> 표 #5*5
    # f4 : Input--> MaxPoll --> 1*1 : ==> 표 pool project

    # p1) 1*1
    p1 = Conv2D( filters=f1, kernel_size=(1,1), padding="same", activation="relu")(input_layer)
    # p2) 3*3
    p2 = Conv2D( filters=f2_conv1, kernel_size=(1,1),padding="same", activation="relu")(input_layer)
    p2 = Conv2D(filters=f2_conv3, kernel_size=(3,3),padding="same", activation="relu")(p2)
    # p3) 5*5
    p3 = Conv2D( filters=f3_conv1, kernel_size=(1,1),padding="same", activation="relu")(input_layer)
    p3 = Conv2D(filters=f3_conv5, kernel_size=(5,5),padding="same", activation="relu")(p3)
    # p4) MaxPool
    p4 = MaxPooling2D(pool_size=(3,3), strides=(1,1), padding="same")(input_layer)
    p4 = Conv2D(filters=f4, kernel_size=(1,1),padding="same", activation="relu")(p4)
    #===> 입력에 대한 4가지 결과물들을 얻어냄!!!

    # 다양한 크기의 특징들을  Concate => TF/Keras:
    # W, H, C --> 쌓는 방향 : Channel이 주로 맨 뒤로 세팅!!
    # 앞에 몇 차원지는 신경 안쓰고,,channel 중심으로 쌓을려고 axis= -1
    output_layer = Concatenate(axis=-1)( [ p1,p2,p3,p4])

    return output_layer
def Inception_v1():
    # 함수 형태로 모델의 구조를 작성하는 방식!!!!! : Base!!!

    # Input_layer : (224 * 224 * 3)
    input_layer = Input(shape=(224,224,3))

    # L1 : Conv7*7, s=2
    X = Conv2D( kernel_size=(7,7), filters=64, strides=2,
               padding="same",activation="relu")(input_layer)
    # L1 : MaxPool: 3*3, s=2
    X = MaxPooling2D(pool_size=(3,3), strides=2,padding="same" )(X)

    # L2 : Conv 1*1 ==> 64 ==> #3*3 Reduce
    X = Conv2D(kernel_size=(1,1), filters=64, strides=1,
               padding="same", activation="relu")(X)
    # L2 : Conv 3*3 ==> 192 ==> #3*3
    X = Conv2D(kernel_size=(3,3), filters=192, strides=1,
               padding="same", activation="relu")(X)
    # MaxPool : 3*3, s=2
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same")(X)

    # ===> inception Module : 계속 블럭을 쌓는데,,,안에 필터수만 변경!!!
    #      하나의 함수로!!!!
    # Inception L3-a
    X = Inception_block(X, f1=64,f2_conv1=96, f2_conv3=128,
                        f3_conv1=16, f3_conv5=32,f4=32)
    # Inception L3-b
    X = Inception_block(X, f1=128,f2_conv1=128, f2_conv3=192,
                        f3_conv1=32, f3_conv5=96,f4=64)
    # L3 : MaxPool
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same")(X)
    #################

    # Inception L4-a
    X = Inception_block(X, f1=192,f2_conv1=96, f2_conv3=208,
                        f3_conv1=16, f3_conv5=48,f4=64)
    # Inception L4-b
    X = Inception_block(X, f1=160,f2_conv1=112, f2_conv3=224,
                        f3_conv1=24, f3_conv5=64,f4=64)
    # Inception L4-c
    X = Inception_block(X, f1=128,f2_conv1=128, f2_conv3=256,
                        f3_conv1=24, f3_conv5=64,f4=64)
    # Inception L4-d
    X = Inception_block(X, f1=112,f2_conv1=144, f2_conv3=288,
                        f3_conv1=32, f3_conv5=64,f4=64)
    # Inception L4-e
    X = Inception_block(X, f1=256,f2_conv1=160, f2_conv3=320,
                        f3_conv1=32, f3_conv5=128,f4=128)
    # L4 : MaxPool
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same")(X)



    # --- 연결에 대한 조립!!!! In / Out
    model = Model( input_layer, X, name="InceptionV1")

    return model
model_inception_v1 = Inception_v1()
model_inception_v1.summary()

  • # ===> To Do : 남은 부분을 완성을 해보세요!!!!!!!
def Inception_v1():
    # 함수 형태로 모델의 구조를 작성하는 방식!!!!! : Base!!!

    # Input_layer : (224 * 224 * 3)
    input_layer = Input(shape=(224,224,3))

    # L1 : Conv7*7, s=2
    X = Conv2D( kernel_size=(7,7), filters=64, strides=2,
               padding="same",activation="relu")(input_layer)
    # L1 : MaxPool: 3*3, s=2
    X = MaxPooling2D(pool_size=(3,3), strides=2,padding="same" )(X)

    # L2 : Conv 1*1 ==> 64 ==> #3*3 Reduce
    X = Conv2D(kernel_size=(1,1), filters=64, strides=1,
               padding="same", activation="relu")(X)
    # L2 : Conv 3*3 ==> 192 ==> #3*3
    X = Conv2D(kernel_size=(3,3), filters=192, strides=1,
               padding="same", activation="relu")(X)
    # MaxPool : 3*3, s=2
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same")(X)

    # ===> inception Module : 계속 블럭을 쌓는데,,,안에 필터수만 변경!!!
    #      하나의 함수로!!!!
    # Inception L3-a
    X = Inception_block(X, f1=64,f2_conv1=96, f2_conv3=128,
                        f3_conv1=16, f3_conv5=32,f4=32)
    # Inception L3-b
    X = Inception_block(X, f1=128,f2_conv1=128, f2_conv3=192,
                        f3_conv1=32, f3_conv5=96,f4=64)
    # L3 : MaxPool
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same")(X)
    #################

    # Inception L4-a
    X = Inception_block(X, f1=192,f2_conv1=96, f2_conv3=208,
                        f3_conv1=16, f3_conv5=48,f4=64)
    # Inception L4-b
    X = Inception_block(X, f1=160,f2_conv1=112, f2_conv3=224,
                        f3_conv1=24, f3_conv5=64,f4=64)
    # Inception L4-c
    X = Inception_block(X, f1=128,f2_conv1=128, f2_conv3=256,
                        f3_conv1=24, f3_conv5=64,f4=64)
    # Inception L4-d
    X = Inception_block(X, f1=112,f2_conv1=144, f2_conv3=288,
                        f3_conv1=32, f3_conv5=64,f4=64)
    # Inception L4-e
    X = Inception_block(X, f1=256,f2_conv1=160, f2_conv3=320,
                        f3_conv1=32, f3_conv5=128,f4=128)
    # L4 : MaxPool
    # name은 내가 이 layer에 이름을 부여하기 위해서 : summary 어딘지 체크 + 설명
    X = MaxPooling2D(pool_size=(3,3), strides=2, padding="same", name="L4-LastMaxPool")(X)
    #################


    # Inception L5-a
    X = Inception_block(X, f1=256,f2_conv1=160, f2_conv3=320,
                        f3_conv1=32, f3_conv5=128,f4=128)
    # Inception L5-b
    X = Inception_block(X, f1=384,f2_conv1=192, f2_conv3=384,
                        f3_conv1=48, f3_conv5=128,f4=128)
    # L5 : AvgPool ==> 크기를 유지하면 안 됨!!!
    # *** 여기서는 padding을 사용하면 안 됨!!사용하면 7*7 --> 1*1로 안 변경됨!
    # ==> 여기는 크기에 대한 고정을 안 하는 valid 옵션으로 변경해야 함!!!
    X = AveragePooling2D(pool_size=(7,7), strides=1, padding="valid", name="L5-LastAvgPool")(X)
    # ==> 표 상으로는 1*1*1024이지만
    #     실질적인 분류를 하기 위해서는 연결을 1D 로 해야 함!(,1024)
    X = Flatten()(X)
    # 참고) 대안으로 그냥 GlobalAveraqgePooling 이런 것들도 있음!!!

    #########################
    X = Dropout(0.4)(X)
    X = Dense(units=1000, activation="softmax")(X)
    ################################


    # --- 연결에 대한 조립!!!! In / Out
    model = Model( input_layer, X, name="InceptionV1")

    return model

 

model_inception_v1 = Inception_v1()
model_inception_v1.summary()


다음시간 ResNet

 

** Inception 기본 아이디어

** 코드화 할 것인가!

 => 계속 사용하니까 코드를 잘 알고 있어야 한다.

=> TF/Pytorch : 모델 코드화하는 기본 방식

=> 바느질 방식 (in / out)

 

 

 

조별 플젝 남은시간