我想在Python中实现自定义丢失函数,它应该像这个伪代码一样工作:
aux = | Real - Prediction | / Prediction
errors = []
if aux <= 0.1:
errors.append(0)
elif aux > 0.1 & <= 0.15:
errors.append(5/3)
elif aux > 0.15 & <= 0.2:
errors.append(5)
else:
errors.append(2000)
return sum(errors)
Run Code Online (Sandbox Code Playgroud)
我开始像这样定义指标:
def custom_metric(y_true,y_pred):
# y_true:
res = K.abs((y_true-y_pred) / y_pred, axis = 1)
....
Run Code Online (Sandbox Code Playgroud)
但我不知道如何获得if和else的res值.另外我想知道什么必须返回功能.
谢谢
确切地说,我正在寻找的损失函数是当绝对误差小于0.5时的平方误差,并且当绝对误差大于0.5时它是绝对误差本身.这样,误差函数的梯度不超过1,因为一旦平方误差函数的梯度达到1,绝对误差函数就会启动,并且梯度保持恒定为1.我已经将我当前的实现包含在下面.出于某种原因,它给我的性能不仅仅是平方误差.
fn_choice_maker1 = (tf.to_int32(tf.sign(y - y_ + 0.5)) + 1)/2
fn_choice_maker2 = (tf.to_int32(tf.sign(y_ - y + 0.5)) + 1)/2
choice_maker_sqr = tf.to_float(tf.mul(fn_choice_maker1, fn_choice_maker2))
sqr_contrib = tf.mul(choice_maker_sqr, tf.square(y - y_))
abs_contrib = tf.abs(y - y_)-0.25 - tf.mul(choice_maker_sqr, tf.abs(y - y_)-0.25)
loss = tf.reduce_mean(sqr_contrib + abs_contrib)
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
Run Code Online (Sandbox Code Playgroud)
choice_maker_sqr是一个列张量,只要误差介于0.5和-0.5之间就是一个.这些名字非常自我解释.
我开始用张量流编写神经元网络,我的每个示例项目中都有一个问题.
我的损失总是从50或更高的东西开始并且没有减少,或者如果它减少,它的确如此缓慢,以至于在我所有的时代之后我甚至没有接近可接受的损失率.
它已经尝试过的事情(并没有太大影响结果)
我根据https://youtu.be/vq2nnJ4g6N0的知识创建了网络
但是,让我们看看我的一个测试项目:
我有一个名单列表,并希望假设性别,所以我的原始数据如下所示:
names=["Maria","Paul","Emilia",...]
genders=["f","m","f",...]
Run Code Online (Sandbox Code Playgroud)
为了将它提供给网络,我将名称转换为charCodes数组(期望最大长度为30)并将性别转换为位数组
names=[[77.,97. ,114.,105.,97. ,0. ,0.,...]
[80.,97. ,117.,108.,0. ,0. ,0.,...]
[69.,109.,105.,108.,105.,97.,0.,...]]
genders=[[1.,0.]
[0.,1.]
[1.,0.]]
Run Code Online (Sandbox Code Playgroud)
我为输出层建立了3个隐藏层[30,20],[20,10],[10,10]和[10,2]的网络.所有隐藏层都具有ReLU作为激活功能.输出层具有softmax.
# Input Layer
x = tf.placeholder(tf.float32, shape=[None, 30])
y_ = tf.placeholder(tf.float32, shape=[None, 2])
# Hidden Layers
# H1
W1 = tf.Variable(tf.truncated_normal([30, 20], stddev=0.1))
b1 = tf.Variable(tf.zeros([20]))
y1 = tf.nn.relu(tf.matmul(x, W1) + b1)
# H2
W2 = tf.Variable(tf.truncated_normal([20, 10], stddev=0.1))
b2 = tf.Variable(tf.zeros([10]))
y2 = tf.nn.relu(tf.matmul(y1, W2) + b2)
# …Run Code Online (Sandbox Code Playgroud) 也许有人能够在这里帮助我.我正在尝试计算网络给定输出的交叉熵损失
print output
Variable containing:
1.00000e-02 *
-2.2739 2.9964 -7.8353 7.4667 4.6921 0.1391 0.6118 5.2227 6.2540
-7.3584
[torch.FloatTensor of size 1x10]
Run Code Online (Sandbox Code Playgroud)
和所需的标签,形式
print lab
Variable containing:
x
[torch.FloatTensor of size 1]
Run Code Online (Sandbox Code Playgroud)
其中x是0到9之间的整数.根据pytorch文档(http://pytorch.org/docs/master/nn.html)
criterion = nn.CrossEntropyLoss()
loss = criterion(output, lab)
Run Code Online (Sandbox Code Playgroud)
这应该工作,但不幸的是我得到一个奇怪的错误
TypeError: FloatClassNLLCriterion_updateOutput received an invalid combination of arguments - got (int, torch.FloatTensor, !torch.FloatTensor!, torch.FloatTensor, bool, NoneType, torch.FloatTensor, int), but expected (int state, torch.FloatTensor input, torch.LongTensor target, torch.FloatTensor output, bool sizeAverage, [torch.FloatTensor weights or None], torch.FloatTensor total_weight, int ignore_index) …Run Code Online (Sandbox Code Playgroud) 我在Keras有一个模型,我正在优化均方误差.但是,如果我losses.py在度量标准中使用与Keras中相同的代码,则会得到不同的结果.为什么是这样?
作为指标:
def MSE_metric(y_true, y_pred):
return K.mean(K.square(y_pred, y_true))
Run Code Online (Sandbox Code Playgroud)
对于模型:
model.compile(optimizer=SGD(lr=0.01, momntum=0.9), loss='MSE', metrics=[MSE_metric])
Run Code Online (Sandbox Code Playgroud)
这导致损失6.07但MSE_metric为0.47
什么会导致model.get_latest_training_loss()每个时期增加的损失?
用于训练的代码:
class EpochSaver(CallbackAny2Vec):
'''Callback to save model after each epoch and show training parameters '''
def __init__(self, savedir):
self.savedir = savedir
self.epoch = 0
os.makedirs(self.savedir, exist_ok=True)
def on_epoch_end(self, model):
savepath = os.path.join(self.savedir, "model_neg{}_epoch.gz".format(self.epoch))
model.save(savepath)
print(
"Epoch saved: {}".format(self.epoch + 1),
"Start next epoch ... ", sep="\n"
)
if os.path.isfile(os.path.join(self.savedir, "model_neg{}_epoch.gz".format(self.epoch - 1))):
print("Previous model deleted ")
os.remove(os.path.join(self.savedir, "model_neg{}_epoch.gz".format(self.epoch - 1)))
self.epoch += 1
print("Model loss:", model.get_latest_training_loss())
def train():
### Initialize model ###
print("Start training Word2Vec model")
workers …Run Code Online (Sandbox Code Playgroud) 我的问题与此处提出的问题类似: 喀拉拉邦将两个损失与可调整的权重相结合
但是,输出具有不同的维数,导致无法串联输出。因此,该解决方案不适用,是否有另一种方法可以解决此问题?
问题:
我有一个带有输出x1和x2的两层的keras功能模型。
x1 = Dense(1,activation='relu')(prev_inp1)
x2 = Dense(2,activation='relu')(prev_inp2)
Run Code Online (Sandbox Code Playgroud)
我需要在加权损失函数中使用这些x1和x2,就像在所附的图像中一样。将“相同损失”传播到两个分支。Alpha可以灵活地随迭代而变化。
在test set为 a 运行 6 个模型后,我在 上有以下评估指标binary classification problem:
accuracy logloss AUC
1 19% 0.45 0.54
2 67% 0.62 0.67
3 66% 0.63 0.68
4 67% 0.62 0.66
5 63% 0.61 0.66
6 65% 0.68 0.42
Run Code Online (Sandbox Code Playgroud)
我有以下问题:
1在logloss(logloss最接近于 0)方面是最好的,因为它的表现最差(就 而言accuracy)。这意味着什么 ?6具有较低的AUC比如模型得分5,当模型6具有更好accuracy。这意味着什么 ?我正在 Keras/Tensorflow 中训练 U-Net CNN,发现第一个时期的最后一批和第二个时期的第一批之间的损失大幅减少:
Epoch 00001: loss improved from inf to 0.07185 - categorical_accuracy: 0.8636
Epoch 2/400: 1/250 [.....................] - loss: 0.0040 - categorical_accuracy: 0.8878
Run Code Online (Sandbox Code Playgroud)
奇怪的是,分类准确率并没有随着损失而下降,而是略有增加。损失下降后,不会进一步减少,而是稳定在较低值附近。我知道关于该问题的信息很少,但这种行为可能表明存在一个常见问题,我可以进一步调查吗?
一些额外信息:Optimizer = Adam(lr=1e-4)(降低 lr 似乎没有帮助)
损失:‘类别加权分类交叉熵’,计算如下
def class_weighted_categorical_crossentropy(class_weights):
def loss_function(y_true, y_pred):
# scale preds so that the class probas of each sample sum to 1
y_pred /= tf.reduce_sum(y_pred, -1, True)
# manual computation of crossentropy
epsilon = tf.convert_to_tensor(K.epsilon(), y_pred.dtype.base_dtype)
y_pred = tf.clip_by_value(y_pred, epsilon, 1. - epsilon)
# Multiply each class by its weight: …Run Code Online (Sandbox Code Playgroud) 我正在训练一个 keras 模型,它的最后一层是一个sigmoid单元:
output = Dense(units=1, activation='sigmoid')
Run Code Online (Sandbox Code Playgroud)
我正在用一些训练数据训练这个模型,其中预期输出总是介于 0.0 和 1.0 之间的数字。我正在用均方误差编译模型:
model.compile(optimizer='adam', loss='mse')
Run Code Online (Sandbox Code Playgroud)
由于预期输出和实际输出都是介于 0 和 1 之间的单个浮点数,因此我也期望损失介于 0 和 1 之间,但是当我开始训练时,我得到了3.3932大于 1的损失。
我错过了什么吗?
编辑: 我正在添加一个示例来显示问题:https : //drive.google.com/file/d/1fBBrgW-HlBYhG-BUARjTXn3SpWqrHHPK/view?usp=sharing (我不能只粘贴代码,因为我需要附加训练数据)
运行后python stackoverflow.py,将显示模型的摘要,以及训练过程。我还在每一步打印 y_true 的最小值和最大值,以验证它们是否在 [0, 1] 范围内。无需等待训练完成,您会看到前几个 epoch 的损失远大于 1。