ディープラーニング プロジェクトの例: オートエンコーダを使用したぼやけた画像の復元

ディープラーニング プロジェクトの例: オートエンコーダを使用したぼやけた画像の復元

より鮮明な写真を撮るには、カメラ レンズの優先フォーカスを使用して同じ写真を再度撮影するか、ディープラーニングの知識を使用してぼやけた画像を再現します。 私の専門は写真撮影ではないので、残された唯一の選択肢は、ディープラーニング技術を使用して画像のぼかしを除去することです。

この記事では、プロジェクトを開始する前に、読者がニューラル ネットワーク、CNN などのディープラーニングの基本概念を理解していることを前提としています。 Keras、Tensorflow、OpenCV についても少し知っておく必要があります。

ぼかしには、モーション ブラー、ガウス ブラー、平均ブラーなど、さまざまな種類があります。 しかし、ここではガウスぼかし画像に焦点を当てます。 このタイプのぼかしでは、ピクセルの重みは不均等になります。 ぼかしは中央で大きくなり、端に向かってベル型の曲線を描いて減少します。

データセット

コードを使い始める前に、まず必要なのは、ぼやけた画像ときれいな画像の 2 セットの画像で構成されるデータセットです。 現時点では、既製のデータセットは利用できないかもしれませんが、上で述べたように、OpenCV の基本を理解していれば、これは非常に簡単です。元の画像があれば、OpenCV を使用してトレーニングに必要なデータセットを生成できます。

ここでのデータセットのサイズは約 50 枚の画像 (50 枚のきれいな画像と 50 枚のぼかし画像) ですが、これはデモンストレーション目的のため、少数の画像のみが選択されています。

コードを書く

データセットの準備ができたので、コードの記述を開始できます。

依存関係

 numpyをnp としてインポートする
pandaspd としてインポートする
matplotlib.pyplot plt としてインポートします
% matplotlib インライン
ランダムにインポート
cv2 をインポート
インポートOS
テンソルフローtf としてインポートする
tqdm からtqdm をインポート

ここで tqdm ライブラリをインポートすると、コードの実行にかかる時間を把握できる進行状況バーを作成できます。

データのインポート

 good_frames = '/content/drive/MyDrive/mini_clean'
bad_frames = '/content/drive/MyDrive/mini_blur'

これで 2 つのリストが作成されました。 keras 前処理ライブラリを使用して、「.jpg」、「jpeg」、または「.png」タイプの画像を読み取り、配列に変換します。ここで画像サイズは128x128です。

 クリーンフレーム= []
tqdm ( sorted ( os . listdir ( good_frames )) 内のファイルの場合):
存在する場合([ '.jpg''jpeg''.png' ] 拡張子に対するファイル内の拡張子):
image = tf . keras . preprocessing . image . load_img ( good_frames + '/' + file , target_size = ( 128 , 128 ))
image = tf.keras.preprocessing.image.img_to_array (image ) .astype ( 'float32 ' ) / 255
clean_frames.append (画像)
clean_frames = np .array ( clean_frames )
ぼやけたフレーム= []
tqdm 内のファイルの場合( sorted ( os . listdir ( bad_frames ))):
存在する場合([ '.jpg''jpeg''.png' ] 拡張子に対するファイル内の拡張子):
image = tf . keras . preprocessing . image . load_img ( bad_frames + '/' + file , target_size = ( 128 , 128 ))
image = tf.keras.preprocessing.image.img_to_array (image ) .astype ( 'float32 ' ) / 255
blurry_frames . append ( 画像)
ぼやけたフレーム= np . 配列( ぼやけたフレーム)

モデルライブラリをインポートする

 keras.layers からDense インポートし入力
keras.layers からConv2D インポートしFlatten
keras.layers からReshapeConv2DTranspose インポートします
keras.models からModel インポートする
keras . callbacks からReduceLROnPlateauModelCheckpoint をインポートします
keras.utils.vis_utils からplot_model インポートする
keras からバックエンドをK としてインポートします
ランダム. シード= 21
np . ランダム. シード= シード

データセットをトレーニングセットとテストセットに分割する

ここで、データセットを 80:20 の比率でトレーニング セットとテスト セットに分割します。

 クリーンフレーム;
y = ぼやけたフレーム;
sklearn.model_selection からtrain_test_split インポートします
x_trainx_testy_trainy_test = train_test_split ( xytest_size = 0.2random_state = 42 ) です。

トレーニングデータセットとテストデータセットの形状を確認する

 印刷( x_train [ 0 ] .shape )
印刷( y_train [ 0 ] .shape )

 r = ランダム. randint ( 0 , len ( clean_frames ) - 1 )
