みなさん、こんにちは、
みむすたーです。
本日は、
ValueError: Data cardinality is ambiguous: と言うエラーが出て解消できない!
と言うお悩みにお答えします。
私自身、このエラーに1時間ほど悩まされ、ようやく解消できました。
みなさんには、すぐに解決していただけるよう、説明していきたいと思います。
それでは、いきましょう。
もくじ
エラーの意味
ValueError: Data cardinality is ambiguous:
データの集合に含まれる要素の数が曖昧だと言われています。
ソースコード
私の場合、以下のコードでこのエラーが発生しました。
理由は、もちろんmodel.fit()関数に指定するlearn_datasに問題がありました。
では、どのように問題があったか次の項目でご説明します。
%tensorflow_version 2.x
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models
from sklearn import datasets
# 順伝播
model = models.Sequential()
# 入力層 - 隠れ層 のモデル追加
model.add(layers.Dense(32,activation='relu',input_shape=(64,),name="relu_layer"))
# 隠れ層 - 出力層 のモデル追加
model.add(layers.Dense(10,activation='softmax',input_shape=(32,),name="softmax_layer"))
# 最適化関数=adam、誤差関数=クロスエントロピー、評価関数=多項分類器、で設定
model.compile(optimizer="adam",
loss="binary_crossentropy",
metrics=["categorical_accuracy"])
# 手書きの10進数データを取り出す
datas = datasets.load_digits().data
target_index_list = datasets.load_digits().target
# one-hot表現への変換
target = np.zeros((len(target_index_list),10))
for i, target_index in enumerate(target_index_list):
target[i][target_index] = 1
# 学習用データとテストデータを分ける
learn_datas = []
learn_datas.extend(datas[0::3])
learn_datas.extend(datas[1::3])
learn_target = []
learn_target.extend(target[0::3])
learn_target.extend(target[1::3])
test_datas = datas[2::3]
test_target = target[2::3]
# 学習開始
history = model.fit(learn_datas,learn_target,batch_size=len(learn_datas),epochs=2000,verbose=0)
# 学習後データ取得
middle_weight, middle_bias, last_weight, last_bias = model.get_weights()
# テストデータで出力を試みる
middle_u = np.dot(test_datas, middle_weight) + middle_bias
middle_out = np.maximum(0, middle_u)
last_u = np.dot(middle_out, last_weight) + last_bias
last_out = np.exp(last_u) / np.sum(np.exp(last_u))
上のpythonのコードを実行した結果は以下の通りです。
sr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/data_adapter.py in __init__(self, x, y, sample_weights, sample_weight_modes, batch_size, epochs, steps, shuffle, **kwargs)
280 label, ", ".join(str(i.shape[0]) for i in nest.flatten(data)))
281 msg += "Please provide data which shares the same first dimension."
--> 282 raise ValueError(msg)
283 num_samples = num_samples.pop()
284
ValueError: Data cardinality is ambiguous:
エラーの理由
model.fitで2次元配列を指定する場合は、本来以下のように指定する必要があります。
# OKなパターン array( [[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.], [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])
しかし、私の場合は、上のコードで以下のような形の配列を設定していました。
# NGなパターン [array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), array([0., 0., 0., 1., 0., 0., 0., 0., 0., 0.]), array([0., 1., 0., 0., 0., 0., 0., 0., 0., 0.]), array([0., 0., 0., 0., 1., 0., 0., 0., 0., 0.])]
arrayはnumpyの配列 nparray のことです。
なぜ下側の配列指定だとダメだったかと言うと、
以下のリンクで記載されている通りなんですが、
https://keras.io/ja/models/model/
model.fitの引数 x で指定する配列は、nparrayでなければならなかったのです。
下側の配列指定を見ると、pythonのプリミティブな配列で囲っています。
そのため、kerasでエラーが出力されています。
内容は以上です。
コメント