简体   繁体   English

在 tf.keras 中的 model.fit 中,有没有办法将每个样本分批传递 n 次?

[英]In model.fit in tf.keras, is there a way to pass each sample in a batch n times?

I am trying to write a custom loss function for a model that utilizes Monte Carlo (MC) dropout.我正在尝试为利用 Monte Carlo (MC) dropout 的模型编写自定义损失函数。 I want the model to run through each sample in a batch n times before feeding the predictions to the loss function.我希望模型在将预测提供给损失函数之前分批运行每个样本n次。 A current toy code is shown below.当前的玩具代码如下所示。 The model has 24 inputs and 10 outputs with 5000 training samples.该模型有 24 个输入和 10 个输出,有 5000 个训练样本。

import numpy as np
import tensorflow as tf

X = np.random.rand(5000,24)
y = np.random.rand(5000,10)

def MC_Loss(y_true,y_pred):
    mu = tf.math.reduce_mean(y_pred,axis=0)
    #error = tf.square(y_true-mu)
    error = tf.square(y_true-y_pred)
    var = tf.math.reduce_variance(y_pred,axis=0)
    return tf.math.divide(error,var)/2 + tf.math.log(var)/2 + tf.math.log(2*np.pi)/2

input_layer = tf.keras.layers.Input(shape=(X.shape[1],))
hidden_layer = tf.keras.layers.Dense(units=100,activation='elu')(input_layer)
do_layer = tf.keras.layers.Dropout(rate=0.20)(hidden_layer,training=True)
output_layer = tf.keras.layers.Dense(units=10,activation='sigmoid')(do_layer)

model = tf.keras.models.Model(input_layer,output_layer)
model.compile(loss=MC_Loss,optimizer='Adam')

model.fit(X,y,epochs=100,batch_size=128,shuffle=True)

The current shape of y_true and y_pred are (None,10) with None being the batch_size. y_truey_pred的当前形状是(None,10)其中None是 batch_size。 I want to be able to have n values for each sample in the batch, so I can get the mean and standard deviation for each sample to use in the loss function.我希望批次中的每个样本都有n 个值,因此我可以获得每个样本的均值和标准差以用于损失函数。 I want these value, because the mean and standard deviation should be unique to each sample, not taken across all samples in a batch.我想要这些值,因为平均值和标准偏差对于每个样本应该是唯一的,而不是在一个批次中的所有样本中进行。 The current shape of mu and sigma are (10,) and I would want them to be (None,10) which would mean y_true and y_pred have the shape (None,n,10) . musigma的当前形状是(10,) ,我希望它们是(None,10)这意味着y_truey_pred具有形状(None,n,10)

How can I accomplish this?我怎样才能做到这一点?

I believe I found the solution after some experimentation.我相信我在一些实验后找到了解决方案。 The modified code is shown below.修改后的代码如下所示。

import numpy as np
import tensorflow as tf

n = 100

X = np.random.rand(5000,24)
X1 = np.concatenate(([X.reshape(X.shape[0],1,X.shape[1]) for _ in range(n)]),axis=1)
y = np.random.rand(5000,10)
y1 = np.concatenate(([y.reshape(y.shape[0],1,y.shape[1]) for _ in range(n)]),axis=1)

def MC_Loss(y_true,y_pred):
    mu = tf.math.reduce_mean(y_pred,axis=1)
    obs = tf.math.reduce_mean(y_true,axis=1)
    error = tf.square(obs-mu)
    var = tf.math.reduce_variance(y_pred,axis=1)
    return tf.math.divide(error,var)/2 + tf.math.log(var)/2 + tf.math.log(2*np.pi)/2

input_layer = tf.keras.layers.Input(shape=(X.shape[1]))
hidden_layer = tf.keras.layers.Dense(units=100,activation='elu')(input_layer)
do_layer = tf.keras.layers.Dropout(rate=0.20)(hidden_layer,training=True)
output_layer = tf.keras.layers.Dense(units=10,activation='sigmoid')(do_layer)

model = tf.keras.models.Model(input_layer,output_layer)
model.compile(loss=MC_Loss,optimizer='Adam')

model.fit(X1,y1,epochs=100,batch_size=128,shuffle=True)

So what I am now doing is stacking the inputs and outputs about an intermediate axis, creating n identical sets of all input and output samples.所以我现在要做的是围绕中间轴堆叠输入和输出,创建n 个相同的所有输入和输出样本集。 While tensorflow shows a warning because the model is created without knowledge of this intermediate axis.虽然 tensorflow 显示警告,因为模型是在不了解此中间轴的情况下创建的。 It still trains with no issues and the shapes are as expected.它仍然可以正常训练,并且形状符合预期。

Note: since y_true now has the shape (None,n,10) , you have to take the mean about the intermediate axis which gives you the true value since all n are identical.注意:由于 y_true 现在具有形状(None,n,10) ,因此您必须取中间轴的平均值,因为所有n都是相同的,因此它为您提供真实值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM