質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

502閲覧

kerasにおけるconv層の初期位置の指定の実装

退会済みユーザー

退会済みユーザー

総合スコア0

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/09/28 08:41

実現したいこと

大サイズの画像(19521952)から入力層(224224)に合わせてブロック分割した複数画像を入力として
CNNを通して大サイズの画像に対してのclassificationを出力として行いたい。

具体的な手法

複数のブロック分割画像を入力するということは
「大サイズ画像(19521952)を入力としてconvolution層(filter=(1952/224)^2=64(ブロック分割分), stride=(224224))を通してから
pointwise(1*1conv)でfilter方向に畳み込みを行ってからCNNに通す」
ことと同じではないかと考えた。

###質問
0. kerasにおけるpaddingはconv操作の前に実行されますか?それともconv操作後に実行されますか?

  1. stride(224, 224)のconv層の入力のfilterは大サイズ画像を8*8ブロック分割の枚数分の数(つまり64)であっていますでしょうか。それとも扱う画像が3チャネルのカラー画像なのでさらにfilter数は3倍必要ですか?
  2. kerasでpointwise(1*1conv)を実装する方法を教えてください。

参考サイト

depthwise separable convolutionについて
https://qiita.com/yu4u/items/34cd33b944d8bdca142d

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

kerasにおけるpaddingはconv操作の前に実行されますか?それともconv操作後に実行されますか?

畳み込みの前です。

stride(224, 224)のconv層の入力のfilterは大サイズ画像を8*8ブロック分割の枚数分の数(つまり64)であっていますでしょうか。それとも扱う画像が3チャネルのカラー画像なのでさらにfilter数は3倍必要ですか?

カラー画像であれば、64 * 3 必要です。
元画像を 8x8 のセルに分割したとした場合、
[1セル目のRGB|2セル目のRGB|3セル目のRGB|...]

kerasでpointwise(1*1conv)を実装する方法を教えてください。

1x1 畳み込みでしたら、Conv2D のフィルターサイズを (1, 1) にするだけでできます。

追記

大きな画像を分割して畳み込んだ場合に、元の画像に対して畳み込んだ場合と同じ結果を得るには、

  1. ゼロパディングする。
  2. パディング分重複するように分割する。
  3. 分割した各画像に対して畳み込みを行う。

これで大きい画像に対して、畳み込みだ場合と同じ結果が得られるはずです。
以下は分割するところまで示してあります。

import numpy as np from numpy.lib.stride_tricks import as_strided # 入力画像 x = np.arange(30000).reshape(100, 100, 3) # フィルター画像 kernel_h, kernel_w = 3, 3 kernel = np.random.randn(kernel_h, kernel_w, 3) # 1. zero padding する。 x_padded = np.pad(x, [(1,), (1,), (0,)], mode='constant', constant_values=0) print('x_padded.shape', x_padded.shape) # x_padded.shape (102, 102, 3) #print(x_padded[:, :, 0]) # 2. 入力を分割する。 h, w, c = x.shape # 入力画像の形状 (100, 100, 3) split_h, split_w = 10, 10 # 分割数 cell_h = h // split_h # 分割した画像の高さ 10 cell_w = w // split_w # 分割した画像の幅 10 out_h = cell_h + np.ceil(kernel_h / 2).astype(int) # 10 + 2 out_w = cell_w + np.ceil(kernel_w / 2).astype(int) # 10 + 2 offset_h, offset_w, offset_c = x_padded.strides print(offset_h, offset_w, offset_c) # 2448 24 8 stride_h = out_h - 1 stride_w = out_w - 1 x_grid = as_strided(x_padded, (split_h, split_w, out_h, out_w, 3), (offset_h * stride_h, offset_w * stride_w, offset_h, offset_w, offset_c)) print(x_grid.shape) # (10, 10, 12, 12, 3)

実際大きい画像はどう扱かう場合が多いか

GPU メモリが大量に使える環境ならモデルの入力サイズを大きくして、流してもいいですが、そうでないなら大きくとも 512x512 ぐらいまでリサイズもしくは分割し、チャンネル方向で結合して流したほうがよさそうです。

分割した場合、パディングにより大きい画像のまま流した場合と微妙に計算結果が違ってきますが、あまり気にしなくてもいいと思います。

投稿2018/09/28 11:21

編集2018/09/28 17:00
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/28 11:37

ご回答ありがとうございます。 パディングがconvの前に行われるということで質問です。 パディングがconv前に行われてしまうということはconvにおけるfilterの中心が画像の座標(0,0)から スタートするという認識でよろしいでしょうか。 このときブロック分割したい場合はおそらく最初の畳み込みを(121, 121)を中心とした座標で本当は行いたいです。このように畳み込みの初期座標を指定する方法はございますか?
tiitoi

2018/09/28 11:52

``` ブロック分割したい場合はおそらく最初の畳み込みを(121, 121)を中心とした座標 ``` (121, 121) はどこからでてきた数ですか? パディングした上で分割して、畳み込みはパディングなしですれば、元の画像を分割なし、パディングありでやった場合と結果は同じにならないでしょうか?
tiitoi

2018/09/28 11:53

畳み込みの初期座標を指定はできないです。
退会済みユーザー

退会済みユーザー

2018/09/28 12:04

(121, 121)はCNNの入力層(224, 224)に合わせて調整を行うための数値のつもりでした。 (0, 0)中心でパディングありの画像をconvした場合、「実現したいこと」で想定している動作と異なりパディング部分を含んだ画像をCNNに入力してしまうことになるので畳み込みを開始する座標を変えたいと思った次第です。 パディングした上で分割して、というのはこのconvの前に画像をパディングしておくということで合ってますでしょうか。
tiitoi

2018/09/28 17:01

確かに分割してチャンネル方向に結合した場合、大きい画像のまま流した場合と比べて、パディングの影響で計算結果に差が出ますが、あまり気にしなくてもいいでしょう。 そのまま分割、チャンネル方向に結合して流してはどうでしょうか
退会済みユーザー

退会済みユーザー

2018/10/02 03:54

追記までご回答頂きありがとうございます。 チャンネル方向で結合したあとの画像のチャンネル数は3*分割数であっているでしょうか。 もうそうであれば既存のCNNに流す際にチャンネルを3つまで減らさなければならないのですが この際、どのようにチャンネル数を調節すればよいでしょうか。
tiitoi

2018/10/02 17:56

分割しない場合とかわるのは、入力層のチャンネル数が3から 3*分割数 になるという点だけだと思います。 ``` もうそうであれば既存のCNNに流す際にチャンネルを3つまで減らさなければならないのですが ``` どういうことでしょうか? 入力層のチャンネル数が増えたとしても2層目以降のパラメータはそのままでもデータを流せると思います。 ---- ちなみにクラス分類なので、画像に写っているメインの対象物は1つで、画像に対してある程度の大きさで写っているということですよね?(つまり、画像に猫と犬が両方写っていたりしないですよね) 自分でしたら、画像が劣化しても縮小やクロップして、ネットワークの入力サイズに合わせます。(224, 224) が小さすぎたら (512, 512) ぐらいのモデルを使えばよいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問