Nip*_*tra 13 python keras tensorflow loss-function
我正在尝试创建一个简单的加权损失函数.
比方说,我的输入尺寸为100*5,输出尺寸也为100*5.我也有一个相同尺寸的重量矩阵.
类似于以下内容:
import numpy as np
train_X = np.random.randn(100, 5)
train_Y = np.random.randn(100, 5)*0.01 + train_X
weights = np.random.randn(*train_X.shape)
Run Code Online (Sandbox Code Playgroud)
def custom_loss_1(y_true, y_pred):
return K.mean(K.abs(y_true-y_pred)*weights)
Run Code Online (Sandbox Code Playgroud)
from keras.layers import Dense, Input
from keras import Model
import keras.backend as K
input_layer = Input(shape=(5,))
out = Dense(5)(input_layer)
model = Model(input_layer, out)
Run Code Online (Sandbox Code Playgroud)
model.compile('adam','mean_absolute_error')
model.fit(train_X, train_Y, epochs=1)
Run Code Online (Sandbox Code Playgroud)
model.compile('adam',custom_loss_1)
model.fit(train_X, train_Y, epochs=10)
Run Code Online (Sandbox Code Playgroud)
它给出了以下堆栈跟踪:
InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
[[Node: loss_9/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_9/dense_8_loss/Abs, loss_9/dense_8_loss/mul/y)]]
Run Code Online (Sandbox Code Playgroud)
32号来自哪里?
def custom_loss_2(y_true, y_pred):
return K.mean(K.abs(y_true-y_pred)*K.ones_like(y_true))
Run Code Online (Sandbox Code Playgroud)
这个功能似乎做了工作.因此,可能表明作为权重矩阵的Keras张量可以起作用.所以,我创建了另一个版本的损失函数.
from functools import partial
def custom_loss_3(y_true, y_pred, weights):
return K.mean(K.abs(y_true-y_pred)*K.variable(weights, dtype=y_true.dtype))
cl3 = partial(custom_loss_3, weights=weights)
Run Code Online (Sandbox Code Playgroud)
使用cl3拟合数据会产生与上述相同的错误.
InvalidArgumentError (see above for traceback): Incompatible shapes: [32,5] vs. [100,5]
[[Node: loss_11/dense_8_loss/mul = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](loss_11/dense_8_loss/Abs, loss_11/dense_8_loss/Variable/read)]]
Run Code Online (Sandbox Code Playgroud)
我想知道我错过了什么!我本可以在Keras中使用sample_weight的概念; 但后来我不得不重塑我的输入到3d矢量.
我认为这个自定义丢失函数应该是微不足道的.
rvi*_*nas 12
在model.fit批量大小是默认32,这就是这个数字的来源.这是发生了什么:
在custom_loss_1张量K.abs(y_true-y_pred)有形状(batch_size=32, 5),而numpy阵列weights有形状(100, 5).这是无效的乘法,因为维度不一致并且无法应用广播.
在custom_loss_2这个问题中不存在,因为你将2个张量相乘,形状相同(batch_size=32, 5).
在custom_loss_3问题是相同custom_loss_1的,因为转换weights成Keras变量不改变它们的形状.
更新:似乎你想给每个训练样本中的每个元素赋予不同的权重,因此weights数组应该(100, 5)确实具有形状.在这种情况下,我会将权重数组输入到模型中,然后在损失函数中使用此张量:
import numpy as np
from keras.layers import Dense, Input
from keras import Model
import keras.backend as K
from functools import partial
def custom_loss_4(y_true, y_pred, weights):
return K.mean(K.abs(y_true - y_pred) * weights)
train_X = np.random.randn(100, 5)
train_Y = np.random.randn(100, 5) * 0.01 + train_X
weights = np.random.randn(*train_X.shape)
input_layer = Input(shape=(5,))
weights_tensor = Input(shape=(5,))
out = Dense(5)(input_layer)
cl4 = partial(custom_loss_4, weights=weights_tensor)
model = Model([input_layer, weights_tensor], out)
model.compile('adam', cl4)
model.fit(x=[train_X, weights], y=train_Y, epochs=10)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9562 次 |
| 最近记录: |