VAEを用いた異常検知を実践(犬猫の分類及びMNISTの手書き文字)

初めまして、みずぺーといいます。
このnoteを機に初めて私を知った方のために、箇条書きで自己紹介を記述します。

  • 年齢:28歳

  • 出身:長崎

  • 大学:中堅国立大学

  • 専門:河川、河川計画、河道計画、河川環境

  • 転職回数:1回(建設(2年9か月)→IT系年収100万up(現職3か月))

  • IT系の資格:R5.4基本情報技術者試験合格💮、R5.5G資格

本記事ではVAEの説明と実際にVAEを用いた異常検知の実践についてお話しできればと思います。


VAEとは

続いての章はVAEによる物体検出の例です。

VAEとはVariational Autoencoderの略で深層学習の一種であり、生成モデルの一つです。

VAEは、データの高次元の分布を低次元の潜在空間にマッピングすることで、データを効率的にエンコードし、その後、潜在空間から元の高次元空間にデータをデコード(再構成)することができます。

VAEの原理は以下の通りです。

  • エンコーダ

  • 潜在空間のサンプリング

  • デコーダ

そして学習を進めていくうえで2つのロス関数を最小化することで同時に行われます。

  • 再構成ロス

  • KLダイバージェンス

一つづつ解説します。

エンコーダ

入力データを潜在空間のパラメータ(平均と分散)に変換します。これは、入力データがどのように潜在空間にマッピングされるかを決定します。

潜在空間のサンプリング

潜在空間(データの抽象的な表現を保持するための低次元の空間)からランダムに点をサンプリングします。この点は、エンコーダから得られた平均と分散を使用したガウス分布からサンプリングされます。

余談:潜在空間とは

データの抽象的な表現を保持する低次元の空間のことを指します。潜在空間は、高次元のデータをより扱いやすい形に圧縮するために使用されます。この圧縮は、データの重要な特徴を保持しながら、ノイズや不要な詳細を取り除くことを目指します。

例えば、画像のピクセルデータは非常に高次元です(各ピクセルが一つの次元を持つため)。しかし、画像の「意味」や「内容」は、そのピクセルデータよりもはるかに低次元で表現することができます。この「意味」や「内容」を表現する低次元の空間が潜在空間です。

潜在空間は、自己符号化器生成敵対ネットワーク(GAN)などの深層学習モデルで広く使用されています。これらのモデルは、データを潜在空間にエンコード(圧縮)し、その後、潜在空間からデコード(再構成)することで、データの生成や変換を行います。

特に、潜在空間が連続的である場合(つまり、潜在空間内の任意の点が有意義なデータに対応する場合)、新しいデータを生成したり、データ間のスムーズな遷移を生成したりすることが可能になります。これは、例えば、Variational Autoencoder(VAE)やGANで利用される特性です。

デコーダ

サンプリングされた潜在変数を元の入力データの次元に戻します。これにより、元のデータを再構成します。

上記の三つがVAEを構成するモデルの概要です。

ここからはそれをどうやって学習させてモデル化するのかを解説します。

再構成ロス

元のデータと再構成データとの間の差を測定します。このロスが小さいほど、デコーダは元のデータを正確に再構成できます。

KLダイバージェンス

エンコーダから得られた潜在変数の分布と事前分布(通常は標準正規分布)との間の差を測定します。このロスが小さいほど、エンコーダはデータを事前分布に近い形でエンコードします。


画像収集

まずは素材がないと始まらない!ということでwebから画像を拾ってくる作業を行います。

猫と犬の画像をwebから拾ってくる

猫、画像と検索して名前を付けて保存

フォルダ構成

保存する際には以下のようなフォルダ構成で配置を行います。

/dataset
    /train
        /dogs
            dog1.jpg
            dog2.jpg
            ...
    /test
        /dogs
            dog1.jpg
            dog2.jpg
            ...

それではここから実際に実装を始めていきます。

前処理

まずはwebから拾ってきた画像は縦横のピクセルサイズしかりカラー画像等様々なので、モデルを読み込ませるために合わせます。

前処理コード

from keras.layers import Input, Dense, Lambda
from keras.models import Model
from keras import backend as K
from keras import losses
from keras.datasets import mnist
from PIL import Image
import os
import numpy as np

def load_images(folder):
    images = []
    for filename in os.listdir(folder):
        img = Image.open(os.path.join(folder, filename))
        if img is not None:
            # 画像をグレースケールに変換し、64x64にリサイズ
            img = img.convert('L').resize((64, 64))
            # 画像データをnumpy配列に変換し、正規化
            img = np.array(img) / 255.0
            # 配列を1次元に変換
            img = img.flatten()
            images.append(img)
    return np.array(images)

# 訓練データとテストデータの読み込み
x_train_dogs = load_images('/content/drive/MyDrive/ColabNotebooks/VAE/dataset/train/dog')
x_train_cats = load_images('/content/drive/MyDrive/ColabNotebooks/VAE/dataset/train/cat')
x_train = np.concatenate([x_train_dogs, x_train_cats])

x_test_dogs = load_images('/content/drive/MyDrive/ColabNotebooks/VAE/dataset/test/dog')
x_test_cats = load_images('/content/drive/MyDrive/ColabNotebooks/VAE/dataset/test/cat')
x_test = np.concatenate([x_test_dogs, x_test_cats])

今の配置から実際にこのような前処理のコードを記載してます。

ここから先は

8,275字 / 8画像

¥ 300

この記事が気に入ったらサポートをしてみませんか?