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

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

ただいまの
回答率

90.51%

  • Python

    11753questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Keras

    473questions

kerasでCNNをはじめてやる画像認識(入力層の4次元テンソルなのに3次元のまま どうすれば追加可能か)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,120

FALLOT

score 10

イメージ説明

画像データはグレースケールにして二値化しています.

白丸が横方向に移動して内部の最大応力が発生した箇所を白丸ごとにラベリングしました.
MLPでは経験者なのですが,CNNは初心者なので何がなんだかわかんない状況です.以下のエラーが出ておりどこを修正すればいいのかご教授願います.

ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (4000, 90, 90)

おそらく,
data_format: 文字列で,"channels_last"(デフォルト)"(batch, height, width, channels)"
TensorFlowでは(サンプル数, 画像の行数, 画像の列数, チャネル数)
バックエンドでTFを使っています.

という形なので,ミニバッチを付け足せばいいと思うのですがどうすればよいですか?

from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers import Activation, Dense, Dropout, Flatten
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
from keras.models import load_model
from keras.callbacks import EarlyStopping, ModelCheckpoint, CSVLogger
import numpy as np
from PIL import Image
import os
import time
import csv


start_time = time.time()
print("開始時刻: " + str(start_time))

# 学習用のデータを作る.
image_list = []
label_list = []

#ハイパーパラメータ
#画像サイズ
x = 90
y = 90
A = x*y #入力のノード数
#エポック数
B = 50
#バッチサイズ
BATCH_SIZE = 32
#学習率
LR = 0.00001
#出力ノード数
output =4


# ./data/train 以下のa,b,cのディレクトリ以下の画像を読み込む。
for dir in os.listdir("data/train"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/train/" + dir 
    label = 0

    if dir == "a":    # 左下に最大応力:ラベル0
        label = 0
    elif dir == "b": # 右下に最大応力:ラベル1
        label = 1
    elif dir == "c": # 右下に最大応力:ラベル1
        label = 2
    elif dir == "d": # 右下に最大応力:ラベル1
        label = 3




    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label) #わからない
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((x, y)))
            print(image.shape)
            print(filepath)
            #image =np.reshape(image, A)
            print(image.shape)
            print('\n')
            image_list.append(image / 255.)


# kerasに渡すためにnumpy配列に変換。
image_list = np.array(image_list)




# ラベルの配列を1と0からなるラベル配列に変更
# 0 -> [1,0], 1 -> [0,1] という感じ。
Y = to_categorical(label_list) #わからない

print("入力データの確認")
print(image_list.shape)
#np.savetxt("check/input_data_pixel.csv",image_list,delimiter=",")
print("ラベルデータの確認")   
print(Y.shape)
#np.savetxt("check/label_data.csv",Y,delimiter=",")


# モデルを生成してニューラルネットを構築
model = Sequential()

