Keras:使用模型输出作为另一个输入:将符号张量输入模型时,我们希望张量具有静态批量大小
Keras: Using model output as the input for another: When feeding symbolic tensors to a model, we expect thetensors to have a static batch size
我有以下两个模型,首先训练model_A
,然后model_A
的输出用于训练model_C
:
import keras
from keras.layers import Input, Dense
from keras.models import Model
inputs = Input(shape=(12,))
# ---------------------------------------
# model_A
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions_A = Dense(3, activation='softmax')(x)
model_A = Model(inputs=inputs, outputs=predictions_A)
model_A.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model_A.fit(my_data_x, axis = 1), pd.get_dummies(my_data['target_cate'],prefix=['cate_']))
#----------------------------------------
input_C_out_A = Input(shape=(3,))
# Concatenating the two input layers
concat = keras.layers.concatenate([inputs, input_C_out_A])
x1 = Dense(64, activation='relu')(concat)
x1 = Dense(64, activation='relu')(x1)
predictions_C= Dense(1, activation='sigmoid')(x1)
model_C = Model(inputs=[inputs, input_C_out_A], outputs=predictions_C)
model_C.compile(loss='mean_squared_error', optimizer='adam')
model_C.fit([my_data_x,predictions_A], my_data['target_numeric'])
model_A训练好像没问题,后来训练model_C时出现如下错误:
Epoch 1/1
374667/374667 [==============================] - 11s 30us/step - loss: 0.3157 - acc: 0.9119
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-78-8df7b1dec93f> in <module>
28 model_C = Model(inputs=[inputs, input_C_out_A], outputs=predictions_C)
29 model_C.compile(loss='mean_squared_error', optimizer='adam')
---> 30 model_C.fit([my_data_x,predictions_A], my_data['target_numeric'])
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
--> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
749 feed_input_shapes,
750 check_batch_axis=False, # Don't enforce the batch size.
--> 751 exception_prefix='input')
752
753 if y is not None:
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
90 data = data.values if data.__class__.__name__ == 'DataFrame' else data
91 data = [data]
---> 92 data = [standardize_single_array(x) for x in data]
93
94 if len(data) != len(names):
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in <listcomp>(.0)
90 data = data.values if data.__class__.__name__ == 'DataFrame' else data
91 data = [data]
---> 92 data = [standardize_single_array(x) for x in data]
93
94 if len(data) != len(names):
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_single_array(x)
23 'When feeding symbolic tensors to a model, we expect the'
24 'tensors to have a static batch size. '
---> 25 'Got tensor with shape: %s' % str(shape))
26 return x
27 elif x.ndim == 1:
ValueError: When feeding symbolic tensors to a model, we expect thetensors to have a static batch size. Got tensor with shape: (None, 3)
知道我错过了什么吗?谢谢!
将模型的输出(符号张量)放入 model.fit
是没有意义的,因为那里没有输入数据。您应该首先从模型 A 获得预测,然后使用它们来拟合模型 C:
pred_a = model_A.predict(my_data_x)
model_C.fit([my_data_x, pred_a], my_data['target_numeric'])
model_C
的工作人员:
- 将输入数据提供给
model_A
,
- 获取
model_A
和 的输出
- 将其与原始输入一起提供给第一个
Dense
层。
所以按照你说的去做(并尽量保持模型独立,即每个模型都有自己的 input/output 层):
input_C = Input(shape=(12,))
out_A = model_A(input_C) # get the output of model_A
concat = keras.layers.concatenate([input_C, out_A])
x1 = Dense(64, activation='relu')(concat)
x1 = Dense(64, activation='relu')(x1)
predictions_C= Dense(1, activation='sigmoid')(x1)
model_C = Model(inputs=input_C, outputs=predictions_C)
model_C.compile(loss='mean_squared_error', optimizer='adam')
model_C.fit(my_data_x, my_data['target_numeric'])
如果你不希望 model_A
在训练 model_C
时被训练(即如果你已经训练 model_A
并且不希望其权重被改变) , 在编译之前设置model_A.trainable = False
model_C
.
我有以下两个模型,首先训练model_A
,然后model_A
的输出用于训练model_C
:
import keras
from keras.layers import Input, Dense
from keras.models import Model
inputs = Input(shape=(12,))
# ---------------------------------------
# model_A
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions_A = Dense(3, activation='softmax')(x)
model_A = Model(inputs=inputs, outputs=predictions_A)
model_A.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model_A.fit(my_data_x, axis = 1), pd.get_dummies(my_data['target_cate'],prefix=['cate_']))
#----------------------------------------
input_C_out_A = Input(shape=(3,))
# Concatenating the two input layers
concat = keras.layers.concatenate([inputs, input_C_out_A])
x1 = Dense(64, activation='relu')(concat)
x1 = Dense(64, activation='relu')(x1)
predictions_C= Dense(1, activation='sigmoid')(x1)
model_C = Model(inputs=[inputs, input_C_out_A], outputs=predictions_C)
model_C.compile(loss='mean_squared_error', optimizer='adam')
model_C.fit([my_data_x,predictions_A], my_data['target_numeric'])
model_A训练好像没问题,后来训练model_C时出现如下错误:
Epoch 1/1
374667/374667 [==============================] - 11s 30us/step - loss: 0.3157 - acc: 0.9119
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-78-8df7b1dec93f> in <module>
28 model_C = Model(inputs=[inputs, input_C_out_A], outputs=predictions_C)
29 model_C.compile(loss='mean_squared_error', optimizer='adam')
---> 30 model_C.fit([my_data_x,predictions_A], my_data['target_numeric'])
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
--> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
749 feed_input_shapes,
750 check_batch_axis=False, # Don't enforce the batch size.
--> 751 exception_prefix='input')
752
753 if y is not None:
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
90 data = data.values if data.__class__.__name__ == 'DataFrame' else data
91 data = [data]
---> 92 data = [standardize_single_array(x) for x in data]
93
94 if len(data) != len(names):
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in <listcomp>(.0)
90 data = data.values if data.__class__.__name__ == 'DataFrame' else data
91 data = [data]
---> 92 data = [standardize_single_array(x) for x in data]
93
94 if len(data) != len(names):
~/workspace/git/tensorplay/venv/lib/python3.7/site-packages/keras/engine/training_utils.py in standardize_single_array(x)
23 'When feeding symbolic tensors to a model, we expect the'
24 'tensors to have a static batch size. '
---> 25 'Got tensor with shape: %s' % str(shape))
26 return x
27 elif x.ndim == 1:
ValueError: When feeding symbolic tensors to a model, we expect thetensors to have a static batch size. Got tensor with shape: (None, 3)
知道我错过了什么吗?谢谢!
将模型的输出(符号张量)放入 model.fit
是没有意义的,因为那里没有输入数据。您应该首先从模型 A 获得预测,然后使用它们来拟合模型 C:
pred_a = model_A.predict(my_data_x)
model_C.fit([my_data_x, pred_a], my_data['target_numeric'])
model_C
的工作人员:
- 将输入数据提供给
model_A
, - 获取
model_A
和 的输出
- 将其与原始输入一起提供给第一个
Dense
层。
所以按照你说的去做(并尽量保持模型独立,即每个模型都有自己的 input/output 层):
input_C = Input(shape=(12,))
out_A = model_A(input_C) # get the output of model_A
concat = keras.layers.concatenate([input_C, out_A])
x1 = Dense(64, activation='relu')(concat)
x1 = Dense(64, activation='relu')(x1)
predictions_C= Dense(1, activation='sigmoid')(x1)
model_C = Model(inputs=input_C, outputs=predictions_C)
model_C.compile(loss='mean_squared_error', optimizer='adam')
model_C.fit(my_data_x, my_data['target_numeric'])
如果你不希望 model_A
在训练 model_C
时被训练(即如果你已经训练 model_A
并且不希望其权重被改变) , 在编译之前设置model_A.trainable = False
model_C
.