我的模型有两个输入分支,input1 2D灰度图像和input2彩色图像。使用连接方法合并两个输入分支,并使用softmax函数对其进行分类。该模型运行良好,但问题在于了解多个输入模型中softmax的操作以及两个分支中权重的更新方式。
答案 0 :(得分:0)
即使在多个输入/输出模型的情况下,softmax函数和损失函数的性能也与单个输入/输出模型相似。如果我们仅将单个损失函数传递给模型,则除非为多个输出指定不同的损失函数和不同的激活函数,否则相同的损失函数将应用于每个输出。
请考虑以下模型,该模型具有形状为(32, 32, 3)
(即(height, width, channels)
)的图像输入和形状为(None, 10)
(即(timesteps, features)
)的时间序列输入。我们的模型将具有根据这些输入的组合计算出的两个输出:“得分”(形状为(1,)
)和五类概率分布(形状为(5,)
)。
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
image_input = keras.Input(shape=(32, 32, 3), name='img_input')
timeseries_input = keras.Input(shape=(None, 10), name='ts_input')
x1 = layers.Conv2D(3, 3)(image_input)
x1 = layers.GlobalMaxPooling2D()(x1)
x2 = layers.Conv1D(3, 3)(timeseries_input)
x2 = layers.GlobalMaxPooling1D()(x2)
x = layers.concatenate([x1, x2])
score_output = layers.Dense(1, name='score_output')(x)
class_output = layers.Dense(5, name='class_output')(x)
model = keras.Model(inputs=[image_input, timeseries_input],
outputs=[score_output, class_output])
让我们绘制此模型,以便您可以清楚地看到我们在这里做什么(请注意,图中显示的形状是批处理形状,而不是按样本的形状)。
keras.utils.plot_model(model, 'multi_input_and_output_model.png', show_shapes=True)
如果我们仅将单个损失函数传递给模型,则将相同的损失函数应用于每个输出,这在此处不合适。
以合适的方式将数据传递到多输入或多输出模型的工作方式与在编译中指定损失函数的方式类似:您可以传递Numpy数组的列表(以1:1映射到接收损失的输出函数)或命令将输出名称映射到训练数据的Numpy数组。
model.compile(
optimizer=keras.optimizers.RMSprop(1e-3),
loss=[keras.losses.MeanSquaredError(),
keras.losses.CategoricalCrossentropy(from_logits=True)])
# Generate dummy Numpy data
img_data = np.random.random_sample(size=(100, 32, 32, 3))
ts_data = np.random.random_sample(size=(100, 20, 10))
score_targets = np.random.random_sample(size=(100, 1))
class_targets = np.random.random_sample(size=(100, 5))
# Fit on lists
model.fit([img_data, ts_data], [score_targets, class_targets],
batch_size=32,
epochs=3)
# Alternatively, fit on dicts
model.fit({'img_input': img_data, 'ts_input': ts_data},
{'score_output': score_targets, 'class_output': class_targets},
batch_size=32,
epochs=3)
输出-
Train on 100 samples
Epoch 1/3
100/100 [==============================] - 2s 22ms/sample - loss: 5.2477 - score_output_loss: 0.1809 - class_output_loss: 5.3292
Epoch 2/3
100/100 [==============================] - 0s 191us/sample - loss: 4.8558 - score_output_loss: 0.1235 - class_output_loss: 4.5884
Epoch 3/3
100/100 [==============================] - 0s 202us/sample - loss: 4.7482 - score_output_loss: 0.1421 - class_output_loss: 4.5786
Train on 100 samples
Epoch 1/3
100/100 [==============================] - 0s 260us/sample - loss: 4.6704 - score_output_loss: 0.1377 - class_output_loss: 4.5686
Epoch 2/3
100/100 [==============================] - 0s 204us/sample - loss: 4.6210 - score_output_loss: 0.2038 - class_output_loss: 4.5260
Epoch 3/3
100/100 [==============================] - 0s 188us/sample - loss: 4.6014 - score_output_loss: 0.1678 - class_output_loss: 4.3346
<tensorflow.python.keras.callbacks.History at 0x7f8cc43a9ac8>