model.add(Conv2D(32,3,input_shape=(x,y,1),kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(Activation('relu'))
model.add(Conv2D(32,3,kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(Activation('relu'))

model.add(Conv2D(64,3,kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(Activation('relu'))

model.add(Flatten())
model.add(Dense(810))
model.add(Activation('relu'))
model.add(Dropout(1.0))


model.add(Dense(output))
model.add(Activation("softmax"))

# オプティマイザ(最適化)にAdamを使用
opt = Adam(lr=LR)
# モデルをコンパイル
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) #わからない
#CSVに各エポックの学習結果の保存
csv_logger = CSVLogger('result/training.csv')
# 学習を実行。20%はテストに使用。
history = model.fit(image_list, Y, nb_epoch=B,verbose=1,callbacks=[csv_logger], batch_size=BATCH_SIZE, validation_split=0.2) 



# テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。
total = 0.
ok_count = 0.
#最終の学習結果の表示
loss, accuracy = model.evaluate(image_list, Y)
print("\nloss:{} accuracy:{}".format(loss, accuracy))
#最終の学習結果を書き込む
fp = open("result/RESULT.txt","w")
fp.write("\nloss:{} accuracy:{}".format(loss, accuracy))
fp.close()
#正解率の書き込み
f = open("result/ANSWER.txt","w")

for dir in os.listdir("data/train"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/test/" + dir 
    label = 0

    if dir == "a":    # 左下に最大応力:ラベル0
        label = 0
    elif dir == "b": # 右下に最大応力:ラベル1
        label = 1
    elif dir == "c": # 右下に最大応力:ラベル1
        label = 2
    elif dir == "d": # 右下に最大応力:ラベル1
        label = 3



    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((x, y)))
            print(filepath)
            image =np.reshape(image, A)
            result = model.predict_classes(np.array([image / 255.]))
            print("label:", label, "result:", result[0])
            L = label
            R = result[0]
            f.write(filepath)
            f.write("\nlabel:{} result:{}\n".format(L, R) )
            total += 1.

            if label == result[0]:
                ok_count += 1.




print("正答率: ", ok_count / total * 100, "%")
SEIKAI =ok_count / total * 100
f.write("\n正答率:{}".format(SEIKAI))

end_time = time.time()
print("終了時刻: ",end_time)
print ("かかった時間: ", (end_time - start_time))

ttime = end_time - start_time
fa = open("result/TIME.txt","w")
fa.write("\nかかった時間:{} ".format(ttime))
fa.close()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

Conv2D は (BatchSize, Height, Width, Channels) の4次元テンソルの入力を期待しているので、(4000, 90, 90) だとエラーになります。

np.expand_dims(x, axis=-1) で (4000, 90, 90, 1) と末尾に1次元追加すれば、その部分は解決するかと思います。

あと前の質問でプーリングしないほうがいいと書きましたが、そうするとパラメータ数がとても多くなってしまうので、やはり入れたほうがいいかもしれません。

試しに、質問の課題よりは簡単な簡易的なものですが、サンプルコードを作ってみました。

以下のように4つの正規分布に従う点群を生成して、

イメージ説明

その点を中心に円を描画して4クラス1000枚の画像で構成されるデータセットを作って、CNN でクラス分類を学習するサンプルです。

イメージ説明

イメージ説明

 追記

まず畳み込みですが、カーネルをスライドさせて線形和で出力を計算する画像処理でいう「フィルタリング」という処理を行っています。

イメージ説明

線形和なので例えば、出力の1つの要素を計算するには、以下のニューロンの結合で計算するのと同じですね。

イメージ説明

このフィルタリングですが、重み次第でエッジであったり、特定の色であったり様々な情報を抽出できます。
つまり、フィルタの種類をたくさん用意しておけば、それだけ多くの特定が抽出できます。
下は ResNet の1層目の畳み込み層の馬の入力画像に対する各カーネルによる出力結果です。カーネルの種類によって、エッジや色など抽出されているのがわかると思います。

イメージ説明

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/15 23:13

    ありがとうございます。
    確かにプーリングは入れた方がよさそうですね。今日、勉強していたのですがコンボリュートで、画像細かくフィルタリングしていくと増えていくということですよね。
    ちなみに、この32とフィルターの3×3はどのように効いてくるのでしょうか?
    色々調べてると、デフォルトで皆さんそうしてるので、もしよろしければ教えて頂けると幸いです。

    キャンセル

  • 2018/11/15 23:30 編集

    32はカーネル (フィルタ) の数です。
    それだけたくさんの特徴が抽出できると考えてください。(3, 3) はカーネルサイズです。小さいほうが細かい画像の局所的な特徴を抽出できます。また小さいほうがパラメータや計算量が少なくてすむので、VGG16以降は3x3がよく使われていますね。

    回答にも追記したので、参考にしてください。

    キャンセル

  • 2018/11/16 12:47

    ありがとうございます・
    初歩的な質問で申し訳ないのですが,CNNでも回帰分析を行うことは可能ですか?
    入力データは上記の画像で,れの出力データとして最大応力の値や座標を入れていきたいと考えています.
    今回は,ラベルデータの判別をしていますが..

    キャンセル

  • 2018/11/16 12:52

    畳み込み層ではそのような流れなのですね.理解しました.
    フィルタの重みはどこで設定されているのでしょうか?
    プーリング層では対象領域の最大(もしくは平均)を取って画像を圧縮しているという理解で大丈夫でしょうか?

    キャンセル

  • 2018/11/16 13:00

    出力層の出力数を近似したい関数の出力数に変えて、損失関数を mse にすればよいです。
    下記の解説などを参考にしてください。

    https://qiita.com/cvusk/items/33867fbec742bda3f307

    > フィルタの重みはどこで設定されているのでしょうか?

    それを誤差逆伝播法で自動で学習するのが、CNN です。

    > プーリング層では対象領域の最大(もしくは平均)を取って画像を圧縮しているという理解で大丈夫でしょうか?

    その理解であっています。
    詳しく解説するには、このコメント欄のやり取りでは難しいので、まず書籍を1つ参照されることをおすすめします。

    実装しながら学びたい場合は「ゼロから作るdeep learning」
    数式を追いながら学びたい場合は「深層学習 (機械学習プロフェッショナルシリーズ)」がおすすめです。
    Keras に特化した解説は「PythonとKerasによるディープラーニング」や「直感 Deep Learning ―Python×Kerasでアイデアを形にするレシピ」があります。
    直近では Keras でいろいろ実装されるのであれば、とりあえず Keras の解説本を1つ購入されてはどうでしょうか

    キャンセル

  • 2018/11/19 12:18

    連絡が遅くなりました。
    一通り、勉強したところプーリングで最大か平均があるのですが、色々調べると最大が一般的で明確な違いがわかりませんでした。違いをご存知ですか?
    あと、はじめてCNNをやる際には畳み込みとプーリングを連続するだけのニューラルネットがよいでしょうか?
    私の場合、画像が円の微小変位なので特徴が学習しづらいと思います。

    キャンセル

  • 2018/11/20 14:02

    > 違いをご存知ですか?

    フィルタ内の平均をとるか、最大をとるかの違いです。

    > はじめてCNNをやる際には畳み込みとプーリングを連続するだけのニューラルネットがよいでしょうか?

    そうですね。まずはそのようなシンプルなモデルから試すのがよいと思います。
    学習しづらいと思っても以外といけたりする可能性もあるので、どうなるかはわからないです。

    キャンセル

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

  • Python

    11753questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Keras

    473questions

  • トップ
  • Pythonに関する質問
  • kerasでCNNをはじめてやる画像認識(入力層の4次元テンソルなのに3次元のまま どうすれば追加可能か)