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

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

ただいまの
回答率

88.57%

kerasのVGG16モデルに対し、グレースケールの画像を入力する方法について

解決済

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 5,287

Kohei_KESE

score 41

表記の件について、下記のようにプログラムを作成したところ、最後の3行でDimension 0 in both shapes must be equal, but are 3 and 64. Shapes are [3,3,1,64] and [64,3,3,3]. for 'Assign' (op: 'Assign') with input shapes: [3,3,1,64], [64,3,3,3]. といったエラーが発生しました。カラースケールにしたときはうまくいったのですが、今回うまくいかなかった理由がわかりませんでした。どうかアドバイスを教えて頂きたいです。よろしくお願いします。

filenames = os.listdir(r"100dataset_train") #dataというフォルダにある画像を読み込み
Path = "./100dataset_train/"
save_PATH = '71VGG16'
h = 256
w = 256

train = np.zeros((num_files, h, w)) #画像データの箱を用意し
# #画像をひとつずつ読み込み箱に入れていく
# two_data = cv2.imread(Path+filenames[1], 0)
# plt.imshow(two_data, cmap = "gray")
# plt.show()
for i,filename in zip(range(num_files),filenames):
    one_data = cv2.imread(Path+filename, 0) #cv2で画像を読み込んで
#     plt.imshow(one_data)
#     plt.show()
#     one_data = cv2.resize(one_data,(h, w)) #認識NNに合わせてサイズ変換し
    train[i] = one_data[400:656, 400:656]
del one_data

x_train = train.reshape(-1, w, h, 1)/255
del train
#VGG16
#Conv層
input_tensor = Input(shape = (w, h, 1))
vgg16 = VGG16(include_top=False,input_tensor=input_tensor)
vgg16.summary()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

設定ファイル ~/.keras/keras.json で "image_data_format": "channels_last" とちゃんとなっていますか?

 追記

自分の環境で試したところ、確かに1チャンネルでは質問のエラーが出ました。

from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.layers import Input

# 学習済みモデル VGG16 を構築する。
h, w, c = 256, 256, 1
input_tensor = Input(shape = (w, h, c))
vgg16 = VGG16(include_top=False, input_tensor=input_tensor)
ValueError: Shapes (3, 3, 1, 64) and (64, 3, 3, 3) are incompatible

Keras のコードを調べたところ、コンストラクタの引数で weights='imagenet' となっており、何も指定しない場合は ImageNet で学習済みのモデルを使用するようになっています。これは3チャンネル画像の入力のモデルであるため、重みを読み込む際に不整合となりエラーとなっておりました。

質問者さんが取れる対策は次のいずれかです。

weights=None と指定し、ImageNet の学習済みモデルを使用しない。

# 学習済みモデル VGG16 を構築する。
h, w, c = 256, 256, 3
input_tensor = Input(shape = (w, h, c))
vgg16 = VGG16(include_top=False, weights=None, input_tensor=input_tensor)

2 入力をRGB画像に変換する。

OpenCV の場合

cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)

フルスクラッチで学習する場合は1、ImageNet の学習済みモデルを使用したい場合は2を選んでください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/14 08:59

    keras.jsonの中身は
    {
    "floatx": "float32",
    "epsilon": 1e-07,
    "backend": "tensorflow",
    "image_data_format": "channels_last"
    }
    とあるのでchannel_lastは設定してあるように思えます。

    キャンセル

  • 2018/11/14 20:02

    kerasであればbackendでtensorflowを使っていますが構築されているモデルにinputレイヤーが含まれていますよ。
    上記の書き方はinputレイヤーが重複してますね。
    グレースケールの画像を3chにするかinputレイヤーを自分で書き換えてあげれば動くと思います。

    キャンセル

  • 2018/11/15 00:46 編集

    channel_last になっていないのが原因かと思ったのですが、原因は別にありました。失礼しました。
    デフォルト引数が weights='imagenet' となっているため、チャンネル数を変更するとカーネルの形状が変わってしまうため、重みの読み込みでエラーになります。
    なので、weights=None にすれば、エラーにならないはずです。

    キャンセル

  • 2018/11/15 11:53

    回答ありがとうございます。
    提示して頂いた方法で動作を確認することができましたし、原因も把握することができました。
    ありがとうございます。

    キャンセル

0

そのvgg16がどこから来てるのかよくわかりませんが、多分スクラッチじゃなないのであればc,w,hの順番でモデル構築されてると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/14 11:50

    モデルは~/.keras/keras.jsonにあります。カラースケールの入力ではきちんと動作したのでw,h,cの順番で合っていると考えています。

    キャンセル

0

VGGの学習済みモデルのはじめのConv層は3ch->64chへ変換するように定義されているため,(None, h, w, 1)の1chのグレースケール画像を入力として受けることができません.

対応としては,

  1. 無理やりグレースケール画像を3chにして入力する.
    例えば,以下のようになります.
train = np.zeros((num_files, h, w, 3)) #画像データの箱を用意し
# #画像をひとつずつ読み込み箱に入れていく
# two_data = cv2.imread(Path+filenames[1], 0)
# plt.imshow(two_data, cmap = "gray")
# plt.show()
for i,filename in zip(range(num_files),filenames):
    one_data = cv2.imread(Path+filename, 0) #cv2で画像を読み込んで
#     plt.imshow(one_data)
#     plt.show()
#     one_data = cv2.resize(one_data,(h, w)) #認識NNに合わせてサイズ変換し
    one_data = np.tile(one_data, (1, 1, 3))
    train[i] = one_data[400:656, 400:656, :]
  1. keras.applicationのVGGを自分で書き換えたPythonファイルを作る.

の2点が考えられると思います.

以上です.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る