我试图为一个利用蒙特卡洛(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)形状。
我怎样才能做到这一点?
发布于 2021-07-01 18:48:59
我相信经过一些实验我找到了解决办法。修改后的代码如下所示。
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都是相同的。
https://stackoverflow.com/questions/68214441
复制相似问题