SRGANs:低解像度と高解像度画像のギャップを埋める
SRGANs Bridging the Gap between Low-Resolution and High-Resolution Images
イントロダクション
あなたが古い家族の写真アルバムをほこりっぽい屋根裏部屋で見つけるシナリオを想像してください。あなたはすぐにほこりを取り、最も興奮してページをめくるでしょう。そして、多くの年月前の写真を見つけました。しかし、それでも、あなたは幸せではないです。なぜなら、写真が薄く、ぼやけているからです。写真の顔や細部を見つけるために目をこらします。これは昔のシナリオです。現代の新しいテクノロジーのおかげで、私たちはスーパーレゾリューション・ジェネレーティブ・アドバーサリ・ネットワーク(SRGAN)を使用して、低解像度の画像を高解像度の画像に変換することができます。この記事では、私たちはSRGANについて最も学び、QRコードの強化のために実装します。
学習目標
この記事では、以下のことを学びます:
- スーパーレゾリューションと通常のズームとの違いについて
- スーパーレゾリューションのアプローチとそのタイプについて
- SRGAN、その損失関数、アーキテクチャ、およびそのアプリケーションについて深く掘り下げる
- SRGANを使用したQRエンハンスメントの実装とその詳細な説明
この記事は、データサイエンスブログマラソンの一環として公開されました。
スーパーレゾリューションとは何ですか?
多くの犯罪捜査映画では、証拠を求めて探偵がCCTV映像をチェックする典型的なシナリオがよくあります。そして、ぼやけた小さな画像を見つけて、ズームして強化してはっきりした画像を得るシーンがあります。それは可能ですか?はい、スーパーレゾリューションの助けを借りて、それはできます。スーパーレゾリューション技術は、CCTVカメラによってキャプチャされたぼやけた画像を強化し、より詳細な視覚効果を提供することができます。
- このGoogleのAI論文は、さまざまなデバイスで大規模な拡散モデルを実行するために画期的なレイテンシー数値を集めるための一連の最適化を提示しています
- LLM-Blenderに会いましょう:複数のオープンソース大規模言語モデル(LLM)の多様な強みを活用して一貫して優れたパフォーマンスを達成するための新しいアンサンブルフレームワーク
- WAYVE社がGAIA-1を発表:ビデオ、テキスト、アクション入力を活用して現実的な運転ビデオを作成する自律性のための新しい生成AIモデル
…………………………………………………………………………………………………………………………………………………………..
…………………………………………………………………………………………………………………………………………………………..
画像の拡大と強化のプロセスをスーパーレゾリューションと呼びます。それは、対応する低解像度の入力から画像またはビデオの高解像度バージョンを生成することを目的としています。それによって、欠落している詳細を回復し、鮮明さを向上させ、視覚的品質を向上させることができます。強化せずに画像をズームインするだけでは、以下の画像のようにぼやけた画像が得られます。強化はスーパーレゾリューションによって実現されます。写真、監視システム、医療画像、衛星画像など、さまざまな領域で多くの応用があります。
………..
スーパーレゾリューションの従来のアプローチ
従来のアプローチでは、欠落しているピクセル値を推定し、画像の解像度を向上させることに重点を置いています。2つのアプローチがあります。補間ベースの方法と正則化ベースの方法です。
補間ベースの方法
スーパーレゾリューションの初期の日々には、補間ベースの方法に重点が置かれ、欠落しているピクセル値を推定し、その後画像を拡大します。隣接するピクセル値が類似しているという仮定を使用して、これらの値を使用して欠落している値を推定します。最も一般的に使用される補間方法には、バイキュービック、バイリニア、および最近傍補間があります。しかし、その結果は満足できないものでした。これにより、ぼやけた画像が生じました。これらの方法は、基本的な解像度タスクや計算リソースに制限がある状況に適しているため、効率的に計算できます。
正則化ベースの手法
一方で、正則化ベースの手法は、画像再構成プロセスに追加の制約や先行条件を導入することで、超解像度の結果を改善することを目的としています。これらの技術は、画像の統計的特徴を利用して、再構築された画像の精度を向上させながら、細部を保存します。これにより、再構築プロセスにより多くの制御が可能になり、画像の鮮明度と細部が向上します。しかし、複雑な画像コンテンツを扱う場合には、過度の平滑化を引き起こすため、いくつかの制限があります。
これらの従来のアプローチにはいくつかの制限があるにもかかわらず、超解像度の強力な手法の出現への道を示しました。
超解像度の学習ベースの手法
学習ベースの手法は、超解像度の強力で効果的な解決策となっています。これにより、高精細で詳細な高解像度画像が生成されるようになりました。主な学習ベースの手法には、Single Image Super-Resolution (SISR) とGenerative Adversarial Networks (GANs)があります。
単一画像超解像度
単一画像超解像度は、低解像度から高解像度画像へ直接マッピングするマッピング関数を学習することに焦点を当てています。畳み込みニューラルネットワーク(CNN)を使用しています。研究者は、低解像度画像と高解像度画像のペアを含む大規模なデータセットを使用してこれらのネットワークをトレーニングします。これらのネットワークは、低解像度と高解像度の画像の基礎となるパターンと関係を学習し、高品質な結果を生成します。SISRモデルのアーキテクチャには、エンコーダとデコーダがあります。
ここでは、エンコーダが低解像度画像の特徴を捕捉し、デコーダを介して拡大し、それらの特徴を磨いて高解像度画像を取得します。実際の画像と生成された画像の違いを測定するために一般的に使用される損失メトリックには、平均二乗誤差(MSE)とピーク信号対雑音比(PSNR)があります。これらの損失関数をトレーニング中に最小化することで、ネットワークは元の高解像度画像に近い高解像度画像を生成することを学習します。
生成的対立ネットワーク(GANs)
一方、生成的対立ネットワーク(GAN)は、対抗学習フレームワークを導入し、超解像度の進歩をもたらしました。GANには2つのパートがあります。識別器ネットワークとジェネレータネットワークで構成されています。ジェネレータネットワークは、低解像度画像を入力として受け取り、高解像度の出力を生成しようとします。識別器ネットワークは、人工的に作成された高解像度画像と実際の高解像度画像を区別しようとします。GANベースの超解像度手法は、現実的な画像を生成する上で印象的な結果を示しています。従来の手法と比較して、複雑なパターンをキャプチャし、細かいテクスチャを作成する能力があります。超解像度生成的対立ネットワーク(SRGANs)は、超解像度タスクのGANの人気のある実装です。
超解像度生成的対立ネットワーク(SRGAN)
今日の世界では、多くのドメインにおいて高品質の画像が非常に重要です。しかし、多くの制限により常に高解像度画像を撮影することはできません。これが超解像度が関連する場合です。低解像度コンテンツを高解像度コンテンツに変換します。従来の手法の制限を克服するために、学習ベースの超解像度手法が登場し、その中の1つにGANを使用する方法があります。
SRGANは、生成的対立ネットワーク(GAN)と深層畳み込みニューラルネットワーク(CNN)の組み合わせであり、低解像度画像から非常に現実的な高解像度画像を生成します。Generative Adversarial Network(SRGAN)は2つのパートで構成されていることを知っています。それらはジェネレータと識別器です。ジェネレータと識別器は、互いに対立して自分自身を学習します。ジェネレータの目的は、地面の真実の高解像度画像と区別がつかない高解像度画像を生成することです。識別器の目的は、生成された画像を本物の画像と区別することです。これを対立的トレーニングと呼びます。ジェネレータは常に超現実的な高解像度画像を生成して識別器を騙そうとします。それは画像の非常に細かいディテールや全体的な視覚的特性を捕捉することを学びます。識別器は生成された画像にフィードバックを提供し、バックプロパゲーションを通じてジェネレータがより良く学習し、損失を最小限に抑えようとします。
知覚損失
SRGANsの場合に使用する損失関数は、2つの異なる損失の組み合わせである知覚損失を使用します。それらは、コンテンツ損失と対立損失です。
- Content Loss: SRGAN以前は、y_fakeとy_realの平均二乗誤差を使用して損失関数を計算していました。しかし、この方法は、信号対雑音比を高くしても高周波情報を多く失ってしまいます。そのため、論文の著者たちは、いくつかのVGG層の損失を採用することにしました。事前学習された19層のVGGネットワークのReLU活性化層は、このVGG損失の基礎として機能し、特徴表現間のユークリッド距離です。トレーニング後、VGGモデルの特定の層から特徴マップを抽出します。特徴マップの比較は、実際の画像と行われます。
- Adversarial Loss: 敵対的な損失の使用は、ジェネレータが非常にリアルな超解像度画像を生成することを促します。敵対的な損失の計算は、ディスクリミネータによって行われた予測に基づいています。ジェネレータはこの損失を最小化しようとしますが、ディスクリミネータはそれを最大化しようとします。SRGANにより、敵対的な損失を含めることで、ジェネレータネットワークが学習し、実際の高解像度画像のように見える超解像度画像を生成できるようになりました。
超解像度の全体的な損失(知覚損失)は次のとおりです。
SRGANのアーキテクチャ
ジェネレータのアーキテクチャ
低解像度画像を入力として、64個の9×9フィルタを使用する畳み込み層を通過させます。次に、パラメトリックReLU関数が入力として受け取ります。値はその後、残差ブロックに送信されます。共通の操作がグループ化され、残差ブロックを形成します。この操作のシーケンスは、通過する各ブロックに対して繰り返されます。残差ブロック内には、64ピクセルの3×3サイズを使用する畳み込み層があります。パラメトリックReLUに続いて、バッチ正規化層が適用されます。これに続いて、他の畳み込み層があり、バッチ正規化が行われます。
最後に、残差ブロックの入力との要素ごとの和が計算されます。このブロックの出力は、次のブロックに送信され、同じ手順が繰り返されます。これは最後の残差ブロックまで続きます。著者による元の論文で述べられているように、SRGANには合計16個の残差ブロックがあります。これらの残差ブロックの目的は、入力画像から特徴を抽出することです。
残差ブロックの後、別の畳み込み層とバッチ正規化層があります。次に、最初のパラメトリックReLU関数の出力が再び要素ごとの和にさらされます。次は、ピクセルシャッフリングが行われ、画像の解像度を徐々に上げるアップサンプリングブロックです。2つのアップスケーリングブロックがあります。これは、畳み込み層とスーパーレゾリューション画像が出力される畳み込み層で終わります。
ディスクリミネータのアーキテクチャ
ディスクリミネータネットワークは、画像分類畳み込みニューラルネットワーク(CNN)です。生成された画像と実際の高解像度画像を区別するための役割を持ちます。入力画像を分類することを学習します。まず、入力画像(実際の高解像度画像またはジェネレータによって生成された高解像度画像)に畳み込み層が適用されます。この層は、入力画像から特徴を抽出し、次にLeaky ReLU関数を通過します。複数のディスクリミネータブロックを通過し、それぞれには畳み込み層、バッチ正規化、Leaky ReLUが含まれます。最後に、Dense層を通過し、Leaky ReLuと別のDense層を通過して出力を取得します。オリジナルの高解像度画像とジェネレータによって生成された高解像度画像の分類であることはわかっています。
SRGANの応用分野
- 画像とビデオのアップスケーリング: SRGANの最初で最も重要な応用分野は、画像とビデオのアップスケーリングです。これは、品質が重要なデジタルメディア、エンターテインメントなどのさまざまな分野で非常に役立ちます。SRGANは、低解像度のコンテンツの詳細、鮮明さ、および全体的な視覚品質を向上させることができます。
- 監視とセキュリティ: 監視とセキュリティでは、SRGANは低解像度のCCTV映像を強化して高解像度の映像を提供するために使用されます。これにより、ナンバープレート、容疑者の画像などの重要な詳細の明確さが向上し、より良い迅速な調査が可能になります。
- 医療画像: SRGANは、医療画像の分野で素晴らしい結果を示しています。MRIスキャンや超音波画像などの低解像度の医療画像を改善し、診断の正確性を向上させるために使用されます。高解像度の画像を取得することで、医師は患者の問題の微細な詳細を理解することができ、これがより良い治療の提供に役立ちました。
- 衛星画像: 衛星画像は常に技術的な制限により低解像度を持っています。そのため、SRGANはこれらの低解像度画像をアップスケーリングするために使用され、地理的特徴、気象パターンなどのより良い分析と理解が可能になります。
SRGANを使用したQRコードの強化の実装
このプロジェクトでは、SRGANを実装に使用します。このプロジェクトはQRコードの強化に関するもので、低解像度でぼやけたQRコードの画像が入力として渡され、モデルが高解像度でクリアなQRコードの画像を提供します。
QRコードのデータセットはこちらからダウンロードできます。
まず、必要なライブラリをインポートします。
import tensorflow as tf
import numpy as np
import pandas as pd
import cv2
import os
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras import layers, Model
from sklearn.model_selection import train_test_split
from keras import Model
from keras.layers import Conv2D
from keras.layers import PReLU
from keras.layers import BatchNormalization
from keras.layers import Flatten
from keras.layers import UpSampling2D
from keras.layers import LeakyReLU
from keras.layers import Dense
from keras.layers import Input
from keras.layers import add
from tqdm import tqdm
pipを使用してすべての不足しているパッケージをインストールします。
!pip install opencv-python
!pip install tqdm
!pip install scikit-image
次に、ディレクトリ内のファイルを反復処理し、OpenCVを使用して画像ファイルを読み取り、matplotlibを使用して表示します。まず、画像が格納されているパスを割り当てます。ループを1回の反復処理で中断するため、1つの画像のみが表示されます。
datadir = r'path-to-dataset'
# 1つの要素のみを反復処理する
for img in os.listdir(datadir):
img_array = cv2.imread(os.path.join(datadir,img) ,cv2.IMREAD_GRAYSCALE)
plt.imshow(img_array, cmap='gray')
plt.show()
break
トレーニングデータの作成
次に、ディレクトリ内のすべての画像を処理し、トレーニングデータを作成する必要があります。これには、2つのリストを宣言する必要があります:arrayとarray_small。これらは、リサイズされた画像を格納するために初期化されます。 ‘tqdm’モジュールは、画像を反復処理するときに進行状況バーを表示するためにインポートされます。 create_training_data関数では、ディレクトリ内の各画像を反復処理します。各画像について、まずimread()を使用して読み取り、resize()関数を使用して(128、128)にリサイズします。その後、リサイズされた画像をarrayリストに追加します。次に、(32、32)にリサイズしてarray_smallリストに追加します。ディレクトリ内のすべての画像に対してこのプロセスを繰り返します。
array = []
array_small =[]
from tqdm import tqdm
def create_training_data():
for img in tqdm(list(os.listdir(datadir))): # iterate over each image per dogs and cats
try:
img_array = cv2.imread(datadir+'/'+img ,cv2.IMREAD_COLOR) # convert to array
new_array = cv2.resize(img_array, (128, 128)) # resize to normalize data size
array.append([new_array])
array_small.append([cv2.resize(img_array, (32,32),
interpolation=cv2.INTER_AREA)]) # add this to our training_data
except Exception as e: # in the interest in keeping the output clean...
pass
create_training_data()
配列の長さを見つけましょう。合計10000枚の画像があることを意味します。
len(array)
#10000
画像処理とリサイズのステップが成功したかどうかを確認するには、2つの空のリストXとXsを作成する必要があります。高解像度の画像をXに、低解像度の画像をXsに追加します。その後、両方のリストを配列に変換して、高解像度と低解像度の画像が含まれた図をプロットします。その前に、両方のリストを配列に変換してください。
X = []
Xs = []
for features in array:
X.append(features)
for features in array_small:
Xs.append(features)
plt.figure(figsize=(16, 8))
X = np.array(X).reshape(-1, 128, 128, 3)
Xs = np.array(Xs).reshape(-1, 32, 32, 3)
plt.subplot(231)
plt.imshow(X[0], cmap = 'gray')
plt.subplot(233)
plt.imshow(Xs[0], cmap = 'gray')
plt.show()
データ拡張
全データを拡張しましょう。ImageDataGenerator()を使用して拡張画像を作成できます。画像を作成した後、それらを整形して別のディレクトリに保存します。
#データ拡張
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from skimage import io
datagen = ImageDataGenerator(
rotation_range = 40,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
brightness_range = (0.5, 1.5))
for a in X:
i = 0
a = a.reshape((1, ) + a.shape)
for batch in datagen.flow(a, batch_size=1, save_to_dir= r'C:\Users\Admin\Downloads\QR\augmented',
save_prefix='ag', save_format='png'):
try:
i += 1
if i>= 10:
break
except Exception:
print("error")
pass
拡張した画像のトレーニングデータをオリジナルデータと同様に作成する必要があります。その後、拡張データを格納するためのX1とXs1の2つのリストを作成し、図をプロットして理解します。そして、オリジナルデータリストと拡張データリストを連結します。
array=[]
array_small=[]
datadir = r'C:\Users\Admin\Downloads\QR\augmented'
create_training_data()
X1 = []
Xs1 = []
for features in array:
X1.append(features)
for features in array_small:
Xs1.append(features)
X1 = np.array(X1).reshape(-1, 128, 128, 3)
Xs1 = np.array(Xs1).reshape(-1, 32, 32, 3)
plt.figure(figsize=(16, 8))
plt.subplot(231)
plt.imshow(X1[0], cmap = 'gray')
plt.subplot(233)
plt.imshow(Xs1[0], cmap = 'gray')
plt.show()
X=np.concatenate((X,X1), axis = 0)
Xs=np.concatenate((Xs,Xs1), axis=0)
X.shape
全データをトレーニングセットとバリデーションセットに分割する時間です。test_sizeは、データの33%をバリデーションセットに割り当て、67%をトレーニングセットに割り当てることを示しています。random_stateは、分割の再現性を確保するためにランダムシードを設定します。
from sklearn.model_selection import train_test_split
X_train,X_valid,y_train, y_valid = train_test_split(Xs, X, test_size = 0.33, random_state = 12)
X_train.shape
ジェネレータを定義する
ジェネレータを構築しましょう。まず、多くの深層学習アーキテクチャで基本的な構成要素である残差ブロックを定義します。次に、入力テンソルの解像度を増やす責任を持つアップスケールブロックを定義します。最後に、3つの入力パラメータを持つジェネレータを定義します。それらは、入力と追加パラメータであり、res_rangeとupscale_rangeです。それぞれ、ネットワーク内の残差ブロックとアップスケールブロックの数を制御します。
def res_block(input_dim):
model = Conv2D(64, (3,3), padding = 'same' )(input_dim)
model = BatchNormalization()(model)
model = PReLU(shared_axes = [1,2])(model)
model = Conv2D(64, (3,3), padding = 'same' )(model)
model = BatchNormalization()(model)
return add([input_dim, model])
def upscale_block(input_dim):
model = Conv2D(256,(3,3), strides=1, padding = 'same')(input_dim)
model = UpSampling2D(size = (2,2))(model)
model = PReLU(shared_axes=[1, 2])(model)
return model
def generator(input, res_range = 1,upscale_range=1):
model = Conv2D(64,(9,9), strides=1, padding = 'same')(input)
model = PReLU(shared_axes = [1,2])(model)
model1 = model
for i in range(res_range):
model = res_block(model)
model = Conv2D(64, (3,3), padding = 'same' )(model)
model = BatchNormalization()(model)
model = add([model,model1])
for i in range(upscale_range):
model =upscale_block(model)
output = Conv2D(3, (9,9), padding='same')(model)
return Model(input, output)
ディスクリミネータを定義する
では、GANの2番目の部分であるディスクリミネータを構築しましょう。まず、ディスクリミネータで使用される畳み込みブロックであるdiscrim_blockを定義します。次に、ディスクリミネータネットワークを定義します。これは、入力テンソルinputを取り、ディスクリミネータアーキテクチャを構築します。64個のフィルタと(3,3)のカーネルサイズを持つ2D畳み込みを適用し、LeakyReLU活性化関数を適用し、いくつかのdiscriminatorブロックを追加し、出力テンソルをフラット化し、1024ユニットを持つ完全に接続された層を適用し、alphaが0.2のLeakyReLU活性化関数を適用し、1つの単位をsigmoid活性化関数で出力し、ディスクリミネータの出力を表します。最後に、この関数は、入力テンソルと出力テンソルを持つKeras ‘Model’オブジェクトを返します。
def discrim_block(input_dim, fmaps = 64, strides = 1):
model = Conv2D(fmaps, (3,3), padding = 'same', strides = strides)(input_dim)
model = BatchNormalization()(model)
model = LeakyReLU()(model)
return model
def discriminator(input):
model = Conv2D(64,(3,3),padding='same')(input)
model = LeakyReLU()(model)
model = discrim_block(model, strides = 2)
model = discrim_block(model, fmaps = 128)
model = discrim_block(model, fmaps = 128, strides = 2)
model = discrim_block(model, fmaps=256)
model = discrim_block(model, fmaps=256, strides=2)
model = discrim_block(model, fmaps=512)
model = discrim_block(model, fmaps=512, strides=2)
model = Flatten()(model)
model = Dense(1024)(model)
model = LeakyReLU(alpha = 0.2)(model)
out = Dense(1, activation='sigmoid')(model)
return Model(input, out)
VGGモデルを定義する
次に、VGGモデルを構築します。ImageNetデータセットで事前にトレーニングされたVGG19モデルをVGG19関数を使用して初期化します。最後に、この関数は、入力テンソルと出力テンソルを持つKeras Modelオブジェクトを返します。
次に、ジェネレータ、ディスクリミネータ、およびVGG19レイヤーを組み合わせたモデルを作成する必要があります。入力は、ジェネレータモデル、ディスクリミネータモデル、VGG19モデル、低解像度の入力、および高解像度の入力です。低解像度の入力をジェネレータモデルに渡して、高解像度の出力を生成します。次に、VGG19モデル(vgg)を使用して生成された高解像度画像から特徴を抽出します。ディスクリミネータモデルはトレーニングされないように設定されています。生成された画像(gen_img)をディスクリミネータモデル(disc_model)を通じて渡すことで、生成された画像の正当性を計算します。ジェネレータ、ディスクリミネータ、およびVGG19レイヤーを組み合わせることで、生成された高解像度画像を生成するためにジェネレータをトレーニングするために使用できるモデルが得られます。
# VGG19レイヤーの紹介
from tensorflow.keras.applications.vgg19 import VGG19
def build_vgg(hr_shape):
vgg = VGG19(weights="imagenet", include_top=False, input_shape=hr_shape)
return Model(inputs=vgg.inputs, outputs=vgg.layers[10].output)
# Generatorの作成
def create_comb(gen_model, disc_model, vgg, lr_ip, hr_ip):
gen_img = gen_model(lr_ip)
gen_features = vgg(gen_img)
disc_model.trainable = False
validity = disc_model(gen_img)
return Model(inputs=[lr_ip, hr_ip], outputs=[validity, gen_features])
# SRGANの構築
SRGANの構築
最終的なGeneratorネットワークを作成してください。高解像度トレーニング画像の形状( y_train )と低解像度トレーニング画像の形状( X_train )を指定して、Generator、Discriminator、およびVGG19レイヤーを作成します。最後に、create_comb関数を使用してGANモデルを作成します。GANモデルは、トレーニングのためにGenerator、Discriminator、およびVGG19レイヤーを単一のモデルに統合します。
hr_shape = (y_train.shape[1], y_train.shape[2], y_train.shape[3])
lr_shape = (X_train.shape[1], X_train.shape[2], X_train.shape[3])
lr_ip = Input(shape=lr_shape)
hr_ip = Input(shape=hr_shape)
generator = generator(lr_ip, res_range = 16, upscale_range=2)
generator.summary()
discriminator = discriminator(hr_ip)
discriminator.compile(loss="binary_crossentropy", optimizer="adam", metrics=['accuracy'])
discriminator.summary()
vgg = build_vgg((128,128,3))
print(vgg.summary())
vgg.trainable = False
gan_model = create_comb(generator, discriminator, vgg, lr_ip, hr_ip)
SRGANをバイナリクロスエントロピーおよび平均二乗誤差損失関数、Adamオプティマイザを使用してコンパイルしてください。最初の損失関数は、Discriminatorの出力( validity )に使用され、2番目の損失関数は、Generatorの出力( gen_features )に使用されます。
gan_model.compile(loss=["binary_crossentropy", "mse"], loss_weights=[1e-3, 1], optimizer="adam")
gan_model.summary()
SRGANモデルのトレーニングデータをバッチに分割してください。low-resolution image batches と high-resolution image batches を保存するために、train_lr_batches と train_hr_batches の2つの空のリストを作成します。ループ内では、y_train データセットから高解像度画像バッチ (y_train[start_idx:end_idx]) と X_train データセットから低解像度画像バッチ (X_train[start_idx:end_idx]) を抽出し、それぞれ train_hr_batches と train_lr_batches に追加します。
batch_size = 1
train_lr_batches = []
train_hr_batches = []
for it in range(int(y_train.shape[0] / batch_size)):
start_idx = it * batch_size
end_idx = start_idx + batch_size
train_hr_batches.append(y_train[start_idx:end_idx])
train_lr_batches.append(X_train[start_idx:end_idx])
トレーニング
次のステップは、このSRGANモデルのトレーニングです。エポック数を繰り返します。fake_label は、偽(生成された)画像のラベルを表す0で埋められたnumpy配列であり、real_label は、本物の画像のラベルを表す1で埋められたnumpy配列です。generator losses と discriminator losses を保存するために、2つの空のリスト、g_losses と d_losses を作成します。
このプロセスでは、Generatorが偽の画像を生成し、Discriminatorは偽の画像と実際の画像の両方を使用してトレーニングされます。VGGネットワークは高解像度画像から特徴を抽出する責任があります。すべてのバッチを繰り返した後、平均Generator loss とDiscriminator loss を計算します。SRGANモデルのトレーニングは、DiscriminatorとGeneratorを対抗的に更新し、彼らの損失を追跡することによって行われます。
epochs = 1
#エポックの反復処理
for e in range(epochs):
fake_label = np.zeros((batch_size, 1))
real_label = np.ones((batch_size,1))
g_losses = []
d_losses = []
#バッチの反復処理
for b in tqdm(range(len(train_hr_batches))):
lr_imgs = train_lr_batches[b]
hr_imgs = train_hr_batches[b]
fake_imgs = generator.predict_on_batch(lr_imgs)
discriminator.trainable = True
d_loss_gen = discriminator.train_on_batch(fake_imgs, fake_label)
d_loss_real = discriminator.train_on_batch(hr_imgs, real_label)
discriminator.trainable = False
d_loss = 0.5 * np.add(d_loss_gen, d_loss_real)
image_features = vgg.predict(hr_imgs)
g_loss, _, _ = gan_model.train_on_batch([lr_imgs, hr_imgs], [real_label, image_features])
d_losses.append(d_loss)
g_losses.append(g_loss)
g_losses = np.array(g_losses)
d_losses = np.array(d_losses)
g_loss = np.sum(g_losses, axis=0) / len(g_losses)
d_loss = np.sum(d_losses, axis=0) / len(d_losses)
print("epoch:", e+1 ,"g_loss:", g_loss, "d_loss:", d_loss)
if (e+1) % 5 == 0:
generator.save("gen_e_"+ str(e+1) +".h5")
トレーニングされたジェネレーターモデルを保存します。
generator.save("generator"+ str(e+1) +".h5")
テスト
最後のステップは、SRGANをチェックすることです。トレーニングされたジェネレーターモデルを使用して超解像度画像を生成し、低解像度画像とオリジナルの高解像度画像と比較しましょう。
from tensorflow.keras.models import load_model
from numpy.random import randint
[X1, X2] = [X_valid, y_valid]
ix = randint(0, len(X1), 1)
src_image, tar_image = X1[ix], X2[ix]
gen_image = generator.predict(src_image)
plt.figure(figsize=(16, 8))
plt.subplot(231)
plt.title('低解像度画像')
plt.imshow(src_image[0,:,:,:], cmap = 'gray')
plt.subplot(232)
plt.title('超解像度画像')
plt.imshow(cv2.cvtColor(gen_image[0,:,:,:], cv2.COLOR_BGR2GRAY),cmap = 'gray')
plt.subplot(233)
plt.title('オリジナルの高解像度画像')
plt.imshow(tar_image[0,:,:,:], cmap = 'gray')
plt.show()
結論
QRコードの強化のためにSRGANを実装しました。ここで得た結果は、たった1エポック後のものです。解像度の変化を観察することができ、ほぼオリジナルの高解像度画像に達しています。もし少なくとも10エポックトレーニングしていたらどうなるでしょうか。それがSRGANの力です。SRGANは、画像の超解像度生成において、最も進歩的で強力なモデルとして現れています。
キーポイント
- SRGAN(Super-Resolution Generative Adversarial Networks)は、超解像度タスクにおける最新のアプローチです。
- コンテンツロスと対抗的ロスの組み合わせである知覚的ロスを使用しています。これにより、高度にリアルな高解像度画像を生成するのに役立ちます。
- ESRGAN、SRResNet、SRGAN(オリジナル)などの事前トレーニングされたSRGANモデルには、研究者や開発者がアクセスできます。これらのモデルを微調整して、自分のタスクに使用します。
- 現時点では、私たちはSRGANに関する多くの知識を得て、QR強化に実装することで、非常に優れた結果を得ることができました。
- 研究者がSRGANのアーキテクチャ、損失関数、トレーニング戦略を探求し、変更するにつれて、将来的にはさらに印象的な結果が期待できます。
よくある質問
ご質問がある場合は、LinkedInで私にお問い合わせください。
本記事で表示されるメディアはAnalytics Vidhyaの所有物ではなく、著者の裁量により使用されています。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles