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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

1回答

1320閲覧

model.fit時の,ValueError: Layer "model" expects 2 input(s), but it received 1 input tensors. の改善方法

harug

総合スコア28

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2022/12/25 16:36

前提

現在,pythonを用いてResNet50v2 + ArcFaceの実装を行っています.
モデル構築自体はこちらを参考に行いました.

そこで,モデル構築を終えてoptunaを用いてパラメータチューニングを行おうとしたときに以下のようなエラーが発生しました.

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

以下のエラーは毎回のtrial時に発生します.

[I 2022-12-24 03:55:03,912] A new study created in memory with name: no-name-3fb7ffc6-9bc1-4f30-aaec-3bf89cc9b1ce Epoch 1: LearningRateScheduler setting learning rate to 0.000911662180442363. Epoch 1/100 [W 2022-12-24 03:55:06,429] Trial 0 failed because of the following error: The value None could not be cast to float. モデル定義内でエラー:in user code: File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1021, in train_function * return step_function(self, iterator) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1010, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1000, in run_step ** outputs = model.train_step(data) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 859, in train_step y_pred = self(x, training=True) File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler raise e.with_traceback(filtered_tb) from None File "/usr/local/lib/python3.8/dist-packages/keras/engine/input_spec.py", line 200, in assert_input_compatibility raise ValueError(f'Layer "{layer_name}" expects {len(input_spec)} input(s),' ValueError: Layer "model" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, 110, 110, 1) dtype=float32>] が発生 ・ ・ ・

該当のソースコード

以下が実際にし使用した,パラメータチューニングに関係するソースコードです.

python

1# 総クラス数,エポック数,入力画像のサイズを指定 2num_classes = 29 3epochs = 100 4height = 110 # 像のピクセル数(縦) 5width = 110 # 像のピクセル数(横)

python

1# ArcFaceの処理を記述 2class Arcfacelayer(Layer): 3 # s:softmaxの温度パラメータ, m:margin 4 def __init__(self, output_dim, s, m, easy_margin=False): 5 self.output_dim = output_dim 6 self.s = s 7 self.m = m 8 self.easy_margin = easy_margin 9 super(Arcfacelayer, self).__init__() 10 11 # 重みの作成 12 def build(self, input_shape): 13 # Create a trainable weight variable for this layer. 14 self.kernel = self.add_weight(name='kernel', 15 shape=(input_shape[0][1], self.output_dim), 16 initializer='uniform', 17 trainable=True) 18 super(Arcfacelayer, self).build(input_shape) 19 20 21 # mainの処理 22 def call(self, x): 23 24 y = x[1] 25 x_normalize = tf.math.l2_normalize(x[0]) # x = x'/ ||x'||2 26 k_normalize = tf.math.l2_normalize(self.kernel) # Wj = Wj' / ||Wj'||2 27 28 cos_m = K.cos(self.m) 29 sin_m = K.sin(self.m) 30 th = K.cos(np.pi - self.m) 31 mm = K.sin(np.pi - self.m) * self.m 32 33 cosine = K.dot(x_normalize, k_normalize) # W.Txの内積 34 sine = K.sqrt(1.0 - K.square(cosine)) 35 36 phi = cosine * cos_m - sine * sin_m #cos(θ+m)の加法定理 37 38 if self.easy_margin: 39 phi = tf.where(cosine > 0, phi, cosine) 40 41 else: 42 phi = tf.where(cosine > th, phi, cosine - mm) 43 44 # 正解クラス:cos(θ+m) 他のクラス:cosθ 45 output = (y * phi) + ((1.0 - y) * cosine) 46 output *= self.s 47 48 return output 49 50 def compute_output_shape(self, input_shape): 51 return (input_shape[0][0], self.output_dim) #入力[x,y]のためx[0]はinput_shape[0][0]

python

1# ResNet50v2 + ArcFace定義 2# 学習に使用 3def create_arcface_with_resnet50v2(input_shape, s, m): 4 # ResNet50V2の入力層の前に独自の入力層を追加 5 input_tensor = input_shape 6 print(input_tensor) 7 8 input_model = Sequential() 9 input_model.add(InputLayer(input_shape=input_tensor)) 10 input_model.add(Conv2D(3, (7, 7), padding='same')) 11 input_model.add(BatchNormalization()) 12 input_model.add(Activation('relu')) 13 14 resnet50v2 = ResNet50V2(include_top=False, weights=None, input_tensor=input_model.output) 15 16# DLしてある重みの読み込み 17 resnet50v2.load_weights('save_model(weights_imagenet)/weights_imagenet.hdf5', by_name=True) 18 19 20 flat = Flatten()(resnet50v2.layers[-1].output) 21 dense = Dense(512, activation="relu", name="hidden")(flat) 22 23 x = BatchNormalization()(dense) 24 25 yinput = Input(shape=(num_classes,)) #ArcFaceで使用 26 27 s_cos = Arcfacelayer(num_classes, s, m)([x,yinput]) #outputをクラス数と同じ数に 28 prediction = Activation('softmax')(s_cos) 29 30 model = Model(inputs=[resnet50v2.input, yinput], outputs=prediction) 31 32 return model

python

1# 学習率を返す関数 2def lr_schedul(epoch, lr): 3 if epoch < 3: 4 new_lr = lr 5 else: 6 new_lr = lr * math.exp(-0.1) 7 return new_lr 8 9 10# モデル定義 11def trainer(**param): 12 lr = param['lr'] 13 batch_size = param['batch_size'] 14 s = param['s'] 15 m = param['m'] 16 17 model = create_arcface_with_resnet50v2(input_shape, s, m) 18 19 # 自動的に学習をやめる 20 early_stopping = EarlyStopping(monitor='val_loss', 21 min_delta=0.0, 22 patience=3, 23 mode='min' 24 ) 25 # 最良の重みとモデルを保存 26 fpath = 'Weight/{}/{}_{}_{}_{}_({{epoch:02d}}-{{loss:.2f}}-{{accuracy:.2f}}-{{val_loss:.2f}}-{{val_accuracy:.2f}}).hdf5'.format(f_elem, batch_size, lr, s, m) 27 model_checkpoint = ModelCheckpoint(filepath=fpath, monitor='val_loss', save_best_only=True, mode='min') 28 # 学習中に学習率を調整 29 lr_scheduler = LearningRateScheduler(lr_schedul, verbose=1) 30 31 adam = Adam(learning_rate=lr) 32 model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy']) 33 34 35 try: 36 # メモリ使用量はモデル構造、入力サイズ、バッチサイズに依存 37 H = model.fit(x_train, y_train, 38 epochs=epochs, 39 verbose=1, 40 steps_per_epoch = math.ceil(num_train/batch_size), 41 validation_data=(x_test, y_test), 42 callbacks=[early_stopping, model_checkpoint, lr_scheduler]) 43 44 part = f_elem.split('/')[1] 45 M_path = 'Model/{}/{}_{}_{}_{}_model_{}.h5'.format(f_elem, batch_size, lr, s, m, part) 46 model.save(M_path) 47 48 #テストデータで精度を確認 49 score = model.evaluate(x_test, y_test) 50 51 #score[0]はloss 52 return score[0] # val_lossが最小であるモデルを探す 53 54 except Exception as e: 55 print(f'モデル定義内でエラー:{e}が発生') 56 57 58def objective(trial): 59 param = { 60 'lr':trial.suggest_float('lr', 1e-6, 1e-2, log=True), 61 'batch_size':trial.suggest_categorical('batch_size', [16, 32, 64]), 62 's':trial.suggest_float('s', 10, 50, log=False), 63 'm':trial.suggest_float('m', 0.0, 1.0, log=False) 64 } 65 66 val_loss = trainer(**param) # 各実行結果のval_lossの値を返す 67 68 return val_loss

上記のプログラムの実行の後,以下を実行すると先ほどのエラーが発生しました.

python

1num_train = len(x_train) 2num_valid = len(x_test) 3 4y_train = tf.cast(y_train, dtype='float32') 5y_test = tf.cast(y_test, dtype='float32') 6 7# optunaによるパラメータの最適化 8study = optuna.create_study(direction="minimize") 9study.optimize(objective, n_trials=100) # 何回実行するか

なお使用しているデータのshapeは以下のようになっています.
x_train.shape → (1566, 110, 110, 1)
y_train.shape → (1566,)

x_test.shape → (88, 110, 110, 1)
y_test.shape → (88,)

input_shape → (110, 110, 1)

試したこと

現在model.fitでエラーが発生しており,私が作成したモデルは2つの入力を想定しているのに対し,受け取った入力は一つしかないためエラーが発生した,というところまでは分かっています.
しかし,model.fitに渡したデータはx_train, y_trainと,2つの入力を与えているのにこのようなエラーが発生しているため自分ではなぜこのようなエラーが発生したのかが分かりません.

どなたかこのエラーの原因と改善方法を教えていただけますと助かります.
どうかよろしくお願いします.

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

ubuntu 20.04
Python 3.8.10

tensorflow-gpu 2.5.3
keras 2.8.0
numpy 1.19.5

jupyter lab 2.3.2

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PondVillege

2022/12/25 17:09 編集

参考元サイトおよび https://github.com/4uiiurz1/keras-arcface これを見る限り, model.fit(x_train, y_train) ではなく model.fit([x_train, y_train], y_train) である必要があるように感じました. エラーからも,2入力を要求しているにも関わらず,x_trainのみの単一入力が与えられたことによるエラーなので,これが原因であることを示唆しているものと思われます.
jbpb0

2022/12/26 09:30 編集

> 私が作成したモデルは2つの入力を想定しているのに対し,受け取った入力は一つしかないためエラーが発生した, > model.fitに渡したデータはx_train, y_trainと,2つの入力を与えているのにこのようなエラーが発生している ネットワークの入力と、「model.fit」の引数を、混同してるように思います https://weblabo.oscasierra.net/python/keras-mnist-sample.html を見てください 「実現したいこと (作成する人工知能の能力)」と書かれてるところの、「画像データ」がネットワークの入力です 一方、「ラベルデータ」はネットワークの入力ではありません 「ラベルデータ」は、「画像データ」がネットワークに入力された時のネットワークの出力(推論結果)が合ってるかどうか照合するのに使われます そのwebページのコードで「history = model.fit(x_train, y_train...」を実行してますが、その時の「x_train」が「画像データ」で、「y_train」が「ラベルデータ」です 上にも書いたように、「ラベルデータ」はネットワークの入力ではありません つまり、「model.fit(x_train, y_train...」で、ネットワークの入力は「x_train」だけです
harug

2023/01/12 16:21 編集

ご指摘ありがとうございます. model.fit([x_train, y_train], y_train) とすると一旦は問題なく動作しました. しかしこれでは,学習データにy_trainを与えてしまっているため推論時にはその都度クラスラベルを設定する手間が必要になってしまいます. そこで,さらに利便性を高めるためにy_trainを与えないでx_trainだけを与えるような1入力のモデルを構築したいと考えております(→詳しくは(https://teratail.com/questions/j5ajdz63iv4pgp)). お手すきの際にこちらも目を通していただけますと幸いです. ご対応ありがとうございました.
guest

回答1

0

自己解決

該当部分を以下のように変更したら無事エラーが解消しました.

python

1# 正解データの形式変更 2y_train = to_categorical(y_train, num_classes) 3y_test = to_categorical(y_test, num_classes) 4 5# 学習部分 6model.fit([x_train, y_train], y_train)

投稿2023/01/12 16:19

harug

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問