フレシェ開始距離(FID)を使用してGANの品質を評価する方法は?
🌟 概要
敵対的生成ネットワーク(GAN)に精通していて、それをトレーニングしたことがある場合は、推論に使用するモデルチェックポイントを疑問に思っているはずです。画像分類では、最高の検証精度を提供するモデルチェックポイントを使用します。
ただし、GANの場合はそうではありません。GANのトレーニングは困難で不安定であり、モードの崩壊などの問題があります。一般的な生成モデルについて詳しく知りたい場合は、Towards Deep Generative Modeling with W&Bをチェックしてください。
独自の単純なGANをトレーニングしてみてください →\rightarrow
トレーニングの指標は、以下のメディアパネルに示されています。問題は、トレーニングメトリックを確認することで、新しい画像の生成に使用するモデルチェックポイントを決定できるかどうかです。
GANを評価する素朴な方法は、モデルのトレーニングプロセスを「ベビーシッター」することです。つまり、モデルのチェックポイントを使用して生成された画像を手動で確認します。コールバックを使用して、n
エポックごとに生成された画像のバッチをログに記録できます。
上にリンクされているcolabノートブックをチェックアウトした場合は、生成された画像をログに記録するためのカスタムKerasコールバックを実装しました。
class GeneratedImageLogger(tf.keras.callbacks.Callback):
def __init__(self, noise_dim, batch_size=32):
super(GeneratedImageLogger, self).__init__()
self.noise = tf.random.normal([batch_size, noise_dim])
def on_epoch_end(self, logs, epoch):
generated_image = generator(self.noise, training=False)
wandb.log({"gen_images": [wandb.Image(image)
for image in generated_image]})
コールバックを使用した結果を以下に示します。以下に示すメディアパネルの⚙アイコンをクリックし、ステップ数を変更して、すべてのエポックで生成された画像を視覚化します。
GAN評価
図1 : (出典)
-
教師あり画像分類では、評価は簡単です。予測された出力を実際の出力と比較する必要があります。
-
ただし、GANを使用すると、ランダムノイズを渡して、この偽の(生成された)画像を取得します。この生成された画像をできるだけリアルに見せたいと思います。では、この生成された画像のリアリズムをどの程度正確に定量化できますか?または、GANをどの程度正確に評価できますか?
まず、評価指標に2つの簡単なプロパティを設定します。
- 忠実度:GANに高品質の画像を生成してもらいたい。
- 多様性:GANは、トレーニングデータセットに固有の画像を生成する必要があります。
したがって、評価メトリックは両方のプロパティに対して評価する必要があります。ただし、正確に何を比較する必要があるため、忠実度と多様性に関する画像の比較は難しい場合があります。コンピュータビジョンで広く使用されている画像を比較するための2つのアプローチは次のとおりです。
-
ピクセル距離:これは、2つの画像のピクセル値を差し引く単純な距離測定です。ただし、これは信頼できるメトリックではありません。
-
特徴距離:事前にトレーニングされた画像分類モデルを使用し、中間層のアクティブ化を使用します。このベクトルは、画像の高レベルの表現です。このような表現を使用して距離メトリックを計算すると、安定した信頼できるメトリックが得られます。
いくつかの根拠がカバーされたので、フレシェ開始距離(FID)を使用してGANを評価する方法をすぐに確認します。
❄️ フレシェ開始距離(FID)
これは、実際の画像と生成された画像の間の特徴距離を測定するための最も一般的なメトリックの1つです。フレシェ距離は、曲線に沿った点の位置と順序を考慮に入れた、曲線間の類似性の尺度です。2つの分布間の距離を測定するためにも使用できます。
FIDを使用してGANを評価する →\rightarrow
数学的には、フレシェ距離は2つの「多変量」正規分布間の距離を計算するために使用されます。「単変量」正規分布の場合、フレシェ距離は次のように与えられます。
d(X,Y)=(μX−μY)2+(σX−σY)2d(X, Y) = (μ_X - μ_Y)^2 + (σ_X - σ_Y)^2
ここで、μμとσσは正規分布の平均と標準偏差であり、XX,とYYは2つの正規分布です。
コンピュータビジョン、特にGAN評価のコンテキストでは、上記のようにフィーチャ距離を使用します。Imagenetデータセットで事前トレーニングされたInception V3モデルを使用します。Inception V3モデルのアクティベーションを使用して各画像を要約すると、スコアに「フレシェ開始距離」という名前が付けられます。
このアクティベーションは、最後から2番目のプーリングレイヤー(TensorFlowを使用している場合はグローバル平均プーリング)から取得されます。形状の出力ベクトル(2048、)
は「多変量」正規分布で近似されると仮定します。
「多変量」正規分布のフレシェ開始距離は、次の式で与えられます。
FID=∣∣μX−μY∣∣2−Tr(∑X+∑Y−2∑X∑Y)FID = ||μ_X - μ_Y||^2 - Tr(\sum_X + \sum_Y - 2\sqrt{\sum_X\sum_Y})
ここで、XXとYYは、2つの多変量正規分布であると想定される実際の埋め込み(開始モデルからのアクティブ化)です。μXμ_XとμYμ_YはベクトルXXとYYの大きさです。TrTrは行列のトレース(linear_algebra)であり、∑Xと∑Yはベクトルの共分散行列です。
🐦 TensorFlowを使用してFIDを実装する
このセクションでは、FIDスコアを使用したGAN評価パイプラインの実装について説明します。同じの主要なコンポーネントを見ていきます。
FIDを使用してGANを評価する方法 →\rightarrow
-
事前にトレーニングされたInceptionV3モデルを使用するには:
inception_model = tf.keras.applications.InceptionV3(include_top=False, weights="imagenet", pooling='avg')
-
実際の画像と生成された画像の埋め込みを計算します。ロ��カルナッシュ均衡に収束する2つのタイムスケール更新ルールによってトレーニングされたGAN の作成者は、最小サンプルサイズ10,000を使用してFIDを計算することを推奨していることに注意してください。そうしないと、ジェネレーターの実際のFIDが過小評価されます。
def compute_embeddings(dataloader, count): image_embeddings = [] for _ in tqdm(range(count)): images = next(iter(dataloader)) embeddings = inception_model.predict(images) image_embeddings.extend(embeddings) return np.array(image_embeddings) count = math.ceil(10000/BATCH_SIZE) # compute embeddings for real images real_image_embeddings = compute_embeddings(trainloader, count) # compute embeddings for generated images generated_image_embeddings = compute_embeddings(genloader, count) real_image_embeddings.shape, generated_image_embeddings.shape
ここで、
trainloader
とgenloader
はtf.data
データセットです。実装の詳細については、colabノートブックを確認してください。 -
実際の画像と生成された画像の埋め込みを使用して、FIDスコアを計算します。
def calculate_fid(real_embeddings, generated_embeddings): # calculate mean and covariance statistics mu1, sigma1 = real_embeddings.mean(axis=0), np.cov(real_embeddings, rowvar=False) mu2, sigma2 = generated_embeddings.mean(axis=0), np.cov(generated_embeddings, rowvar=False) # calculate sum squared difference between means ssdiff = np.sum((mu1 - mu2)**2.0) # calculate sqrt of product between cov covmean = linalg.sqrtm(sigma1.dot(sigma2)) # check and correct imaginary numbers from sqrt if np.iscomplexobj(covmean): covmean = covmean.real # calculate score fid = ssdiff + np.trace(sigma1 + sigma2 - 2.0 * covmean) return fid fid = calculate_fid(real_image_embeddings, generated_image_embeddings)
これで、FIDスコアの計算方法がわかりました。GANチェックポイントのFIDスコアを計算してみましょう。私はW&Bアーティファクトを使用して、5エポックごとにチェックポイントを保存しました。上記の関数を使用して、各チェックポイントのFIDスコアを計算しました。結果は下のメディアパネルに表示されます。
観察
-
モデルのチェックポイントが優れているほど、FIDスコアは低下します。推論のために低いFIDスコアを生成するモデルチェックポイントを選択できます。
-
インセプションモデルは自然画像を構成するImagenetでトレーニングされ、GANはFashionMNISTデータセットでトレーニングされるため、FIDスコアは比較的高くなります。
🐸 FIDの欠点
-
事前にトレーニングされたInceptionモデルを使用しますが、すべての機能をキャプチャできるとは限りません。これにより、上記の場合のように高いFIDスコアが得られる可能性があります。
-
大きなサンプルサイズが必要です。 推奨される最小サンプルサイズは10,000です。高解像度の画像(たとえば512x512ピクセル)の場合、これは計算コストが高く、実行に時間がかかる可能性があります。
-
限定された統計(平均および共分散)は、FIDスコアの計算に使用されます。