Python で畳み込みニューラル ネットワークを視覚化する

Python で畳み込みニューラル ネットワークを視覚化する

ディープラーニングなどのエンドツーエンドのモデルの場合、トレーニングプロセスをどのように説明し理解するかは、ほとんどの研究者にとって注目の話題の 1 つです。この問題は、医療や軍事などの高リスクの業界にとって特に重要です。ディープラーニングでは、この問題は「ブラックボックス」と呼ばれます。モデルがどのように機能するかを説明できない場合、モデルの出力をどのようにして簡単に信頼できるのでしょうか?

がんの腫瘍を検出するディープラーニング モデルを例に挙げてみましょう。このモデルは、がんを最大 99% の精度で検出できると説明していますが、どのように機能して判断を下すのかは説明していません。それで、モデルは MRI スキャンで重要な手がかりを見つけたのでしょうか?それとも、単にスキャン画像上の汚れが誤って腫瘍と判定されたのでしょうか?モデルの出力は患者の生死や治療計画に影響するため、医師はそのようなミスを犯すわけにはいかない。

[[224830]]

この記事では、コンピューター ビジョンで最も広く使用されているネットワークである畳み込みニューラル ネットワーク (CNN) を視覚化する方法について説明します。まず、CNN モデルの視覚化の重要性を理解します。次に、いくつかの視覚化方法を紹介し、ユースケースを使用して、読者がモデルの視覚化の概念をよりよく理解できるようにします。

1. 畳み込みニューラルネットワークモデルの可視化の重要性

上記の癌腫瘍診断の例に見られるように、研究者は設計したモデルがどのように機能し、何を行うのかを明確に理解することが重要です。一般的に、ディープラーニングの研究者は次の点に留意する必要があります。

1. モデルの仕組みを理解する

2. モデルのパラメータを調整する

3. モデルが失敗した理由を調べる

4. モデルの決定を消費者/エンドユーザーまたは経営幹部に説明する

ここで、ニューラル ネットワーク モデルを視覚化することで、その仕組みを理解し、モデルのパフォーマンスを向上させることができる例を見てみましょう。

かつて、米軍はニューラル ネットワークを使用して、カモフラージュされた敵の戦車を自動的に検出したいと考えていました。研究者たちは、迷彩柄の戦車の写真50枚と森林の写真50枚を使ってニューラルネットワークを訓練した。このモデルは、教師あり学習法を使用してトレーニングされました。研究者がネットワーク パラメータをトレーニングすると、ネットワーク モデルはトレーニング セットに対して正しい判断を下すことができました。カモフラージュされた戦車の写真 50 枚すべてが「はい」を出力し、木の写真 50 枚すべてが「いいえ」を出力しました。しかし、これはモデルが新しいサンプルを正しく分類できることを保証するものではありません。研究者たちは賢明にも、まず最初に迷彩柄の戦車の写真 100 枚と木の写真 100 枚を含む 200 枚の写真を撮影した。 50 枚の写真 (合計 100 枚の写真) をトレーニング セットとして選択し、残りの 100 枚の写真をテスト セットとして選択します。モデルはテスト セットも正しく分類できることが分かりました。そのため、研究者たちはモデルに問題はないと判断し、最終結果を軍に提出した。軍は研究結果に非常に満足するだろうと思っていましたが、軍からのフィードバックは、テスト後に効果は良くなかったというものでした。

[[224831]]

研究者たちは、この件が少し奇妙だと感じました。前回のテストでは 100% 正確だったのに、軍によるテストでは再び失敗したのはなぜでしょうか?最終的に、研究者のデータセットに問題があることが発覚しました。迷彩戦車が収集されたときは曇りでしたが、森が収集されたときは晴れていました。ニューラルネットワークは最終的に、迷彩戦車と森を区別するのではなく、晴れた日と曇りの日を区別することを学習しました。これは本当に笑えます。この問題の主な原因は、モデルの具体的な動作原理と機能がまだわかっていないことです。

2. CNNモデルの可視化方法

CNN 視覚化手法は、その内部動作原理に応じて、おおよそ次の 3 つのカテゴリに分類できます。

1. 予備的アプローチ: 訓練されたモデルの全体構造を示す簡単な方法

2. 活性化に基づく方法:単一または複数のニューロンの活性化状態を解読し、その動作プロセスを理解する

3. 勾配ベースの方法: トレーニング中に前方伝播と後方伝播によって形成された勾配を操作する

上記 3 つの方法については、以下で詳しく説明します。ここで示す例は、Keras ディープラーニング ライブラリを使用して実装されています。また、この記事で使用されているデータセットは、「Recognize Numbers」コンテストで提供されています。したがって、この記事の例を再現する場合は、Kears をインストールし、これらの手順を実行したことを確認してください。

