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

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

ただいまの
回答率

88.80%

ValueError: Input 0 is incompatible with layer conv3d_6: expected ndim=5, found ndim=4

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 452

tukutuku

score 14

学習の入力には2048×512の画像を512×512×4の3次元配列にしたものを、教師には512×512の2次元画像を用いています。
画像はグレースケール画像です。

ValueError: Input 0 is incompatible with layer conv3d_6: expected ndim=5, found ndim=4
上記のエラーがでて困っています。解決方法わかる方いらっしゃいましたら、ご教示いただけますと幸いです。

import os
import cv2
import numpy as np
from keras.layers import Input, Conv3D, MaxPooling3D, UpSampling3D, Add
from keras.models import Model
import keras.optimizers as optimizers
from tensorflow.python.keras import backend as K
import matplotlib.pyplot as plt

import tensorflow as tf

gpuConfig = tf.ConfigProto(
    gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=1.0),
    device_count={'GPU': 2})
with tf.Session(config=gpuConfig) as session:


 IMAGE_SIZE = 512
EPOCHS = 30


# ディレクトリ内の画像を読み込む
# inputpath: ディレクトリ文字列,imagesize: 画像サイズ, type_color: ColorかGray
def load_images(inputpath, imagesize, type_color):
    imglist = []

    for root, dirs, files in os.walk(inputpath):
        for fn in sorted(files):
            bn, ext = os.path.splitext(fn)
            if ext not in [".bmp", ".BMP", ".jpg", ".JPG", ".jpeg", ".JPEG", ".png", ".PNG"]:
                continue

            filename = os.path.join(root, fn)

            if type_color == 'Color':
                # カラー画像の場合
                testimage = cv2.imread(filename, cv2.IMREAD_COLOR)
                # サイズ変更
                height, width = testimage.shape[:2]
                testimage = cv2.resize(testimage, (imagesize, imagesize), interpolation = cv2.INTER_AREA)  #主に縮小するのでINTER_AREA使用
                testimage = np.asarray(testimage, dtype=np.float64)
                # チャンネル,高さ,幅に入れ替え.data_format="channels_first"を使うとき必要
                #testimage = testimage.transpose(2, 0, 1)
                # チャンネルをbgrの順からrgbの順に変更
                testimage = testimage[::-1]

            elif type_color == 'Gray':
                # グレースケール画像の場合
                testimage = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
                # 2次元配列を3次元配列に変換する
                testimage = np.asarray([testimage], dtype=np.float64)
                testimage = np.asarray(testimage, dtype=np.float64).reshape(4, 512, 512)
                # チャンネルの次元がないので1次元追加する
                testimage = np.asarray([testimage], dtype=np.float64)
                testimage = np.asarray(testimage, dtype=np.float64).reshape(1, 4, 512, 512)
                # 深さ、高さ,幅,チャンネルに入れ替え.data_format="channels_last"を使うとき必要
                testimage = testimage.transpose(1, 2, 3, 0)

            imglist.append(testimage)
    imgsdata = np.asarray(imglist, dtype=np.float32)

    return imgsdata, sorted(files)  # 画像リストとファイル名のリストを返す

def load_images2(inputpath, imagesize, type_color):
    imglist = []

    for root, dirs, files in os.walk(inputpath):
        for fn in sorted(files):
            bn, ext = os.path.splitext(fn)
            if ext not in [".bmp", ".BMP", ".jpg", ".JPG", ".jpeg", ".JPEG", ".png", ".PNG"]:
                continue

            filename = os.path.join(root, fn)

            if type_color == 'Color':
                # カラー画像の場合
                testimage = cv2.imread(filename, cv2.IMREAD_COLOR)
                # サイズ変更
                height, width = testimage.shape[:2]
                testimage = cv2.resize(testimage, (imagesize, imagesize), interpolation = cv2.INTER_AREA)  #主に縮小するのでINTER_AREA使用
                testimage = np.asarray(testimage, dtype=np.float64)
                # チャンネル,高さ,幅に入れ替え.data_format="channels_first"を使うとき必要
                #testimage = testimage.transpose(2, 0, 1)
                # チャンネルをbgrの順からrgbの順に変更
                testimage = testimage[::-1]

            elif type_color == 'Gray':
                # グレースケール画像の場合
                testimage = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
                # サイズ変更
                height, width = testimage.shape[:2]
                testimage = cv2.resize(testimage, (imagesize, imagesize), interpolation = cv2.INTER_AREA)  #主に縮小するのでINTER_AREA使用
                # チャンネルの次元がないので1次元追加する
                testimage = np.asarray([testimage], dtype=np.float64)
                testimage = np.asarray(testimage, dtype=np.float64).reshape((1, imagesize, imagesize))
                # 高さ,幅,チャンネルに入れ替え.data_format="channels_last"を使うとき必要
                testimage = testimage.transpose(1, 2, 0)

            imglist.append(testimage)
    imgsdata = np.asarray(imglist, dtype=np.float32)

    return imgsdata, sorted(files)  # 画像リストとファイル名のリストを返す

