在 tf.keras 的 model.fit 中,有没有办法将每个样本分批传递 n 次?
Posted
技术标签:
【中文标题】在 tf.keras 的 model.fit 中,有没有办法将每个样本分批传递 n 次?【英文标题】:In model.fit in tf.keras, is there a way to pass each sample in a batch n times? 【发布时间】:2021-09-13 18:34:17 【问题描述】:我正在尝试为利用 Monte Carlo (MC) 辍学的模型编写自定义损失函数。我希望模型在将预测输入到损失函数之前,以批次 n 次运行每个样本。当前的玩具代码如下所示。该模型有 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)
y_true
和 y_pred
的当前形状是 (None,10)
,None
是 batch_size。我希望能够为批次中的每个样本提供 n 个值,这样我就可以获得每个样本的均值和标准差以用于损失函数。我想要这些值,因为每个样本的平均值和标准偏差应该是唯一的,而不是在一个批次中的所有样本中获取。 mu
和 sigma
的当前形状是 (10,)
,我希望它们是 (None,10)
,这意味着 y_true
和 y_pred
的形状是 (None,n,10)
。
我怎样才能做到这一点?
【问题讨论】:
【参考方案1】:我相信经过一些实验后我找到了解决方案。修改后的代码如下所示。
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)
所以我现在要做的是围绕中间轴堆叠输入和输出,创建 n 个相同的所有输入和输出样本集。虽然 tensorflow 显示警告,因为模型是在不知道该中间轴的情况下创建的。它仍然可以正常训练,并且形状符合预期。
注意:由于 y_true 现在的形状为 (None,n,10)
,因此您必须取中间轴的平均值,因为所有 n 都相同。
【讨论】:
以上是关于在 tf.keras 的 model.fit 中,有没有办法将每个样本分批传递 n 次?的主要内容,如果未能解决你的问题,请参考以下文章
使用 tf.keras.Model.fit 进行训练时如何将自定义摘要添加到 tensorboard
tf.keras model.fit():在相同数据上火车损失和val损失之间的巨大差异
model.predict 不适用于 Keras 自定义层(推理错误)
Keras中的TypeError:即使已经提供了shuffle =“batch”,也要传递shuffle =“batch”