为端到端 CNN 组合不同的基本事实时处理输入
Handling input when combining different ground truth for end-to-end CNNs
我希望设计一个端到端的 CNN 来提取三个特征:事物 A 的分割和分叉,以及事物 B 的检测。将有一个共同的权重主干,然后三个分支有自己的三种特征类型的权重,然后分支将被合并。我希望通过自定义随机梯度体面函数来实现这一点。
我需要合并相同主题的不同数据集,其中每个图像包含 A 和 B,但不同的数据集包含不同的基本事实。我希望为每个图像添加一个额外的向量,指示三个基本事实中的哪一个可用(例如 [0 0 1])。这样一来,公共权重 w_0 将始终更新,但各个分支权重 w_t 知道在遇到不合适的图像时忽略不合适的图像,甚至在批次中没有遇到足够的图像时忽略合适的图像。
问题是我不确定如何处理。
- ground truth 参数是否需要与图像大小相同,并作为带有冗余 0 的图像的额外通道传递?如果是这样,我如何确保它不被视为普通频道?
- 我可以单独传入吗,例如[x_train y_train g_train]?其他层将如何处理这个问题,尤其是编译和验证?
我正在考虑用 Lasagne 中的 Theano 来做这件事,而不是我的初衷是 Keras,因为 Keras 的抽象层次更高。如果事物 B 过于复杂,也可以忽略对事物 B 的检测。
所以,你有两种不同的基本事实形状。
但既然它们是“真相”,它们就应该放在 Y 边,而不是 X 边。
假设A的分割结果是一个与输入图像大小相同的二维(边,边)矩阵,分叉的结果是一维(2,)数组,你可以这样做:
创建具有两个输出的模型
#this is the data you already have
batch = the amount of training images you have
side = the size in pixels of one side of your training images
segTruth = your truth images for segmentation, shaped (batch,side,side)
bifTruth = your truth coordinates for bifurcations, shaped (batch,2)
trainImages = your training images, shaped (batch,side,side)
现在,让我们创建主干:
from keras.models import Model
from keras.layers import *
inp = Input((side,side))
x = Convolution2D(blablabla)(inp)
x = AnyOtherLayerYouNeed(blablabla)(x)
....
trunkOut = TheLastTrunkLayer(balblabla)(x)
现在,我们拆分模型:
b1 = FirstLayerInBranch1(blablaba)(trunkOut)
b2 = FirstLayerInBranch2(blablabl)(trunkOut)
....
out1 = LastLayerInBranch1(blablabla)(b1)
out2 = LastLayerInBranch2(blablabla)(b2)
最后,当我们定义模型时,我们传递两个输出:
model = Model(inp, [out1,out2])
编译的时候可以定义loss = [lossfunction1, lossfunction2]
。或者简单地给出一个对两个输出都相同的损失函数。
并且在训练时,也在列表中传递真值:
model.fit(trainImages, [segTruth,bifTruth],.....)
如您所见,结果没有合并,模型有两个输出。每个输出都有单独的损失函数。
如果您确实需要合并输出,那将是一项非常复杂的任务,因为它们具有不同的形状。如果您需要一个损失函数更重要,您可以在 compile
调用中传递 loss_weights
参数。
分别训练每一侧:
如果您只想使用一个分支进行训练或预测,您只需创建一个新的Model
,无需更改任何层:
modelB1 = Model(inp, out1)
modelB2 = Model(inp, out2)
因此,假设您只有一组特定图像的“bifTruth”。然后只需使用 modelB2
进行训练。它根本不考虑其他分支。
在训练之前,您必须 compile
每个模型。但是它们的权重对于所有三个模型(model、modelB1 和 modelB2)都是通用的。
如果你希望模型的某些部分在训练时保持不变,你可以在编译之前去每个model.layer[i]
并制作它们的.trainable = False
。 (这不会更改已编译的模型)。
我希望设计一个端到端的 CNN 来提取三个特征:事物 A 的分割和分叉,以及事物 B 的检测。将有一个共同的权重主干,然后三个分支有自己的三种特征类型的权重,然后分支将被合并。我希望通过自定义随机梯度体面函数来实现这一点。
我需要合并相同主题的不同数据集,其中每个图像包含 A 和 B,但不同的数据集包含不同的基本事实。我希望为每个图像添加一个额外的向量,指示三个基本事实中的哪一个可用(例如 [0 0 1])。这样一来,公共权重 w_0 将始终更新,但各个分支权重 w_t 知道在遇到不合适的图像时忽略不合适的图像,甚至在批次中没有遇到足够的图像时忽略合适的图像。
问题是我不确定如何处理。
- ground truth 参数是否需要与图像大小相同,并作为带有冗余 0 的图像的额外通道传递?如果是这样,我如何确保它不被视为普通频道?
- 我可以单独传入吗,例如[x_train y_train g_train]?其他层将如何处理这个问题,尤其是编译和验证?
我正在考虑用 Lasagne 中的 Theano 来做这件事,而不是我的初衷是 Keras,因为 Keras 的抽象层次更高。如果事物 B 过于复杂,也可以忽略对事物 B 的检测。
所以,你有两种不同的基本事实形状。
但既然它们是“真相”,它们就应该放在 Y 边,而不是 X 边。
假设A的分割结果是一个与输入图像大小相同的二维(边,边)矩阵,分叉的结果是一维(2,)数组,你可以这样做:
创建具有两个输出的模型
#this is the data you already have
batch = the amount of training images you have
side = the size in pixels of one side of your training images
segTruth = your truth images for segmentation, shaped (batch,side,side)
bifTruth = your truth coordinates for bifurcations, shaped (batch,2)
trainImages = your training images, shaped (batch,side,side)
现在,让我们创建主干:
from keras.models import Model
from keras.layers import *
inp = Input((side,side))
x = Convolution2D(blablabla)(inp)
x = AnyOtherLayerYouNeed(blablabla)(x)
....
trunkOut = TheLastTrunkLayer(balblabla)(x)
现在,我们拆分模型:
b1 = FirstLayerInBranch1(blablaba)(trunkOut)
b2 = FirstLayerInBranch2(blablabl)(trunkOut)
....
out1 = LastLayerInBranch1(blablabla)(b1)
out2 = LastLayerInBranch2(blablabla)(b2)
最后,当我们定义模型时,我们传递两个输出:
model = Model(inp, [out1,out2])
编译的时候可以定义loss = [lossfunction1, lossfunction2]
。或者简单地给出一个对两个输出都相同的损失函数。
并且在训练时,也在列表中传递真值:
model.fit(trainImages, [segTruth,bifTruth],.....)
如您所见,结果没有合并,模型有两个输出。每个输出都有单独的损失函数。
如果您确实需要合并输出,那将是一项非常复杂的任务,因为它们具有不同的形状。如果您需要一个损失函数更重要,您可以在 compile
调用中传递 loss_weights
参数。
分别训练每一侧:
如果您只想使用一个分支进行训练或预测,您只需创建一个新的Model
,无需更改任何层:
modelB1 = Model(inp, out1)
modelB2 = Model(inp, out2)
因此,假设您只有一组特定图像的“bifTruth”。然后只需使用 modelB2
进行训练。它根本不考虑其他分支。
在训练之前,您必须 compile
每个模型。但是它们的权重对于所有三个模型(model、modelB1 和 modelB2)都是通用的。
如果你希望模型的某些部分在训练时保持不变,你可以在编译之前去每个model.layer[i]
并制作它们的.trainable = False
。 (这不会更改已编译的模型)。