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

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

ただいまの
回答率

89.07%

kerasで学習モデルを作成したいがエラーが発生してしまう。

解決済

回答 1

投稿

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

genosuke

score 12

前提・実現したいこと

人物画のリアルタイム顔検出をしたいため、モナリザの学習モデルの作成をしようと以下のプログラムを実行したところ、

ValueError: You are passing a target array of shape (765, 1) while using as loss categorical_crossentropycategorical_crossentropy expects targets to be binary matrices (1s and 0s) of shape (samples, classes). If your targets are integer classes, you can convert them to the expected format via:

from keras.utils import to_categorical
y_binary = to_categorical(y_int)

Alternatively, you can use the loss function sparse_categorical_crossentropy instead, which does expect integer targets.

とこのようなエラーメッセージが表示され、学習が進まない状況です。
原因がわかる方どこに問題があるのか教えていただけると助かります。

発生している問題・エラーメッセージ

Using TensorFlow backend.
(32, 32, 3)
gakusyu.py:32: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(16, (3, 3), input_shape=(32, 32, 3..., padding="same")`
  model.add(Convolution2D(16, 3, 3, border_mode="same", input_shape=in_shape))
2019-12-06 14:14:10.771488: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
gakusyu.py:36: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(16, (3, 3), padding="same")`
  model.add(Convolution2D(16, 3, 3, border_mode="same"))
gakusyu.py:46: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(32, (3, 3), padding="same")`
  model.add(Convolution2D(32, 3, 3, border_mode="same"))
gakusyu.py:50: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(32, (3, 3), padding="same")`
  model.add(Convolution2D(32, 3, 3, border_mode="same"))
gakusyu.py:58: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same")`
  model.add(Convolution2D(64, 3, 3, border_mode="same"))
gakusyu.py:62: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same")`
  model.add(Convolution2D(64, 3, 3, border_mode="same"))
gakusyu.py:72: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (3, 3), padding="same")`
  model.add(Convolution2D(128, 3, 3, border_mode="same"))
gakusyu.py:105: UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`.
  model.fit(X, y, batch_size=50, nb_epoch=100)
Traceback (most recent call last):
  File "gakusyu.py", line 124, in <module>
    main()
  File "gakusyu.py", line 22, in main
    model = model_train(X_train, y_train)
  File "gakusyu.py", line 105, in model_train
    model.fit(X, y, batch_size=50, nb_epoch=100)
  File "C:\Users\Taisei\Anaconda3\envs\opencv\lib\site-packages\keras\engine\training.py", line 1154, in fit
    batch_size=batch_size)
  File "C:\Users\Taisei\Anaconda3\envs\opencv\lib\site-packages\keras\engine\training.py", line 642, in _standardize_user_data
    y, self._feed_loss_fns, feed_output_shapes)
  File "C:\Users\Taisei\Anaconda3\envs\opencv\lib\site-packages\keras\engine\training_utils.py", line 284, in check_loss_and_target_compatibility
    ' while using as loss `categorical_crossentropy`. '

ValueError: You are passing a target array of shape (765, 1) while using as loss `categorical_crossentropy`. `categorical_crossentropy` expects targets to be binary matrices (1s and 0s) of shape (samples, classes). If your targets are integer classes, you can convert them to the expected format via:

from keras.utils import to_categorical
y_binary = to_categorical(y_int)


Alternatively, you can use the loss function `sparse_categorical_crossentropy` instead, which does expect integer targets.

該当のソースコード

from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils
import numpy as np

# 分類対象のカテゴリ
root_dir = "C:\python code"
categories = ["output"]
nb_classes = len(categories)
#image_size = 50

# データをロード --- (※1)
def main():
    X_train, X_test, y_train, y_test = np.load("monariza.npy")
    # データを正規化する
    X_train = X_train.astype("float") / 256
    X_test  = X_test.astype("float")  / 256
    y_train = np_utils.to_categorical(y_train, nb_classes)
    y_test  = np_utils.to_categorical(y_test, nb_classes)
    # モデルを訓練し評価する    
    model = model_train(X_train, y_train)
    model_eval(model, X_test, y_test)