# 指定ディレクトリに画像リストの画像を保存する
# savepath: ディレクトリ文字列, filenamelist: ファイル名リスト, imagelist: 画像リスト
def save_images(savepath, filenamelist, imagelist):
    for i, fn in enumerate(filenamelist):
        filename = os.path.join(savepath, fn)
        testimage = imagelist[i]
        #testimage = np.delete(testimage, 2, 1)  # グレースケール画像を保存するときだけ使用.チャンネルに相当する3列目削除
        cv2.imwrite(filename, testimage)


#%%
# データ準備
# 画像読み込み
# training用の低解像度画像と高解像度画像読み込み
imagelow_train, imagelow_train_filenames = load_images("ファイル名", (2048, 512), 'Gray')
imagehigh_train, imagehigh_train_filenames = load_images2("ファイル名", IMAGE_SIZE, 'Gray')
# test用の低解像度画像と高解像度画像読み込み
imagelow_test, imagelow_test_filenames = load_images("ファイル名", (2048, 512), 'Gray')
imagehigh_test, imagehigh_test_filenames = load_images2("ファイル名", IMAGE_SIZE, 'Gray')

image_infer, image_infer_filenames = load_images("ファイル名", (2048, 512), 'Gray')

# 画素値0-1正規化
imagelow_train /= 255.0
imagehigh_train /= 255.0
imagelow_test /= 255.0
imagehigh_test /= 255.0
image_infer /= 255.0

#%%
# ネットワークの定義
# Deep Denoising Super Resolution CNN
def network_ddsrcnn():
    #Input(InputImageSize, InputImgageSize, Channel)
    input_img = Input((IMAGE_SIZE, IMAGE_SIZE, 1), dtype='float')

    enc1 = Conv3D(64, kernel_size=3, activation="relu", padding='same')(input_img)
    enc1 = Conv3D(64, kernel_size=3, activation="relu", padding='same')(enc1)
    down1 = MaxPooling3D(pool_size=2)(enc1)

    enc2 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(down1)
    enc2 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(enc2)
    down2 = MaxPooling3D(pool_size=2)(enc2)

    enc3 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(down2)
    enc3 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(enc3)
    down3 = MaxPooling3D(pool_size=2)(enc3)

    enc4 = Conv3D(256, kernel_size=3, activation="relu", padding='same')(down3)

    up4 = UpSampling3D(size=2)(enc4)
    dec4 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(up4)
    dec4 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(dec4)

    add3 = Add()([dec4, enc3])
    up3 = UpSampling3D(size=2)(add3)
    dec3 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(up3)
    dec3 = Conv3D(128, kernel_size=3, activation="relu", padding='same')(dec3)

    add2 = Add()([dec3, enc2])
    up2 = UpSampling3D(size=2)(add2)
    dec2 = Conv3D(64, kernel_size=3, activation="relu", padding='same')(up2)
    dec2 = Conv3D(64, kernel_size=3, activation="relu", padding='same')(dec2)

    add1 = Add()([dec2, enc1])
    dec1 = Conv3D(1, kernel_size=5, activation="linear", padding='same')(add1)

    model = Model(input=input_img, output=dec1)

    return model

model = network_ddsrcnn()

# ネットワークを表示
print(model.summary())


#%%
def psnr(y_true, y_pred):
    return -10*K.log(K.mean(K.flatten((y_true - y_pred))**2))/np.log(10)

# trainingの設定
adam = optimizers.Adam(lr=1e-3)
model.compile(loss='mean_squared_error', optimizer='adam', metrics=[psnr])


from keras.callbacks import ModelCheckpoint

#エポックごとにモデル保存
os.makedirs('model', exist_ok=True)
model_checkpoint = ModelCheckpoint(
        filepath=os.path.join('model', 'model_{epoch:02d}_h5'),
        monitor='val_loss', period=5,
        verbose=1)

# training実行
# training用低解像度画像と高解像度画像でtrainingする.validation用にtest用の低解像度画像と高解像度画像を使用する.
training = model.fit(imagelow_train, imagehigh_train,
                     epochs=EPOCHS, batch_size=20, shuffle=True, validation_data=(imagelow_test, imagehigh_test),
                     callbacks=[model_checkpoint], verbose=1)


#%%
# training結果をファイルに保存
# ネットワーク定義保存
#json_string = model.to_json()
#open("keras_ddsrcnn14_model_json", "w").write(json_string)
# 重み
#model.save_weights('keras_ddsrcnn14_weight_hdf5')

# 学習履歴グラフ表示
def plot_history(history):
    plt.plot(history.history['psnr'])
    plt.plot(history.history['val_psnr'])
    plt.title('model accuracy')
    plt.xlabel('epoch')
    plt.ylabel('accuracy')
    plt.legend(['psnr', 'val_psnr'], loc='lower right')
    plt.show()

    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('model loss')
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.legend(['loss', 'val_loss'], loc='lower right')
    plt.show()

plot_history(training)

#%%
# test用低解像度画像を用いた推定の実行
results = model.predict(image_infer, verbose=1)
# 推定結果の画像をファイル保存
results *= 255.0    # 0-1の範囲の値が出力されるので見やすいように255倍する
save_images(".\\result\\", imagelow_test_filenames, results)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

まだ回答がついていません

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

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

関連した質問

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