[深さ学習/コンピュータビジョン]第2章-画像分類


画像分類は、所与の画像にラベルを貼り付けるものです.本ユニットはTensorflowを用いて直接分類し,精度の向上を学習する.

📃 第2ユニット学習目標


学習
  • MNSIT
  • は、異なる画像データセット
  • を使用することを試みる.
  • 画像分類に用いることができる深さ学習モデル
  • catvs dog分類
  • 📕 Training the MNIST model in Tensorflow


    The MNIST datasets


    始める前に、MNISTとは何かを知っておきましょう.
    MNISTとは?改正された国家標準技術研究所(National Institute of Standards and Technology)の略で、0から9まで10個の数字のデータセットを手書きで書いた.約60000のトレーニングデータと10000のテストデータがあります.画像は28 x 28のサイズからなり、階調です.
    次のリンクからデータセットにリンクをダウンロードできます.
    THE MNIST DATABASE of handwritten digits
    上記リンクを通さずに天書flowで直接使用する方法もあります.私はこの方法でデータをロードしました.

    Loading the MNIST data


    現在,天書フローを用いて学習する前に,MNISTデータをロードする必要がある.
    以下のコードでロードされ、実行時にModuleNotFoundError:No moduleName'tensorflowと呼ばれています.サンプルなどのエラーが発生しました.
    from tensorflow.examples.tutorials.mnist import input_data
    
    mnist_data = input_data.read_data_sets('MNIST_data', one_hot = True)

    この本は2018年にTensorflowに書かれましたexamples.チュートリアルフォルダがないために発生した問題.そこで,本コンテンツはテンソルフロー公式サイトが提供するコンテンツで学習する.
    まずテンソルストリームをインポートし、使用するmnistデータセットを読み込みます.
    import tensorflow as tf 
    
    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
    まず列車データをテストデータに分け,x入力値とyラベル値に分けて負荷データを実行する.
    test値とtraining input値をそれぞれ255.0に分割したのは、サンプル値を浮動小数点に変換するためである.
    実行すると、次のデータがロードされます.

    batchの設定


    batchとは?
    モデルを学習する際,学習データは使い捨てではなく,グループ化して学習する.これで学習速度を速めることができます.この小さなグループをbatchと言います.
    tf.データ設定バッチの使用
    今度はbatchを設定します.
    train_ds = tf.data.Dataset.from_tensor_slices(
    (x_train, y_train)).shuffle(100000).batch(32
    
    test_ds = tf.data.Dataset.from_tensor_slices(
    (x_test,y_test)).batch(32)
    入力データはbatchに分かれているので、トレーニングデータセットとテストデータセットに対応するデータはbatchに分かれている.
    テンソルストリームが提供するデータモジュールが使用されます.tf.data.Datasetでshuffle関数ブレンド(x train,y train)値を使用します.batch関数を用いてパラメータの個数に基づいてbatchを生成する.

    モデルの作成


    モデルを作成する方法は、シーケンスモデル、関数モデル、サブクラスモデルです.次はサブクラスモデルです.
    サブクラス化モデルでモデルを作成する場合は、モデルを直接クラスとして作成し、initに使用するレイヤを作成し、call関数にはinitで使用するレイヤを配置します.
    class MyModel(tf.keras.Model) : 
        def __init__(self): #객체 생성할 때 호출
            super(MyModel, self).__init__()
            self.conv1 = tf.keras.layers.Conv2D(32,3,activation = 'relu')
            self.flatten = tf.keras.layers.Flatten()
            self.d1 = tf.keras.layers.Dense(128, activation ='relu')
            self.d2 = tf.keras.layers.Dense(10, activation = 'softmax')
        
        def call(self, x): #인스턴스 생성할 때 호출
            x = self.conv1(x)
            x = self.flatten(x)
            x = self.d1(x)
            return self.d2(x)
    
    model = MyModel()
    Init関数を表示すると、使用するレイヤが作成されます.tf.KerasはAPIを提供して深さ学習モデルを構築し学習する.モデルの一部の要素レイヤを作成するには、これを使用します.
  • Conv 2 d():ボリューム層
  • Flatten():画像を1次元にタイリングします.
  • keras.layers.Flatten(input_shape=(28, 28)),
    上記のコードは、28 x 28の画像を平らにすることを意味します.
  • Dense():緊密に接続されたレイヤを表します.完全接続とも呼ばれます.
  •  keras.layers.Dense(128, activation='relu'),
    最初のパリメートルは128ノードがあることを意味します.2番目のパリミットはアクティブ化関数を設定します.

    学習モデル


  • ロス関数
    モデルがパラメータを学習するには、損失を最小限に抑える方向に進む必要があります.この損失を計算するために関数を設定します.
    例として用いたloss関数はカテゴリクロスエントロピーであり,3つ以上の分類ラベルがある場合はone-hotが一般的に用いられる.

  • オプティマイザとは?
    オプティマイザは、損失を最小限に抑える方法を決定します.ランダム勾配降下(SGD)、勾配降下(GD)などの方法がある.この例では、Adamオプティマイザを使用して行います.
  • loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
    optimizer = tf.keras.optimizers.Adam()
  • 測定指標:tfを決定する.keras.metrics.Mean
    この測定値に基づいて最終結果を与えた.
  • train_loss = tf.keras.metrics.Mean(name = 'train_loss')
    train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name = 'train_accuracy')
    
    test_loss = tf.keras.metrics.Mean(name='test_loss')
    test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')
    
    

    モデルを訓練する


    tf.Gradient Tapeとは?
    Tensorflowは、微分を計算するためのAPIを提供する.これは、勾配微分値をテープに保存することを意味する.それを使ってモデルを訓練しようとした.
    @tf.function
    これらの表現をPython関数の前に書くと、Python関数はテンソルフロー操作とともに使用できることを意味します.
    #모델 훈련 시키기
    @tf.function
    def train_step(images,labels): 
        with tf.GradientTape() as tape: 
            #모델로 예측한 값
            predictions = model(images) 
            # loss function으로 계산한 loss
            loss = loss_object(labels, predictions) 
            #tape에서 gradient 값 
        gradients = tape.gradient(loss, model.trainable_variables) 
         #optimizer로 update
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    
        
        train_loss(loss)
        train_accuracy(lables, predictions)

    モデルのテスト


    Epochとは?
    エポックの歴史的意義は「時代」だ.深い学習では、学習回数を意味します.つまり、訓練集は何度もニューラルネットワーク全体を通過した.
    次は、モデルをテストするために定義されたtest step関数です.
    
    # 학습된 모델 test하기 
    @tf.function
    def test_step(images, labels): 
        #모델로 예측한 값
        predictions = model(images) 
        #실제 vs 예측값 비교한 loss 값 
        t_loss = loss_object(labels, predictions)
    
        #정확도 계산하기 
        test_loss(t_loss)
        test_accuracy(labels, predictions)
    このモデルを用いてepoch 5を用いて訓練とテストを行った.
    
    EPOCHS = 5
    
    
    for epoch in range(EPOCHS): 
        #training 
        for images, labels in train_ds : 
            train_step(images, labels)
    
        #testing 
        for test_images , test_labels in test_ds: 
            test_step(test_images, test_labels)
    
        # 결과값 출력
        template = '에포크: {}, 손실: {}, 정확도: {}, 테스트 손실: {}, 테스트 정확도: {}'
        print(template.format(epoch+1, 
                            train_loss.result(),
                            train_accuracy.result()*100,
                            test_loss.result(),
                            test_accuracy.result()*100))

    完全なコード

    import tensorflow as tf 
    from tensorflow.keras.models import Sequential 
    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
    
    x_train = x_train[..., tf.newaxis]
    x_test = x_test[..., tf.newaxis]
    
    train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(100000).batch(32)
    test_ds = tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(32)
    
    class MyModel(tf.keras.Model) : 
        def __init__(self): #객체 생성할 때 호출
            super(MyModel, self).__init__()
            self.conv1 = tf.keras.layers.Conv2D(32,3,activation = 'relu')
            self.flatten = tf.keras.layers.Flatten()
            self.d1 = tf.keras.layers.Dense(128, activation ='relu')
            self.d2 = tf.keras.layers.Dense(10, activation = 'softmax')
        
        def call(self, x): #인스턴스 생성할 때 호출
            x = self.conv1(x)
            x = self.flatten(x)
            x = self.d1(x)
            return self.d2(x)
    
    model = MyModel()
    
    
    loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
    optimizer = tf.keras.optimizers.Adam()
    
    train_loss = tf.keras.metrics.Mean(name = 'train_loss')
    train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name = 'train_accuracy')
    
    test_loss = tf.keras.metrics.Mean(name='test_loss')
    test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')
    
    
    #모델 훈련 시키기
    @tf.function
    def train_step(images,labels): 
        with tf.GradientTape() as tape: 
            #모델로 예측한 값
            predictions = model(images) 
            # loss function으로 계산한 loss
            loss = loss_object(labels, predictions) 
            #tape에서 gradient 값 
        gradients = tape.gradient(loss, model.trainable_variables) 
         #optimizer로 update
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    
        
        train_loss(loss)
        train_accuracy(labels, predictions)
    
    # 학습된 모델 test하기 
    @tf.function
    def test_step(images, labels): 
        #모델로 예측한 값
        predictions = model(images) 
        #실제 vs 예측값 비교한 loss 값 
        t_loss = loss_object(labels, predictions)
    
        #정확도 계산하기 
        test_loss(t_loss)
        test_accuracy(labels, predictions)
    
    EPOCHS = 5
    
    
    for epoch in range(EPOCHS): 
        #training 
        for images, labels in train_ds : 
            train_step(images, labels)
    
        #testing 
        for test_images , test_labels in test_ds: 
            test_step(test_images, test_labels)
    
        # 결과값 출력
        template = '에포크: {}, 손실: {}, 정확도: {}, 테스트 손실: {}, 테스트 정확도: {}'
        print(template.format(epoch+1, 
                            train_loss.result(),
                            train_accuracy.result()*100,
                            test_loss.result(),
                            test_accuracy.result()*100))

    結果


    運転時に次のような結果が得られます.

    設定した5 EPOCHで運転すると、後のEpochほど正解率は95.8%から98%にアップします.損失も0.1から0.04に減少した.

    に感銘を与える


    深さ学習を用いて最初から最後まで画像分類実習を行った.プロセス全体がどのように構成されているか理解できると思います.次にテンソルボードの使用、CIFARデータセットの使用などの練習を行います.