在多输出 Keras 模型中对每个输出使用不同的样本权重
Using different sample weights for each output in a multi-output Keras model
我的输入数组是 image_array
,包含 10000 张大小为 512x512、4 个通道的图像数据。 IE。 image_array.shape = (10000, 512, 512, 4)
。这些图像中的每一个都有一个相关的指标,我想训练一个 CNN 来为我预测。因此 metric_array.shape = (10000)
。由于我不希望网络偏向于更频繁出现的指标值,因此我有一个加权数组,其中包含指标的每个值的权重。因此 weightArray.shape = (10000)
.
我正在使用 Keras。这是我的顺序模型:
model = Sequential()
model.add(Conv2D(32, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu', input_shape=(512,512,4))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(128, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu'))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(32))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dense(1, activation=relu_max))
我想使用均方误差损失函数和随机梯度下降优化器。我编译我的模型:
model.compile(loss='mean_squared_error', optimizer=optimizers.SGD(lr=0.01))
我将数据集拆分为训练和验证:
X_train, X_validate, Y_train, Y_validate, W_train, W_validate \
= train_test_split(image_array, metric_array, weightArray, test_size=0.3)
最后训练模型:
model.fit(X_train, Y_train, epochs=100, batch_size = 32, \
validation_data=(X_validate,Y_validate), sample_weight=W_train)
以上全部有效。现在,我想做的是使用 2 个指标而不是一个。我为每个图像设置了一个 metric1 值和一个 metric2 值。 metric1 和 metric2 的每个值都有关联的权重。因此
metric_array1.shape = metric_array2.shape = weightArray1.shape = weightArray2.shape = (10000)
我的网络将有两个输出节点,每个节点对应一个指标。
我尝试将上面的最后一层更改为:
model.add(Dense(2, activation=relu_max))
然后我将指标和权重数据组合成一个 metric_array 和一个元组的 weightArray,形状为 (10000, 2)。
这让我发现顺序模型是为单个输出设计的,因此我应该改用函数模型。
我看了一些文档,好像挺复杂的。我尝试使用上面的模型(但在最后一层有 2 个节点)然后做
from keras.models import Model
new_model = Model(model)
但是当我尝试编译它时它不喜欢它,因为模型没有选项.add
。
有没有一种简单的方法可以修改我已经拥有的东西以获得我的新用途?非常感谢任何指导。
首先要澄清一个误会:
如果你的模型有 one output/input layer 那么你可以使用 Sequential API 来构建你的模型,无论输出层和输入层中的 个神经元 是多少。另一方面,如果你的模型有 multiple output/input layers,那么你必须使用 Functional API 来定义你的模型(无论 input/output 层可能有多少个神经元)。
现在,您已经声明您的模型有两个输出值,并且您希望对每个输出值使用 不同的样本权重 。为此,您的模型必须具有 两个输出层 ,然后您可以将 sample_weight
参数设置为包含对应于两个输出层的两个权重数组的字典。
为了更清楚,请考虑这个虚拟示例:
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})
我的输入数组是 image_array
,包含 10000 张大小为 512x512、4 个通道的图像数据。 IE。 image_array.shape = (10000, 512, 512, 4)
。这些图像中的每一个都有一个相关的指标,我想训练一个 CNN 来为我预测。因此 metric_array.shape = (10000)
。由于我不希望网络偏向于更频繁出现的指标值,因此我有一个加权数组,其中包含指标的每个值的权重。因此 weightArray.shape = (10000)
.
我正在使用 Keras。这是我的顺序模型:
model = Sequential()
model.add(Conv2D(32, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu', input_shape=(512,512,4))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(128, use_bias=True, kernel_size=(3,3), strides=(1, 1), activation='relu'))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(32))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dense(1, activation=relu_max))
我想使用均方误差损失函数和随机梯度下降优化器。我编译我的模型:
model.compile(loss='mean_squared_error', optimizer=optimizers.SGD(lr=0.01))
我将数据集拆分为训练和验证:
X_train, X_validate, Y_train, Y_validate, W_train, W_validate \
= train_test_split(image_array, metric_array, weightArray, test_size=0.3)
最后训练模型:
model.fit(X_train, Y_train, epochs=100, batch_size = 32, \
validation_data=(X_validate,Y_validate), sample_weight=W_train)
以上全部有效。现在,我想做的是使用 2 个指标而不是一个。我为每个图像设置了一个 metric1 值和一个 metric2 值。 metric1 和 metric2 的每个值都有关联的权重。因此
metric_array1.shape = metric_array2.shape = weightArray1.shape = weightArray2.shape = (10000)
我的网络将有两个输出节点,每个节点对应一个指标。
我尝试将上面的最后一层更改为:
model.add(Dense(2, activation=relu_max))
然后我将指标和权重数据组合成一个 metric_array 和一个元组的 weightArray,形状为 (10000, 2)。 这让我发现顺序模型是为单个输出设计的,因此我应该改用函数模型。
我看了一些文档,好像挺复杂的。我尝试使用上面的模型(但在最后一层有 2 个节点)然后做
from keras.models import Model
new_model = Model(model)
但是当我尝试编译它时它不喜欢它,因为模型没有选项.add
。
有没有一种简单的方法可以修改我已经拥有的东西以获得我的新用途?非常感谢任何指导。
首先要澄清一个误会:
如果你的模型有 one output/input layer 那么你可以使用 Sequential API 来构建你的模型,无论输出层和输入层中的 个神经元 是多少。另一方面,如果你的模型有 multiple output/input layers,那么你必须使用 Functional API 来定义你的模型(无论 input/output 层可能有多少个神经元)。
现在,您已经声明您的模型有两个输出值,并且您希望对每个输出值使用 不同的样本权重 。为此,您的模型必须具有 两个输出层 ,然后您可以将 sample_weight
参数设置为包含对应于两个输出层的两个权重数组的字典。
为了更清楚,请考虑这个虚拟示例:
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})