印刷( r )
= plt . ()
. subplots_adjust ( hspace = 0.1wspace = 0.2 )
ax = .add_subplot ( 1 , 2 , 1 )
ax.imshow ( クリーンフレーム[ r ])
ax = .add_subplot ( 1 , 2 , 2 )
ax.imshow (ぼやけフレーム[ r ])

上記のコードでは、トレーニング データセットとテスト データセットから画像を表示できます。次に例を示します。

以下はモデルを書くときに必要ないくつかのパラメータを初期化します

 # ネットワークパラメータ
入力形状= ( 128 , 128 , 3 )
バッチサイズ= 32
カーネルサイズ= 3
潜在次元= 256
# エンコーダー/デコーダーの CNN レイヤー数とレイヤーあたりのフィルター数
レイヤーフィルター= [ 64 , 128 , 256 ]

エンコーダモデル

オートエンコーダの構造については、以前の記事で何度も詳しく説明しているので、ここでは詳しく説明しません。

 inputs = 入力( 形状= input_shape名前= 'encoder_input' )
x = 入力

まず最初に入力(画像の配列)が必要です。入力を取得したら、Conv2D(64) - Conv2D(128) - Conv2D(256) のシンプルなエンコーダーを構築します。エンコーダーは画像を (16, 16, 256) に圧縮します。この配列がデコーダーの入力になります。

 layer_filters 内のフィルターの場合:
x = Conv2D ( フィルター= フィルター
カーネルサイズ= カーネルサイズ
ストライド= 2
アクティベーション= 'relu'
パディング= '同じ' )( x )
形状= K . int_shape ( x )
x = 平坦化()( x )
潜在= ( latent_dimname = 'latent_vector' )( x )

ここで、K.int_shape() はテンソルを整数のタプルに変換します。

エンコーダモデルを次のようにインスタンス化する

 エンコーダ= モデル( 入力潜在名前= 'エンコーダ' )
エンコーダ.サマリー( )

デコーダーモデル

デコーダー モデルはエンコーダー モデルに似ていますが、逆の計算を実行します。 デコーダーは入力を (128, 128, 3) に戻します。 したがって、ここではConv2DTranspose(256) - Conv2DTranspose(128) - Conv2DTranspose(64)を使用します。

 latent_inputs = 入力( 形状= ( latent_dim ,), 名前= 'decoder_input' )
x = ( 形状[ 1 ] * 形状[ 2 ] * 形状[ 3 ])( 潜在入力)
x = Reshape (( shape [ 1 ], shape [ 2 ], shape [ 3 ]))( x ) 、 layer_filters [:: - 1 ] 内のフィルター場合:
x = Conv2DTranspose ( フィルター= フィルター,
カーネルサイズ= カーネルサイズ
ストライド= 2
アクティベーション= 'relu'
パディング= '同じ' )( x )
出力= Conv2DTranspose ( フィルター= 3
カーネルサイズ= カーネルサイズ
活性化= 'シグモイド'
パディング= '同じ'
名前= 'デコーダー出力' )( x )

デコーダーは次のとおりです。

 デコーダー= モデル( latent_inputsoutputsname = 'decoder' )
デコーダー. 概要()

オートエンコーダに統合

オートエンコーダー = エンコーダー + デコーダー

 autoencoder = モデル( 入力デコーダー( エンコーダー( 入力) )、 名前= 'autoencoder' )
オートエンコーダ.サマリー( )

最後に、モデルをトレーニングする前にハイパーパラメータを設定する必要があります。

 オートエンコーダ. コンパイル( loss = 'mse'optimizer = 'adam'metrics = [ "acc" ])

損失関数として平均二乗誤差、最適化ツールとして Adam、評価メトリックとして精度を選択しました。次に、メトリックが改善されない場合に学習率を下げることができるように、学習率調整スケジュールを定義する必要があります。

 lr_reducer = ReduceLROnPlateau ( 係数= np.sqrt ( 0.1 ) 
クールダウン= 0
忍耐力= 5
詳細= 1
最小lr = 0.5e-6 )

学習率の調整は、トレーニングの各ラウンドで呼び出す必要があります。

 コールバック= [ lr_reducer ]

モデルのトレーニング

 history = オートエンコーダ.fit ( blurry_frames ,
クリーンフレーム
検証データ= ( ぼやけたフレーム, きれいなフレーム),
エポック= 100
バッチサイズ= バッチサイズ
コールバック= コールバック)

このコードを実行した後、トレーニング エポックを 100 に設定しているため、最終出力が表示されるまでに約 5 ~ 6 分、またはそれ以上かかる場合があります。

最終結果

