keras模型输出的设置对训练结果的一个奇怪影响

Background

环境:python 3.6.0 + tensorflow-gpu 1.12.0 + Keras 2.2.4
用 keras 写的一个模型(训练 Model 中涉及两个 trainable 的子 Model),通过 add_loss 的方式为模型设置损失,形如:

loss_tensor = loss_1(...) + loss_2(...)  # 将 loss 写成 tensor
# 此 model 的损失中涉及两个 trainable 的子 model
model.add_loss(loss_tensor)  # add_loss 的方式
model.compile(Adam())

这种写法下,用 fit_generator 的方式训练模型时,generator 只需要 yield 模型的输入数据就行,target 的部分直接上 None,即:

def generator_no_target():
	...
	yield [data_1, data_2], None

那么讲道理,模型训练应该同当初建立模型时的输出部分无关
我的意思是:模型有两个输出,写成(写法1):

model = Model([input_1, input_2], [ouput_1, output_2])

但在这种情况下,写成(写法2):

model = Model([input_1, input_2], ouput_1)

应该不会影响训练?(因为训练的时候 target data 传的是 None 啊)

Problem

然而,写法1训练效果正常写法2训练效果非常差
这是为什么?
这种模型输出的设置是怎么影响模型训练过程的
难道有两个 trainable 的子 model 就要有两个输出吗?

Further Testing

1. 不用 add_loss 的方式,而是定义损失函数

即前面第一块代码写成:

# loss_tensor = loss_1(...) + loss_2(...)
def loss_fn(y_true, y_pred):  # 将 loss 写成函数
	return loss_1(...) + loss_2(...)
# model.add_loss(loss)
model.compile(Adam(), loss=loss_fn)  # 在 compile 里指明 loss 函数

这时训练数据的 target 部分需要传入数据,于是在 generator 的 yield 那里补上 target 的部分,用全 0 补,即 generator 写成:

def generator_with_target():
	...
	# yield [data_1, data_2], None
	fake_target = np.zeros((BATCH_SIZE, DIM), dtype=np.float32)  # 全零
	# yield [data_1, data_2], fake_target  # 若模型有一个输出
	yield [data_1, data_2], [fake_target, fake_target]  # 若模型有两个输出

(其中 yield 的那句,模型输出只有一个 output 就只返回一个 fake_target,有两个就返回两个)
没有变化,依然有这个奇怪的差异

2. 不用 fit_generator,而是用 train_on_batch

但是生成训练数据的 generator 还是之前那个,loss 用 add_loss 设置。
也没有用,同样有这个奇怪的差异

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值