很抱歉出现一个小问题:
拥有在fit_generator模式下训练的NN,像这样:
Lambda(...)
或
Dense(...)
和自定义损失函数,什么是输入张量? 如果是Lambda图层,我是否正确期望(批处理大小,上一层的输出)? 如果自定义损失函数如下所示,它将是相同的(批大小,数据)吗?
triplet_loss(y_true, y_pred)
y_true,y_pred是(batch,上一层的输出)和(batch,我们馈送到NN的真实“预期”数据)格式吗?
答案 0 :(得分:0)
我可能会复制密集层。代替具有2个128个单位的层,而具有4个64个单位的层。结果是相同的,但是您将能够更好地执行叉积。
from keras.models import Model
#create dense layers and store their output tensors, they use the output of models 1 and to as input
d1 = Dense(64, ....)(Model_1.output)
d2 = Dense(64, ....)(Model_1.output)
d3 = Dense(64, ....)(Model_2.output)
d4 = Dense(64, ....)(Model_2.output)
cross1 = Lambda(myFunc, output_shape=....)([d1,d4])
cross2 = Lambda(myFunc, output_shape=....)([d2,d3])
#I don't really know what kind of "merge" you want, so I used concatenate, there are
Add, Multiply and others....
output = Concatenate()([cross1,cross2])
#use the "axis" attribute of the concatenate layer to define better which axis will
be doubled due to the concatenation
model = Model([Model_1.input,Model_2.input], output)
现在,使用lambda函数:
import keras.backend as K
def myFunc(x):
return x[0] * x[1]
答案 1 :(得分:0)
自定义损失函数,什么是输入张量?
这取决于您如何定义模型outputs
。
例如,让我们定义一个简单的模型,使输入保持不变。
model = Sequential([Lambda(lambda x: x, input_shape=(1,))])
让我们使用虚拟输入X和标签Y
x = [[0]]
x = np.array(x)
y = [[4]]
y = np.array(y)
如果我们的自定义损失功能如下所示
def mce(y_true, y_pred):
print(y_true.shape)
print(y_pred.shape)
return K.mean(K.pow(K.abs(y_true - y_pred), 3))
model.compile('sgd', mce)
然后我们可以看到y_true
和y_pred
的形状
y_true: (?, ?)
y_pred: (?, 1)
但是,对于triplet loss
,也可以像这样接收损失函数的输入-
ALPHA = 0.2
def triplet_loss(x):
anchor, positive, negative = x
pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1)
neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1)
basic_loss = tf.add(tf.subtract(pos_dist, neg_dist), ALPHA)
loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
return loss
# Source: https://github.com/davidsandberg/facenet/blob/master/src/facenet.py
def build_model(input_shape):
# Standardizing the input shape order
K.set_image_dim_ordering('th')
positive_example = Input(shape=input_shape)
negative_example = Input(shape=input_shape)
anchor_example = Input(shape=input_shape)
# Create Common network to share the weights along different examples (+/-/Anchor)
embedding_network = faceRecoModel(input_shape)
positive_embedding = embedding_network(positive_example)
negative_embedding = embedding_network(negative_example)
anchor_embedding = embedding_network(anchor_example)
loss = merge([anchor_embedding, positive_embedding, negative_embedding],
mode=triplet_loss, output_shape=(1,))
model = Model(inputs=[anchor_example, positive_example, negative_example],
outputs=loss)
model.compile(loss='mean_absolute_error', optimizer=Adam())
return model