# モデルを構築 --- (※2)
def build_model(in_shape):
    model = Sequential()

    print(in_shape)
    #畳み込み層の作成
    #1層目の追加  1024個の層を最初に作り、フィルター3*3のフィルターを16個作成
    model.add(Convolution2D(16, 3, 3, border_mode="same", input_shape=in_shape)) 
    model.add(Activation("relu"))

    #2層目の畳み込み層
    model.add(Convolution2D(16, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

     #プーリング層
    model.add(MaxPooling2D())

    #Dropoutとは過学習を防ぐためのもの 0.5は次のニューロンへのパスをランダムに半分にするという意味
    model.add(Dropout(0.5))

    #3層目の作成
    model.add(Convolution2D(32, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

    #4層目の作成
    model.add(Convolution2D(32, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

     #プーリング層
    model.add(MaxPooling2D())
    model.add(Dropout(0.5))

    #5層目
    model.add(Convolution2D(64, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

    #6層目
    model.add(Convolution2D(64, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

    #プーリング層
    model.add(MaxPooling2D())

    #Dropout
    model.add(Dropout(0.5))

    #7層目
    model.add(Convolution2D(128, 3, 3, border_mode="same"))
    model.add(Activation("relu"))

    #Dropout
    model.add(Dropout(0.5))

    #平坦化
    model.add(Flatten())

    #8層目 全結合層 FC
    model.add(Dense(100))
    model.add(Activation("relu"))

    #Dropout
    model.add(Dropout(0.5))

    #8層目 引数nub_classesとは分類の数を定義する。
    model.add(Dense(nb_classes))
    model.add(Activation('softmax'))

    #ここまででモデルの層完成

    #lossは損失関数を定義するところ
    model.compile(loss="categorical_crossentropy", 
        metrics   = ["accuracy"], 
        optimizer = "adam"
    )
    return model


# モデルを訓練する --- (※3)
def model_train(X, y):
    model = build_model(X.shape[1:])
    model.fit(X, y, batch_size=50, nb_epoch=100)

    #学習モデルの保存
    json_string = model.to_json()
     #モデルのファイル名 拡張子.json
    open('C:\python code\monariza2.json', 'w').write(json_string)

    # モデルを保存する --- (※4)
    hdf5_file = "C:\python code\monariza-model.hdf5"
    model.save_weights(hdf5_file)
    return model

# モデルを評価する --- (※5)
def model_eval(model, X, y):
    score = model.evaluate(X, y)
    print('loss=', score[0])
    print('accuracy=', score[1])

if __name__ == "__main__":
    main()

試したこと

インターネットで解決策を探しましたが見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

ソースコードや手順はすべてこちらのサイトから参考にさせていただいてます。
https://ai-coordinator.jp/face-recognition#i-6

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

エラーメッセージにそのまま解決方法が書かれておりますし、過去に同じような質問もあります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/12/07 01:05

    ご回答ありがとうございます。
    過去の質問通りにloss='categorical_crossentropy',の部分を
    loss=='sparse_categorical_crossentropy'に変更するとValueErrorは出なくなりましたが、また別のエラーで、
    tensorflow.python.framework.errors_impl.InvalidArgumentError: Received a label value of 1 which is outside the valid range of [0, 1). Label values: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    [[node loss/activation_9_loss/sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at C:\Users\Taisei\Anaconda3\envs\opencv\lib\site-packages\tensorflow_core\python\framework\ops.py:1751) ]] [Op:__inference_keras_scratch_graph_2819]

    Function call stack:
    keras_scratch_graph
    と表示されてしまい学習が進まないです。
    もし解決策がお分かりでしたらご回答お願いいただけないでしょうか。。
    何度も申し訳ございません。

    キャンセル

  • 2019/12/07 09:43

    「=」は1つで十分(質問者が間違えたのだと思う)ですが、そのようにしておりますか?

    キャンセル

  • 2019/12/07 09:58

    …と思ったけれど、categoriesが1種類(nb_classesが1)しかないですね。
    categorical_crossentropyやsparse_categorical_crossentropyは「複数のクラスのうちどれなのか」というときに使うものなので、以下のようにする必要があります。
    - 2つ以上のクラスにする(例:「人間である」「そうでない」、「人物Aである」「人物Bである」など)
    - 1つの出力値だけが必要なのであれば、最後のActivationを'softmax'から他のもの(例:'sigmoid')にし、lossも変更する(例:'binary_crossentropy')
    (そもそも、モナリザの画像だけでは学習できない気がしますがどうなのでしょう)

    キャンセル

  • 2019/12/07 14:04

    ご回答ありがとうございます。
    Activationとlossを教えていただいた通りに変更すると無事学習させることができました!
    本当にありがとうございます!!
    せっかくなので2つ以上のクラスにした場合も試したいと思います。
    ありがとうございました!!

    キャンセル

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

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

関連した質問

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