0vb*_*vbb 5 python regression keras
假设您有一个以n神经元作为输出的 Keras 模型,其中每个神经元都与一个回归变量(例如汽车的速度、汽车的高度等)相关联,如下面的代码片段所示:
# define Keras model
input_layer = Input(shape=shape)
... # e.g. conv layers
x = Dense(n, activation='linear')(x)
model = Model(inputs=input_layer, outputs=x)
model.compile(loss='mean_absolute_error', optimizer='sgd', metrics=['mean_squared_error'])
history = model.fit_generator(...)
Run Code Online (Sandbox Code Playgroud)
现在,存储在历史字典中的 MAE 损失是单个数字,它是基于n- 维y_pred和y_true
数组计算的。因此,单个损失值是n标签的单个损失的平均值,正如在 Keras MAE 函数中所见:
def mean_absolute_error(y_true, y_pred):
return K.mean(K.abs(y_pred - y_true), axis=-1)
Run Code Online (Sandbox Code Playgroud)
但是,我想获得一个包含每个n标签损失的历史对象,即{loss: {'speed': loss_value_speed, 'height': loss_value_height}}. 理想情况下,训练期间的进度条还应显示单个损失而不是组合损失。
我怎样才能做到这一点?
我想可以为每个输出神经元编写一个自定义指标,它只计算y_pred和y_true向量中单个索引的损失,但这感觉像是一种解决方法:
def mean_absolute_error_label_0(y_true, y_pred):
# calculate the loss only for the first label, label_0
return K.mean(K.abs(y_pred[0] - y_true[0]), axis=-1)
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是为每个目标使用单独的输出层,并name为每个目标分配 a (即Dense(1, name='...'))。在您的情况下,这与使用输出层进行训练相同Dense(n),因为总损失只是各个损失的总和。
例如,
input_layer = Input(shape=(1000,))
x = Dense(100)(input_layer)
# name each output layer
target_names = ('speed', 'height')
outputs = [Dense(1, name=name)(x) for name in target_names]
model = Model(inputs=input_layer, outputs=outputs)
model.compile(loss='mean_absolute_error', optimizer='sgd', metrics=['mean_squared_error'])
Run Code Online (Sandbox Code Playgroud)
现在,当您拟合模型时,您应该能够分别查看每个目标的损失(和指标)。
X = np.random.rand(10000, 1000)
y = [np.random.rand(10000) for _ in range(len(outputs))]
history = model.fit(X, y, epochs=3)
Epoch 1/1
10000/10000 [==============================] - 1s 127us/step - loss: 0.9714 - speed_loss: 0.4768 - height_loss: 0.4945 - speed_mean_squared_error: 0.5253 - height_mean_squared_error: 0.5939
Epoch 2/3
10000/10000 [==============================] - 1s 101us/step - loss: 0.5109 - speed_loss: 0.2569 - height_loss: 0.2540 - speed_mean_squared_error: 0.0911 - height_mean_squared_error: 0.0895
Epoch 3/3
10000/10000 [==============================] - 1s 107us/step - loss: 0.5040 - speed_loss: 0.2529 - height_loss: 0.2511 - speed_mean_squared_error: 0.0873 - height_mean_squared_error: 0.0862
Run Code Online (Sandbox Code Playgroud)
保存到返回对象的损失history也将被命名。
print(history.history)
{'height_loss': [0.49454938204288484, 0.2539591451406479, 0.25108356306552887],
'height_mean_squared_error': [0.5939331066846848,
0.08951960142850876,
0.08619525188207626],
'loss': [0.9713814586639404, 0.5108571118354798, 0.5040025643348693],
'speed_loss': [0.47683207807540895, 0.25689796624183653, 0.25291900217533114],
'speed_mean_squared_error': [0.5252606071352959,
0.09107607080936432,
0.0872862442612648]}
Run Code Online (Sandbox Code Playgroud)
编辑:如果输出损失height取决于 的值speed,您可以:
Concatenate的输出heightmodel.compile()(一个用于speed连接输出,另一个用于连接输出height)input_layer = Input(shape=(1000,))
x = Dense(100)(input_layer)
# name each output layer
target_names = ('speed', 'height')
outputs = [Dense(1, name=name)(x) for name in target_names]
model = Model(inputs=input_layer, outputs=outputs)
model.compile(loss='mean_absolute_error', optimizer='sgd', metrics=['mean_squared_error'])
Run Code Online (Sandbox Code Playgroud)
输出将是:
X = np.random.rand(10000, 1000)
y = [np.random.rand(10000), np.random.rand(10000)]
history = model.fit(X, y, epochs=3)
Epoch 1/3
10000/10000 [==============================] - 5s 501us/step - loss: 1.0001 - speed_loss: 0.4976 - height_loss: 0.5026 - speed_mean_squared_error: 0.3315
Epoch 2/3
10000/10000 [==============================] - 2s 154us/step - loss: 0.9971 - speed_loss: 0.4960 - height_loss: 0.5011 - speed_mean_squared_error: 0.3285
Epoch 3/3
10000/10000 [==============================] - 1s 149us/step - loss: 0.9971 - speed_loss: 0.4960 - height_loss: 0.5011 - speed_mean_squared_error: 0.3285.
print(history.history)
{'height_loss': [0.502568191242218, 0.5011419380187988, 0.5011419407844544],
'loss': [1.0001451692581176, 0.9971360887527466, 0.9971360870361328],
'speed_loss': [0.4975769768714905, 0.4959941484451294, 0.4959941472053528],
'speed_mean_squared_error': [0.33153974375724793,
0.32848617186546325,
0.32848617215156556]}
Run Code Online (Sandbox Code Playgroud)