Python 在多输出Keras模型中为每个输出使用不同的样本权重

Python 在多输出Keras模型中为每个输出使用不同的样本权重,python,keras,deep-learning,conv-neural-network,loss-function,Python,Keras,Deep Learning,Conv Neural Network,Loss Function,我的输入数组是image\u数组,包含大小为512x512的10000幅图像的数据,有4个通道。例如,image\u array.shape=(10000、512、512、4)。这些图像中的每一张都有一个相关的指标,我想训练CNN为我预测。因此metric\u array.shape=(10000)。由于我不希望网络偏向更频繁出现的度量值,因此我有一个加权数组,包含度量值的每个值的权重。因此weightArray.shape=(10000) 我正在使用Keras。这是我的顺序模型: model=

我的输入数组是
image\u数组
,包含大小为512x512的10000幅图像的数据,有4个通道。例如,
image\u array.shape=(10000、512、512、4)
。这些图像中的每一张都有一个相关的指标,我想训练CNN为我预测。因此
metric\u array.shape=(10000)
。由于我不希望网络偏向更频繁出现的度量值,因此我有一个加权数组,包含度量值的每个值的权重。因此
weightArray.shape=(10000)

我正在使用Keras。这是我的顺序模型:

model=Sequential()
add(Conv2D(32,use_bias=True,kernel_size=(3,3),strips=(1,1),activation='relu',input_shape=(512512,4))
添加(BatchNormalization())
add(MaxPooling2D(池大小=(2,2),跨步=(2,2)))
add(Conv2D(64,use_bias=True,kernel_size=(3,3),strips=(1,1),activation='relu'))
添加(BatchNormalization())
add(MaxPooling2D(池大小=(2,2),跨步=(2,2)))
add(Conv2D(128,use_bias=True,kernel_size=(3,3),strips=(1,1),activation='relu'))
添加(BatchNormalization())
model.add(展平())
模型.添加(密度(32))
添加(激活('relu'))
添加(BatchNormalization())
添加(密集(1,激活=relu_max))
我想使用均方误差损失函数和随机梯度下降优化器。我编译了我的模型:

model.compile(loss='mean_squared_error',optimizer=optimizers.SGD(lr=0.01))
我将数据集分为培训和验证:

X_列,X_验证,Y_列,Y_验证,W_列,W_验证\
=序列测试分割(图像数组、度量数组、权重数组、测试大小=0.3)
最后对模型进行训练:

model.fit(X\u系列,Y\u系列,历代=100,批量=32\
验证数据=(X验证,Y验证),样本重量=W列车)
所有这些都有效。现在,我想做的是使用2个度量,而不是一个。我有一个metric1值和一个metric2值用于每个图像。metric1和metric2的每个值都有一个关联的权重。因此

metric\u array1.shape=metric\u array2.shape=weightArray1.shape=weightarrary2.shape=(10000)
然后,我的网络将有两个输出节点,每个节点对应一个度量

我尝试将上面的最后一层更改为:

model.add(密集(2,激活=relu_max))
然后,我将度量和权重数据组合成一个度量_数组和一个元组的权重数组,形状为(10000,2)。 这让我发现顺序模型是为单个输出设计的,因此我应该使用函数模型

我已经阅读了一些文档,它看起来相当复杂。我尝试使用上面的模型(但最后一层有两个节点),然后

来自keras.models导入模型
新模型=模型(模型)
但当我试图编译它时,它不喜欢它,因为Model没有选项
.add


有没有一种简单的方法可以改变我已经拥有的东西以达到我的新目的?我非常感谢任何指导。

首先,让我们澄清一个误解:

如果您的模型有一个输出/输入层,则无论输出层和输入层中神经元的数量如何,您都可以使用顺序API构建模型。另一方面,如果您的模型有多个输出/输入层,则必须使用函数APIAPI来定义模型(无论输入/输出层可能有多少个神经元)

现在,您已经声明您的模型有两个输出值,并且对于每个输出值,您希望使用不同的样本权重。要做到这一点,您的模型必须具有两个输出层,然后您可以将
样本权重
参数设置为包含两个对应权重数组的字典g到两个输出层

为了更清楚,请考虑这个虚拟例子:

from keras import layers
from keras import models 
import numpy as np

inp = layers.Input(shape=(5,))
# assign names to output layers for more clarity
out1 = layers.Dense(1, name='out1')(inp)
out2 = layers.Dense(1, name='out2')(inp)

model = models.Model(inp, [out1, out2])
model.compile(loss='mse',
              optimizer='adam')

# create some dummy training data as well as sample weight
n_samples = 100
X = np.random.rand(n_samples, 5)
y1 = np.random.rand(n_samples,1)
y2 = np.random.rand(n_samples,1)

w1 = np.random.rand(n_samples,)
w2 = np.random.rand(n_samples,)

model.fit(X, [y1, y2], epochs=5, batch_size=16, sample_weight={'out1': w1, 'out2': w2})

如果更改模型结构,以前的权重将无法使用。顺序模型可以使用多个权重outputs@Frobot请参见。@venkata krishnan您指的是单输出模型的权重吗?我对保留它们不感兴趣。我想要一个有两个输出的新模型,我可以在数据集wi上进行训练两个指标。您有一个输出层和两个神经元,因此顺序API可以正常工作。另一方面,如果您的模型有多个输出/输入层(而不是神经元),那么你必须使用函数式API。非常感谢!这很清楚。在你描述的模型中添加其余层的最简单方法是什么?@Luismi98我不确定我是否正确理解你的问题:你的意思是“我们如何使用函数式API构建模型?”?如果是这样的话,那么该文档将用于救援。非常感谢。这应该在TensorFlow文档中提及。。。