Baseline of ResNet Ablation Study


実習目標


  • 直接実施ResNet

  • モデルをconfigに従って変更できるようにする

  • 直接実験で性能を比較する
  • 学習内容


  • Ablation Study

  • CIFAR-10データセットの準備

  • ブロック構成

  • VGG Complete Model

  • VGG-16 vs VGG-19

  • ResNet Ablation Study
  • Ablation Study


    深さ学習論文では,除去したモデル試験と添加したモデル試験結果を比較し,それらの有効性を実証するために,種々の方法で問題を解決する方法を提案した.
    Abration Studyは,この考え方によって提案された性能または効果を決定するための実験である.
    すなわち,ResNet論文で提案した残りの接続はAbulation Studioである.これは、イメージ・ネットワーク検証データセットの「前回のエラー・レート」が、残りの接続が存在するネットワークと存在しない通常のネットワークを比較し、パフォーマンスが向上したことを証明しているためです.

    Abration Studio実習


    実際の実験を行い、実験結果が本当に有効かどうかを見てみましょう.これは同じデータセットではなく適切なサイズのCIFAR−10データセットを用いる実験である.
    我々の実験目的はCIFAR−10の従来のネットワークとResNetを実施し,両者を比較してResNetと残りの接続の有効性を検証することであり,前回のブログで論文をまとめ実現したため,コード理解は以前よりも良好である.
    実践を容易にするために,コードに注釈処理を行い,途中で用語や進捗説明を行った後にコードを記述した.

    CIFAR-10データの準備


    このデータセットには10カテゴリ、60000枚の画像、32 x 32ピクセルがあります.このデータセットを使用して、オブジェクトを分類します.
    60000枚相当のデータをロードするには長い時間がかかるので、安心してやってください.
    データセットの準備ができたら、クラスの数と名前を表示できます.

    Follow the Code

  • ----------これに基づいてコードを別々に打つことをお勧めします.
  • Flow

  • Tensorflowのインストール

  • 必要なライブラリの読み込み

  • GPUの検証
  • # Tensorflow datasets패키지가 없을 시 설치하기
    
    ! pip install tensorflow-datasets
    
    ---------------------------------------
    
    # TensorFlow and tf.keras
    import tensorflow as tf
    from tensorflow import keras
    
    # Helper libraries
    import numpy as np
    import matplotlib.pyplot as plt
    
    import tensorflow_datasets as tfds
    
    
    -------------------
    
    # Tensorflow가 활용할 GPU가 장착되어 있는지 확인해 봅니다.
    tf.config.list_physical_devices('GPU')
    
    

    Flow


  • データのダウンロード

  • データ属性情報の理解

  • トレーニングおよびテストデータの数について
  • # 데이터 로드
    import urllib3
    urllib3.disable_warnings()
    
    #tfds.disable_progress_bar()   # 이 주석을 풀면 데이터셋 다운로드과정의 프로그레스바가 나타나지 않습니다.
    
    (ds_train, ds_test), ds_info = tfds.load(
        'cifar10',
        split=['train', 'test'],
        shuffle_files=True,
        with_info=True,
    ) # tfds.load(): 기본적으로 ~/tensorflow_datases 경로 데이터셋을 다운로드하고 혹시 데이터셋 경로를 바꾸고 싶다면, data_dir인자 사용하기
    
    -----------
    
    # Tensorflow 데이터셋을 로드하면 꼭 feature 정보를 확인해 보세요. 
    print(ds_info.features)
    
    -------------
    
    # 데이터의 개수도 확인해 봅시다. 
    print(tf.data.experimental.cardinality(ds_train))
    print(tf.data.experimental.cardinality(ds_test))
    

    Input Normalization


    画像は、画素数を用いて画像の大きさを表すこともできるし、画素のチャネル値を用いて画素の色を表すこともできる.このように入力内容が豊富であれば,モデルが混乱する可能性があるため,まず入力データを正規化する.
    正規化は、各チャネルの最大値を255に設定し、画像の表示を0と1の間にします.

    Flow


  • 仕様入力データ

  • クラスの数の決定

  • クラスpaa

  • 一流の写真を見る
  • # 정규화 및 이미지 크기 재조정
    
    def normalize_and_resize_img(image, label):
        """Normalizes images: `uint8` -> `float32`."""
        # image = tf.image.resize(image, [32, 32])
        return tf.cast(image, tf.float32) / 255., label
        
    
    ---------------
    
    ### 정규화된 데이터셋 적용하기
    
    def apply_normalize_on_dataset(ds, is_test=False, batch_size=16):
        ds = ds.map(
            normalize_and_resize_img, 
            num_parallel_calls=1
        )
        ds = ds.batch(batch_size)
        if not is_test:
            ds = ds.repeat()
            ds = ds.shuffle(200)
        ds = ds.prefetch(tf.data.experimental.AUTOTUNE)
        return ds
        
    -----------
    #클래스 개수
    
    ds_info.features["label"].num_classes
    
    -----------------
    
    # 클래스 종류
    ds_info.features["label"].names
     
     
    -----------
    # 크기가 일정한 데이터셋의 사진들이 출력됩니다.
    
    fig = tfds.show_examples(ds_train, ds_info)
    
    --------------
    
    # 크기가 일정한 데이터셋의 사진들이 출력됩니다.
    
    fig = tfds.show_examples(ds_test, ds_info)
    
    

    Abration Studio実習


    組織ブロック


    ブロックとは、主な構造をモジュール化して少しずつ置き換えることができる単位を指す.
    レイヤは、ベースライブラリなどが提供する単位です.
    すぐにResNetを実装することを理解している場合は、より簡単なVGGの例を使用します.
    VGブロックは、複数のCNN層(3 X 3)と1つのMaxpooling層からなり、1つのブロック内の層のチャネルは1つに維持され、他のCNN層のチャネル数とは異なる場合がある.
    そしてCNNの層数とチャンネルを調整して作ります.

    複数のVGタイプから16と19個の基本構造ブロックを作成する.

    Flow


  • 関数を使用したVGGモデルの作成

  • Input layerとOutputの指定

  • 概要(モデル構成)
  • # function for building VGG Block
    
    def build_vgg_block(input_layer,
                        num_cnn=3, 
                        channel=64,
                        block_num=1,
                       ): #block_num은 레이어의 이름 붙여주기 
        # 입력 레이어
        x = input_layer
    
        # CNN 레이어
        for cnn_num in range(num_cnn):
            x = keras.layers.Conv2D(
                filters=channel,
                kernel_size=(3,3),
                activation='relu',
                kernel_initializer='he_normal',
                padding='same',
                name=f'block{block_num}_conv{cnn_num}'
            )(x)    
    
        # Max Pooling 레이어
        x = keras.layers.MaxPooling2D(
            pool_size=(2, 2),
            strides=2,
            name=f'block{block_num}_pooling'
        )(x)
    
        return x
        
    -------------------
    
    vgg_input_layer = keras.layers.Input(shape=(32,32,3))   # 입력 레이어 생성
    vgg_block_output = build_vgg_block(vgg_input_layer)
    
    ----------------
    
    # 블록 1개짜리 model 생성
    model = keras.Model(inputs=vgg_input_layer, outputs=vgg_block_output)  
    # 케라스의 Model클래스에서 I/O정의하면
    model.summary() # 블록 모델 요약본 확인 가능
    
    
    

    Ablation Study


    VGG Complete Model


    ブロック内のCNN層の数とチャンネルの数はブロックによって変化し,関数によって伝達されなければならない.各ブロックはCNNの数とチャンネルリストをあなたに伝えます.

    Flow


  • VGGモデル作成関数

  • VGG16

  • VGG19
  • # VGG 모델 자체를 생성하는 함수입니다.
    def build_vgg(input_shape=(32,32,3),
                  num_cnn_list=[2,2,3,3,3],
                  channel_list=[64,128,256,512,512],
                  num_classes=10):
        
        assert len(num_cnn_list) == len(channel_list) #모델을 만들기 전에 config list들이 같은 길이인지 확인합니다.
        
        input_layer = keras.layers.Input(shape=input_shape)  # input layer를 만들어둡니다.
        output = input_layer
        
        # config list들의 길이만큼 반복해서 블록을 생성합니다.
        for i, (num_cnn, channel) in enumerate(zip(num_cnn_list, channel_list)):
            output = build_vgg_block(
                output,
                num_cnn=num_cnn, 
                channel=channel,
                block_num=i
            )
            
        output = keras.layers.Flatten(name='flatten')(output)
        output = keras.layers.Dense(4096, activation='relu', name='fc1')(output)
        output = keras.layers.Dense(4096, activation='relu', name='fc2')(output)
        output = keras.layers.Dense(num_classes, activation='softmax', name='predictions')(output)
        
        model = keras.Model(
            inputs=input_layer, 
            outputs=output
        )
        return model
        
    ----------
    # 기본값을 그대로 사용해서 VGG 모델을 만들면 VGG-16이 됩니다.
    vgg_16 = build_vgg()
    
    vgg_16.summary()
    
    
    ---------
    
    # 원하는 블록의 설계에 따라 매개변수로 리스트를 전달해 줍니다.
    vgg_19 = build_vgg(
        num_cnn_list=[2,2,4,4,4],
        channel_list=[64,128,256,512,512]
    )
    
    vgg_19.summary()
    
    

    Ablation Study


    VGG-16 vs VGG-19


    VGGの層差を比較するために,16と19を比較する.

    Flow


  • パラメータの設定

  • CIFAR 10データセットの読み込み

  • VGG 16モデルトレーニング

  • VGG 19モデルトレーニング

  • VGG 16とVGG 19の損失と精度の比較(グラフィック可視化)
  • # 파라미터 설정
    
    BATCH_SIZE = 128
    EPOCH = 20
    
    -------------------------
    
    # CIFAR10 데이터셋 부르기
    
    (ds_train, ds_test), ds_info = tfds.load(
        'cifar10',
        split=['train', 'test'],
        as_supervised=True,
        shuffle_files=True,
        with_info=True,
    )
    ds_train = apply_normalize_on_dataset(ds_train, batch_size=BATCH_SIZE)
    ds_test = apply_normalize_on_dataset(ds_test, batch_size=BATCH_SIZE)
    
    -----------
    #VGG16 모델 훈련
    
    vgg_16.compile(
        loss='sparse_categorical_crossentropy',
        optimizer=tf.keras.optimizers.SGD(lr=0.01, clipnorm=1.),
        metrics=['accuracy'],
    )
    
    history_16 = vgg_16.fit(
        ds_train,
        steps_per_epoch=int(ds_info.splits['train'].num_examples/BATCH_SIZE),
        validation_steps=int(ds_info.splits['test'].num_examples/BATCH_SIZE),
        epochs=EPOCH,
        validation_data=ds_test,
        verbose=1,
        use_multiprocessing=True,
    )
    
    
    ------------
    
    #VGG19모델 훈련
    
    vgg_19.compile(
        loss='sparse_categorical_crossentropy',
        optimizer=tf.keras.optimizers.SGD(lr=0.01, clipnorm=1.),
        metrics=['accuracy'],
    )
    
    history_19 = vgg_19.fit(
        ds_train,
        steps_per_epoch=int(ds_info.splits['train'].num_examples/BATCH_SIZE),
        validation_steps=int(ds_info.splits['test'].num_examples/BATCH_SIZE),
        epochs=EPOCH,
        validation_data=ds_test,
        verbose=1,
        use_multiprocessing=True,
    )
    
    -----------------
    
    # 손실 비교(낮을 수록 좋음)
    
    import matplotlib.pyplot as plt
    
    plt.plot(history_16.history['loss'], 'r')
    plt.plot(history_19.history['loss'], 'b')
    plt.title('Model training loss')
    plt.ylabel('Loss')
    plt.xlabel('Epoch')
    plt.legend(['vgg_16', 'vgg_19'], loc='upper left')
    plt.show()
    
    --------------------
    
    ## 정확성(높을 수록 좋음)
    
    plt.plot(history_16.history['val_accuracy'], 'r')
    plt.plot(history_19.history['val_accuracy'], 'b')
    plt.title('Model validation accuracy')
    plt.ylabel('Accuracy')
    plt.xlabel('Epoch')
    plt.legend(['vgg_16', 'vgg_19'], loc='upper left')
    plt.show()
    
    

    n/a.結論


    コードによって直接実験を行い,グラフィックによって可視化を行ったので,論文の実施は興味深い.