1 予備的な方法

1.1 モデル構造図を描く

研究者ができる最も簡単なことは、モデル構造の図を描くことです。さらに、ニューラル ネットワークの各層の形状とパラメータに注釈を付けることもできます。 keras では、次のコマンドを使用してモデル構造図を描画できます。

  1. モデル.要約()  
  2. _________________________________________________________________  
  3. レイヤー(タイプ)出力形状パラメータ#  
  4. =================================================================  
  5. conv2d_1 (Conv2D) (なし、26、26、32) 320  
  6. _________________________________________________________________  
  7. conv2d_2 (Conv2D) (なし、24、24、64) 18496  
  8. _________________________________________________________________
  9. max_pooling2d_1 (MaxPooling2 (なし、12、12、64) 0  
  10. _________________________________________________________________  
  11. dropout_1 (ドロップアウト) (なし、12、12、64) 0  
  12. _________________________________________________________________  
  13. flatten_1 (フラット化) (なし、9216) 0  
  14. _________________________________________________________________  
  15. 密_1 (密) (なし、128) 1179776  
  16. _________________________________________________________________  
  17. dropout_2 (ドロップアウト) (なし、128) 0
  18. _________________________________________________________________  
  19. preds (密集) (なし、10) 1290  
  20. =================================================================  
  21. 合計パラメータ: 1,199,882  
  22. トレーニング可能なパラメータ: 1,199,882  
  23. トレーニング不可能なパラメータ: 0

モデル構造図をよりクリエイティブで表現力豊かな方法で提示することもできます。keras.utils.vis_utils 関数を使用して、モデル アーキテクチャ図の描画を完了できます。

1.2 視覚化フィルター

もう 1 つのアプローチは、トレーニング済みモデルのフィルターをプロットして、これらのフィルターがどのように動作するかを把握することです。たとえば、最初のレイヤーの最初のフィルターは次のようになります。

  1. top_layer = モデル.layers[0]  
  2. plt.imshow(top_layer.get_weights()[0][:, :, :, 0].squeeze(), cmap= 'gray' )

一般的に、ニューラル ネットワークの最下層は主にエッジ検出器として機能します。層の数が深くなるにつれて、フィルターは顔などのより抽象的な概念を捉えることができるようになります。

2. アクティベーション方法

2.1 活性化の最大化

ニューラル ネットワークの仕組みを理解するには、入力画像にフィルターを適用し、その畳み込み出力をプロットします。これにより、フィルターの特定のアクティブ化パターンが何であるかを理解できます。たとえば、下の画像は顔フィルターで、入力画像が顔画像の場合に有効になります。

  1. vis.visualizationからvisualize_activation をインポートします 
  2. vis.utilsからutilsをインポート 
  3. kerasからアクティベーションをインポートする 
  4. matplotlibからpyplotをpltとしてインポートします 
  5. %matplotlib インライン 
  6. plt.rcParams[ 'figure.figsize' ] = (18, 6)  
  7. #レイヤーインデックス検索するユーティリティ による 名前  
  8. # あるいは、最後レイヤー対応するため、これを -1として指定することもできます  
  9. layer_idx = utils.find_layer_idx(モデル、 'preds' )  
  10. # ソフトマックスを線形置き換える 
  11. model.layers[layer_idx].activation = activations.linear  
  12. モデル = utils.apply_modifications(モデル)  
  13. # これは最大化たい出力ノードです。filter_idx = 0  
  14. img = visualize_activation(モデル、レイヤーID、フィルターインデックス=フィルターID)  
  15. plt.imshow(画像[..., 0])

同様に、この考え方をすべてのカテゴリに適用し、そのパターンがどのようになるかを確認できます。

  1. np.arange(10)output_idxの場合:  
  2. #今回詳細出力をオフにしましょう 混乱を避けて出力だけ確認します  
  3. img = visualize_activation(モデル、レイヤーIDX、フィルターインデックス=出力IDX、入力範囲=(0.、1.))  
  4. plt.figure()  
  5. plt.title( '{} のネットワーク認識' .format(output_idx))  
  6. plt.imshow(画像[..., 0])

2.2 画像の遮蔽

画像分類の問題では、対象オブジェクトが遮蔽され、オブジェクトのごく一部しか見えない状況に遭遇することがあります。画像オクルージョンベースの方法では、灰色の四角形を通して画像のさまざまな部分を体系的に入力し、分類器の出力を監視します。これらの例は、モデルがシーン内のオブジェクトを見つけるときに、オブジェクトが遮蔽されている場合は、オブジェクトを正しく分類する確率が大幅に低下することを明確に示しています。

この概念を理解するには、データセットから画像をランダムにサンプリングし、その画像のヒートマップをプロットしてみるとよいでしょう。これにより、モデルが実際のクラスを明確に区別するために、画像のどの部分が重要であるかを直感的に理解できるようになります。

  1. def iter_occlusion(画像、サイズ=8):  
  2. # https://www.kaggle.com/blargl/simple-occlusion-and-saliency-mapsより引用 
  3.  
  4. 閉塞 = np.full ((サイズ* 5,サイズ* 5, 1), [0.5], np.float32)  
  5. 閉塞中心 = np.full ((サイズ,サイズ, 1), [0.5], np.float32)  
  6. occlusion_padding =サイズ* 2  
  7.  
  8. # print( 'padding...' )  
  9. image_padded = np.pad(image, ( \ (occlusion_padding, occlusion_padding), (occlusion_padding, occlusion_padding), (0, 0) \ ), 'constant' , constant_values ​​= 0.0)  
  10.  
  11. yが範囲(occlusion_padding、image.shape[0] + occlusion_padding、 size )の場合:   
  12. xが範囲(occlusion_padding、image.shape[1] + occlusion_padding、サイズ)の場合:  
  13. tmp = image_padded.copy()   
  14.  
  15. tmp[y - occlusion_padding:y + occlusion_center.shape[0] + occlusion_padding, \  
  16. x - occlusion_padding:x + occlusion_center.shape[1] + occlusion_padding] \ = 閉塞 
  17.  
  18. tmp[y:y + occlusion_center.shape[0], x:x + occlusion_center.shape[1]] = occlusion_center は x - occlusion_padding、y - occlusion_padding、\ を生成します。  
  19. tmp[occlusion_padding:tmp.shape[0] - occlusion_padding, occlusion_padding:tmp.shape[1] - occlusion_padding]i = 23 #たとえばdata = val_x[i]correct_class = np.argmax(val_y[i])  
  20.  
  21. # 入力テンソルfor model.predictinp = data.reshape(1, 28, 28, 1) # 画像データfor matplotlib's imshowimg = data.reshape(28, 28)  
  22. # 閉塞img_size = img.shape[0]   
  23.  
  24. occlusion_size = 4print( 'occluding...' )heatmap = np.zeros((img_size, img_size), np.float32)class_pixels = np.zeros((img_size, img_size), np.int16)  
  25. コレクションからdefaultdictをインポート 
  26. counters = defaultdict( int )n 、(x、y、img_float)、 enumerate (iter_occlusion(data、 size =occlusion_size)) の場合:   
  27. X = img_float.reshape(1, 28, 28, 1)  
  28. 出力= モデル.予測(X)  
  29. #print( '#{}: {} @ {} (正しいクラス: {})' .format(n, np.argmax( out ), np.amax( out ), out [0][correct_class]))  
  30. #print( 'x {} - {} | y {} - {}' .format(x, x + occlusion_size, y, y + occlusion_size))   
  31. ヒートマップ[y:y + occlusion_size, x:x + occlusion_size] =出力[0][correct_class]  
  32. class_pixels[y:y + occlusion_size, x:x + occlusion_size] = np.argmax(出力)  
  33. カウンター[np.argmax( out )] += 1

3. 勾配法

3.1 顕著性マップ

先ほどのタンクの例で見たように、モデルが予測のどの部分に重点を置くべきかをどうやって知るのでしょうか?この目的のために、顕著性マップを使用してこの問題を解決することができます。この論文では、サリエンシーマップが初めて紹介されています。

顕著性マップを使用する概念は非常に単純です。入力画像に対する出力クラスの勾配を計算します。これにより、入力画像のピクセルの小さな変化に対して出力クラス値がどのように変化するかがわかります。グラデーションのすべての正の値は、ピクセルの小さな変化によって出力値が増加することを示しています。したがって、これらの勾配を視覚化することで、ある程度の直感が得られ、このアプローチにより、出力に最も貢献する顕著な画像領域が強調表示されます。

  1. class_idx = 0 インデックス = np。ここで(val_y[:, class_idx] == 1.)[0]  
  2. # ここからランダムな入力選択します。idx = indices[0]  
  3. #選択した画像の妥当性をチェックします。from matplotlib import pyplot as plt%matplotlib inline  
  4. plt.rcParams[ 'figure.figsize' ] = (18, 6)plt.imshow(val_x[idx][..., 0])  
  5.  
  6. vis.visualizationからvisualize_saliency をインポートします 
  7. from vis.utils import utilsfrom keras import activations#レイヤーインデックス検索するユーティリティ による 名前  
  8. # あるいは、最後レイヤー対応するため、これを -1として指定することもできます  
  9. layer_idx = utils.find_layer_idx(モデル、 'preds' )  
  10. # softmax をlinearmodel.layers[layer_idx].activation = activations.linear入れ替えます 
  11. モデル = utils.apply_modifications(モデル) grads = visualize_saliency(モデル、layer_idx、filter_indices=class_idx、seed_input=val_x[idx])  
  12.  
  13. #プロット ヒートマップとして視覚化するための'jet'カラーマップ。plt.imshow(grads, cmap= 'jet' )  
  14.  
  15. # これは高密度線形層対応します。 for class_idx in np.arange(10):  
  16. インデックス = np.where (val_y[:, class_idx] == 1.)[0]  
  17. idx = インデックス[0]  
  18.  
  19. f, ax = plt.subplots(1, 4)  
  20. ax[0].imshow(val_x[idx][..., 0])  
  21.  
  22. iの場合enumerate([None, 'guided' , 'relu' ])修飾子:  
  23. grads = visualize_saliency(モデル、layer_idx、filter_indices=class_idx、  
  24. seed_input=val_x[idx]、backprop_modifier=修飾子)  
  25. 修飾子Noneの場合:  
  26. 修飾子 = 'バニラ'    
  27. ax[i+1].set_title(修飾子)  
  28. ax[i+1].imshow(grads, cmap= 'jet' )

3.2 勾配ベースのクラス活性化マッピング

クラス アクティベーション マップ (CAM) または grad-CAM は、モデルを視覚化する別の方法ですが、勾配の出力を使用する代わりに、この方法では最後から 2 番目の畳み込み層の出力を使用して、最後から 2 番目の層に格納されている空間情報を利用します。

  1. vis.visualizationからvisualize_camをインポートします 
  2. # これは高密度線形層対応します。 for class_idx in np.arange(10):  
  3. インデックス = np.where (val_y[:, class_idx] == 1.)[0]  
  4. idx = インデックス[0]f、ax = plt.subplots(1, 4)  
  5. ax[0].imshow(val_x[idx][..., 0])  
  6. iの場合enumerate([None, 'guided' , 'relu' ])修飾子:  
  7. grads = visualize_cam(モデル、layer_idx、filter_indices=class_idx、  
  8. seed_input=val_x[idx]、backprop_modifier=修飾子)  
  9. 修飾子Noneの場合:  
  10. 修飾子 = 'バニラ'    
  11. ax[i+1].set_title(修飾子)  
  12. ax[i+1].imshow(grads, cmap= 'jet' )

要約する

この記事では、CNN モデルの視覚化の重要性について簡単に説明し、CNN ネットワーク モデルを視覚化するいくつかの方法を紹介します。この記事が読者の皆さんの役に立つことを願っています。読者の皆さんが、今後のディープラーニング アプリケーションでより優れたモデルを構築できるようになります。

<<:  中国の顔認識技術が世界を震撼させている! (顔認証調査報告書を添付します)

>>:  AIの第一人者ジェフ・ディーン氏がGoogleのAI事業を統括

ブログ    
ブログ    

推薦する

第1回自動車開発者会議(2021)が成功裏に終了しました

10月20日、国家インテリジェントコネクテッドビークルイノベーションセンター(以下、「イノベーション...

AI投資を最大限に活用するための6つのステップ

人工知能は、将来の発展にとって大きな破壊的技術の 1 つであるとよく考えられています。これにより、多...

AIやIoT技術を活用した企業が職場復帰する際に考慮すべきこと

新型コロナウイルス感染症のパンデミックにより、社会の多くの分野でデジタル変革が加速し、人工知能ツール...

...

...

自動運転は本当に実現します!最初の発砲は全国7か所で行われた。

自動車市場の発展に伴い、さまざまないわゆる「ブラックテクノロジー」が自動車所有者の敏感な神経をますま...

量子コンピューティングは人工知能をどう変えるのか

量子コンピューティングと人工知能は、現代の最も破壊的なテクノロジーの 2 つです。 2 つのテクノロ...

レッドハットのCEOがAIの取り組みとソースコードの混乱について語る

今年初めの Red Hat Summit で、Red Hat は OpenShift AI によるプ...

...

...

[文字列処理アルゴリズム] 入力文字列の各単語の順序を逆にするアルゴリズム設計とCコード実装

1. 要件の説明文字列を入力し、文字列内の単語を逆順に組み立てて出力するプログラムを作成します。たと...

ついに、人工知能の3つの重要な機能を説明する人がいた。

これらすべての認知機能を 1 つのマシンに統合し、あらゆる一般的なシナリオを処理できる人工知能を汎用...

...

...