我希望设计一个端到端的CNN来提取三个特征:事物A的分割和分叉,以及事物B的检测。将有一个共同的权重主干,然后是三个具有自己权重的分支三种要素类型,然后将合并分支。我希望通过自定义随机梯度体面函数实现这一目标。
我需要组合相同主题的不同数据集,其中每个图像包含A和B,但不同的数据集包含不同的基础事实。我希望为每个图像添加一个额外的矢量,指示三个基本事件中哪一个可用(例如[0 0 1])。这使得公共权重将始终更新,但是各个分支权重在遇到时会知道忽略不合适的图像,或者如果批次内没有遇到足够的图像,则甚至知道合适的图像。
问题是我不知道如何处理这个问题。
我正在考虑用烤宽面条中的Theano做这个,而不是我对Keras的初衷,因为后者有更高的抽象层次。如果事物B过于复杂化,也可以忽略事物B的检测。
答案 0 :(得分:1)
所以,你有两种不同形状的事实。
但是因为他们是"真相",他们应该进入Y方,而不是X.
假设A的分割导致二维(侧面,侧面)矩阵与输入图像的大小相同,并且分叉的结果是一维(2,)数组,则可以这样做:< / p>
#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],.....)
如您所见,结果未合并,模型有两个输出。每个输出都有单独的损耗函数。
如果确实需要合并输出,那将是一项非常复杂的任务,因为它们具有不同的形状。如果您需要一个丢失函数更重要,您可以在loss_weights
调用中传递compile
参数。
如果您想仅使用一个分支进行训练或预测,您只需要创建一个新的Model
,而无需更改任何图层:
modelB1 = Model(inp, out1)
modelB2 = Model(inp, out2)
所以,假设你只有&#34; bifTruth&#34;对于某组图像。然后只需使用modelB2
进行培训。它根本没有考虑其他分支。
在训练之前,您必须compile
每个模型。但是它们的权重对于所有三个模型(模型,模型B1和模型B2)都是常见的。
如果您希望模型的某些部分在训练期间保持不变,您可以在编译之前转到每个model.layer[i]
并创建.trainable = False
。 (这不会更改已编译的模型)。