|
・In English
前提知識
・畳み込みニューラルネットワーク
・python関数
■画像フィルタとは
ここで扱う画像フィルタ処理は、主に畳み込みニューラルネットワーク(CNN)などに用いられる画像フィルタ処理です。
フィルタ処理は画像データとフィルタ値を掛けたものを足し合わせる"積和演算"を行い、更にフィルタをスライド(スライドさせる幅をストライドといいます)させながら画像全体に対して積和演算をしていきます。これを
畳み込み演算(Convolution)といいます。なおこの様な2次元の行列で表されるフィルタの事をカーネルともいいます。
<縦エッジ,横エッジフィルタ>
縦方向と横方向のラインを画像をそれぞれ際立たせるためのフィルタが以下となります。
■パディング処理
上記のフィルタ処理を加えると画像データが小さくなります。これを防止するため画像データの周りに値を入れて置くことをパディング処理といいます。
特に画像データの周りに0を入れておくことをゼロパディングといいます。パディングは他にも、画像データの端と同じデータと入れる手法もあります。
■フィルタ、パディング処理後の画像サイズの求め方
以下となります。
■pythonによる実装具体例
以下28x28ピクセルの画像に対してフィルタ処理をかけます。CNNでは画像フィルタ係数は初期はランダム値で、学習で最適値に向けて更新していきますが、
ここでは係数は固定とし特定の機能を持った縦エッジフィルタと横エッジフィルタを用います。
・ 画像データ:filter.zip
import numpy as np
import matplotlib.pyplot as plt
# 画像データの読み込み、前処理
train = np.loadtxt('mnist_fig.txt')
train = train/255 # 正規化
input_data = train.reshape(28,28) # 28x28にリシェイプ
img = np.pad(input_data, [(1, 1), (1, 1)], 'constant') # ゼロパディング処理
# フィルタ処理
fil = np.array([[-2,1,1], [-2,1,1], [-2,1,1]]).reshape(9,1)
# 縦エッジ,横エッジにする場合は[[1,1,1],[1,1,1],[-2,-2,-2]]
col = np.zeros((3, 3, 28, 28))
for y in range(3):
y_max = y + 28
for x in range(3):
x_max = x + 28
col[y, x, :, :] = img[y:y_max, x:x_max]
col1 = col.transpose(2, 3, 0, 1).reshape(28*28, -1)
fil_data=np.dot(col1,fil) # 実際のフィルタの計算
img_fin=np.transpose(fil_data).reshape(28,28) # フィルタリングされた画像データ
# 画像表示
plt.imshow(img_fin, cmap='Greys')
plt.show()
結果は以下のとおり。
<プログラムの解説>
プログラム上部は画像データの読み込み、パディング処理となり、特に難しい所は無いと思います。
フィルタ処理と書かれているところからが重要で、特にfor分のところが何をしているのか解りづらいと思います。これは計算の効率化のために必要な処理となっており、効率化を考慮しないならもっと理解しやすいコードがかけます。
ニューラルネットワークはたくさんのデータを処理するので全体として計算に非常に時間がかかります。そのため多少解りづらくても効率よく計算する方法が求められます。
さてここを理解するには、結果から見た方がイメージがつきます。"col1"は以下の様になっており、行例計算しやすいようにフィルタの対象を9つずつ並んでいるのですが、これを一括で実行しているのがこのプログラムです。
計28x28=784行です。また数値は便宜的に割りつけた番号となります。
fil_dataは以下の様になり、この部分が実際のフィルタ処理となりなす。
サブチャンネルあります。⇒ 何かのお役に立てればと
|
|