ニューラルネットワークを使って,画像のピクセルワイズなセグメンテーションを行おうとしています.(FCNやSegNetのような)
普通はCaffeなどのフレームワークを使用するのでしょうが,ニューラルネットによる推論をノートPCやAndroidなど様々な端末で動かす必要があるため,NVIDIAのGPUなどに依存し,環境構築の大変な既存のフレームワークは使えません.(学習はデスクトップで行います)
なので,Python3系を使って,使用するすべてのレイヤ,機能を1から書いています.(もちろん,ネットや書籍を参考にしながらですが.)
しかし,ピクセルワイズセグメンテーションを行うためには必要な,Upsampling層またはDeconvolution層の実装が出来ません.
基本的に使っているのはNumpyのみで,各層は以下のようにクラスとして定義しています.
python
1# シグモイド層 2class Sigmoid: 3 def __init__(self): 4 self.out = None 5 6 def forward(self, x): 7 out = sigmoid(x)#シグモイド関数 8 self.out = out 9 return out 10 11 def backward(self, dout): 12 dx = dout * (1.0 - self.out) * self.out 13 14 return dx
各クラスの中に,forward処理とbackward処理を実装しています.
Upsampling層も実装しようと思ったのですがどうすればいいのかわからず,質問させていただきました.
アイデアとしては,
のように,対象とする行列に左右から行列をかけて2倍にしたいです.
(汎用性は2の次で,2倍に出来ればいいです.入力される行列は2×2とは限りませんが偶数×偶数の正方行列です.)
以下が書きかけのコードです.
python
1# Upsampling層(行,列をニアレストネイバー法で2倍にする) 2class Upsampling: 3 def __init__(self): 4 5 self.arrray1 = None 6 self.arrray2 = None 7 8 self.x = None 9 self.original_x_shape = None 10 11 def forward(self, x): 12 N, C, H, W = x.shape 13#Xは[N,C,H,W]からなる行列:Nはミニバッチ数Cはチェンネル数 14 15 nparrray1 = np.zeros(H*2, H)#左からかける零行列 16 nparrray2 = np.zeros(W, W*2)#右からかける零行列 17 18#以下でかける行列の必要な要素を1に変更 19 w1 = 0 20 count1 = 0 21 w2 = 0 22 count2 = 0 23 for i in range(0, H*2): 24 x[i][w1] = 1 25 count1 += 1 26 if count1== 2: 27 count1 = 0 28 w1 += 1 29 for i in range(0, W*2): 30 x[w2][i] = 1 31 count2 += 1 32 if count2== 2: 33 count2 = 0 34 w2 += 1 35'''' 36ここから,どうすればいいのかわかりません. 37入力されているのは4次元で,作ったのは2次元配列なので 38このままdot積をとっても適切に計算できないと思い, 39いろいろ調べてみたのですが,手詰まりです. 40'''' 41 return out//最後に出力される行列を返す. 42 43 def backward(self, dout)://doutを微分して返せばいい? 44''''' 45こっちのbackwardの方は,完全にどうしていいのかわかりません. 46数学に長けているわけでもないので, 47どうすれば逆伝播が表現できるのか,理論レベルでも実装レベルでもちんぷんかんぷんです… 48''''' 49 return dx
Caffe等,既存のフレームワークのコードを参照してみたりしましたが
そもそも書き方も言語も違うためか,理解できませんでした.
大変未熟者でお恥ずかしいのですが,
そもそものアイデアのところから,間違えていたらご指摘お願いします.
実装レベルでコードまでご教授いただけると,大変助かります.
あなたの回答
tips
プレビュー