Can';在Keras/Tensorflow中增加损耗的两种不同方法不能一起使用吗?

Can';在Keras/Tensorflow中增加损耗的两种不同方法不能一起使用吗?,tensorflow,keras,autoencoder,loss,Tensorflow,Keras,Autoencoder,Loss,我写了下面的代码通过一个自动编码器做了一个简单的实验,我只想用两个损耗,第一个损耗是输入和输出的传统MSE损耗,它是由AE的潜在向量重建的,第二个损耗是编码器和解码器中对称层的两个输出之间的MSE损耗,也就是说,如果AE有5层,我想在第二层和第四层之间添加一个MSE损耗,因为它们是对称的。代码如下: from time import time import numpy as np import random from keras.models import Model import keras.

我写了下面的代码通过一个自动编码器做了一个简单的实验,我只想用两个损耗,第一个损耗是输入和输出的传统MSE损耗,它是由AE的潜在向量重建的,第二个损耗是编码器和解码器中对称层的两个输出之间的MSE损耗,也就是说,如果AE有5层,我想在第二层和第四层之间添加一个MSE损耗,因为它们是对称的。代码如下:

from time import time
import numpy as np
import random
from keras.models import Model
import keras.backend as K
from keras.engine.topology import Layer, InputSpec
from keras.layers import Dense, Input, GaussianNoise, Layer, Activation
from keras.models import Model
from keras.optimizers import SGD, Adam
from keras.utils.vis_utils import plot_model
from keras.callbacks import EarlyStopping

#build vae model

input_place = Input(shape=(128,))

e_layer1 = Dense(64,activation='relu')(input_place)
e_layer2 = Dense(32,activation='relu')(e_layer1)
hidden = Dense(16,activation='relu')(e_layer2)

d_layer1 = Dense(32,activation='relu')(hidden)
d_layer2 = Dense(64,activation='relu')(d_layer1)

output_place = Dense(128,activation='sigmoid')(d_layer2)

model = Model(inputs=input_place,outputs=output_place)

loss = K.mean(K.square(d_layer1 - e_layer2),axis = -1)

model.add_loss(loss)

model.compile(optimizer = 'adam',
              loss=['mse'],
              metrics=['accuracy'])

input_data = np.random.randn(400,128)

model.fit(input_data,
          input_data,
          batch_size = 32,
          epochs=5)
但是当我运行这段代码时,它发生了一个关于

Epoch 1/5
 32/400 [=>............................] - ETA: 12s - loss: 1.6429 - acc: 0.0000e+00Traceback (most recent call last):

  File "<ipython-input-49-eac3a65824ec>", line 1, in <module>
    runfile('/Users/jishilun/Desktop/keras_loss_test.py', wdir='/Users/jishilun/Desktop')

  File "/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 704, in runfile
    execfile(filename, namespace)

  File "/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/Users/jishilun/Desktop/keras_loss_test.py", line 49, in <module>
    epochs=5)

  File "/anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 1039, in fit
    validation_steps=validation_steps)

  File "/anaconda3/lib/python3.7/site-packages/keras/engine/training_arrays.py", line 204, in fit_loop
    callbacks.on_batch_end(batch_index, batch_logs)

  File "/anaconda3/lib/python3.7/site-packages/keras/callbacks.py", line 115, in on_batch_end
    callback.on_batch_end(batch, logs)

  File "/anaconda3/lib/python3.7/site-packages/keras/callbacks.py", line 236, in on_batch_end
    self.totals[k] += v * batch_size

ValueError: operands could not be broadcast together with shapes (32,) (16,) (32,) 
1/5纪元
32/400[=>………]-预计到达时间:12秒-损失:1.6429-附件:0.0000e+00回溯(最近一次呼叫):
文件“”,第1行,在
运行文件('/Users/jishilun/Desktop/keras_loss_test.py',wdir='/Users/jishilun/Desktop')
文件“/anaconda3/lib/python3.7/site packages/spyder_kernels/customize/spyderrcustomize.py”,第704行,在runfile中
execfile(文件名、命名空间)
文件“/anaconda3/lib/python3.7/site packages/spyder_kernels/customize/spyderrcustomize.py”,第108行,在execfile中
exec(编译(f.read(),文件名,'exec'),命名空间)
文件“/Users/jishilun/Desktop/keras_loss_test.py”,第49行,在
时代=5)
文件“/anaconda3/lib/python3.7/site-packages/keras/engine/training.py”,第1039行,适合
验证步骤=验证步骤)
文件“/anaconda3/lib/python3.7/site packages/keras/engine/training\u arrays.py”,第204行,在fit\u循环中
回调。在批处理结束时(批处理索引、批处理日志)
文件“/anaconda3/lib/python3.7/site packages/keras/callbacks.py”,第115行,在末尾
回调。在批处理结束时(批处理,日志)
文件“/anaconda3/lib/python3.7/site packages/keras/callbacks.py”,第236行,在“批处理”末尾
自身总计[k]+=v*批量大小
ValueError:操作数无法与形状(32,)(16,)(32,)一起广播
如果我删除了add_loss,代码就可以运行了,所以我认为Keras/Tensorflow中添加_loss的两种方法不能简单地一起使用,或者可能会有一些变化(可能是小批量的问题?) 请帮帮我!欢迎您提供任何意见或建议!
多谢各位

问题不是来自
添加损耗()
,而是来自您的
批量大小。您的输入数据是
(400128)
,但
批量大小是32。尝试将其更改为400的因式分解数,例如40或20,它将起作用

您的代码在这里运行得非常好。你确定这是“你的”代码还是你简化了它?问题似乎只是形状不匹配。?这是我的代码真的>\u我根据您的建议更改了代码,代码可以工作,谢谢!但我仍然有一个问题:如果样本数是一个素数,而且它很大(可能超过5000),我应该如何运行代码??我认为如果批处理单元的大小太大(等于样本数),GPU的内存就会溢出。这可能是一个版本特定的错误。我向您保证,您发布的代码在这里运行良好,没有任何更改。@FlightPanda24如果您去掉上一批的一些示例,应该可以。@DanielMöller您对keras的版本是什么?我很好奇,为什么fit方法没有像“keep_-employer”这样的论点,或者一些标记我们是否应该保留提醒的东西。什么是“keep_-employer”?剩余的?通常它只是在最后运行一个较小的批次。这是Keras 2.3.0