モデルのトレーニングが成功したので、モデルの予測を見てみましょう。

 print ( "\n グラウンドトゥルース予測値を入力してください" )
iが範囲( 3 ) 内にある場合:

r = ランダム. randint ( 0 , len ( clean_frames ) - 1 )
x , y = ぼやけたフレーム[ r ]、 きれいなフレーム[ r ]
x_inp = x . reshape ( 1 , 128 , 128 , 3 )
結果= オートエンコーダ. 予測( x_inp )
結果= 結果.reshape ( 128,128,3 )
= plt . ( 図サイズ= ( 12 , 10 ))
. subplots_adjust ( hspace = 0.1wspace = 0.2 )
ax = .add_subplot ( 1 , 3 , 1 )
ax . imshow ( x )
ax = .add_subplot ( 1 , 3 , 2 )
ax.imshow ( y ) 関数
ax = .add_subplot ( 1 , 3 , 3 )
plt . imshow ( 結果)

モデルは画像のぼかしをうまく除去し、ほぼ元の画像を取得できることがわかります。 3 層の畳み込みアーキテクチャのみを使用したため、より深いモデルを使用する場合は、ハイパーパラメータの調整によってより良い結果が得られるはずです。

トレーニングの進行状況を確認するには、損失関数と精度のグラフをプロットして、より適切な決定を下すことができます。

損失の変化

 plt . ( 図サイズ= ( 12 , 8 ))
plt . plot ( history . history [ 'loss' ])
plt . plot ( history . history [ 'val_loss' ])
plt . legend ([ 'Train' , 'Test' ])
plt . xlabel ( 'エポック' )
plt . ylabel ( '損失' )
plt . xticks ( np . arange ( 0 , 101 , 25 ))
plt . 表示()

損失が大幅に減少し、エポック 80 から停滞していることがわかります。

正確さ

 plt . ( 図サイズ= ( 12 , 8 ))
plt . plot ( history . history [ 'acc' ])
plt . plot ( history . history [ 'val_acc' ])
plt . legend ([ 'Train' , 'Test' ])
plt . xlabel ( 'エポック' )
plt . ylabel ( '精度' )
plt . xticks ( np . arange ( 0 , 101 , 25 ))
plt . 表示()

ここでは精度が大幅に向上していることがわかります。より多くのエポックでトレーニングすると、精度はさらに向上する可能性があります。 したがって、エポック サイズを増やして精度が実際に向上するかどうかを確認したり、早期停止メカニズムを追加してトレーニングを自動的に停止したりすることができます。

要約する

78.07% という良好な精度を達成しました。 この記事は、より優れたネットワーク アーキテクチャ、より多くのデータ、ハイパーパラメータの調整などの実用的なアプリケーションのほんの始まりにすぎません。


<<:  AIはHRにどのように役立つのでしょうか?

>>:  自然言語処理: エンタープライズ AI の新たなフロンティア

ブログ    
ブログ    
ブログ    

推薦する

...

TensorFlow を使用して機械学習モデルを構築する方法

[[432744]] TensorFlow は、Google が開発し、2015 年にオープンソース...

...

AIとビッグデータのつながり

ビッグデータと人工知能は、今日最も新しく、最も有用なテクノロジーの 2 つです。人工知能は10年以上...

無人タクシーが登場します。準備はできていますか?

[[243616]]地図: 小魚クラウド コンピューティングやビッグ データなどのアプリケーション...

AIモデルの「レッドチーム」からの迅速な修正を期待しないでください

ホワイトハウスの関係者らが人工知能チャットボットが引き起こす可能性のある社会的危害を懸念する中、シリ...

...

バイトマルチモーダル大規模モデル PixelLM: SA に頼らない効率的なピクセルレベル推論

マルチモーダルな大規模モデルが爆発的に増加していますが、画像編集、自動運転、ロボット工学などのきめ細...

...

著者の半数以上が中国人です! Google Researchの画像表現モデルALIGNがImageNetを支配

[[399343]]ニューラル ネットワークは実際には表現を学習しています。CV の分野では、優れ...

ChatGPTはオンラインモードを緊急にシャットダウンし、有料のウェブページに無料でアクセスできることが一度明らかになった。

ChatGPT を使用して有料の Web コンテンツに無料でアクセスすることは、まもなくできなくな...

ハッシュアルゴリズムを使用した ASP.NET データ暗号化

ハッシュ アルゴリズムを使用して ASP.NET データ暗号化を実装するプロセスは何ですか?私たちの...

TensorRT が顔認識を高速化する方法

[[329844]]顔認識のリアルタイム パフォーマンスを向上させるために、私たちのチームは従来のニ...