在为端到端CNN组合不同的基础事实时处理输入

时间:2017-05-04 17:33:31

标签: neural-network keras theano conv-neural-network lasagne

我希望设计一个端到端的CNN来提取三个特征:事物A的分割和分叉,以及事物B的检测。将有一个共同的权重主干,然后是三个具有自己权重的分支三种要素类型,然后将合并分支。我希望通过自定义随机梯度体面函数实现这一目标。

我需要组合相同主题的不同数据集,其中每个图像包含A和B,但不同的数据集包含不同的基础事实。我希望为每个图像添加一个额外的矢量,指示三个基本事件中哪一个可用(例如[0 0 1])。这使得公共权重将始终更新,但是各个分支权重在遇到时会知道忽略不合适的图像,或者如果批次内没有遇到足够的图像,则甚至知道合适的图像。

问题是我不知道如何处理这个问题。

  • 地面实况参数是否需要与图像大小相同,并作为冗余0的图像的额外通道传递?如果是这样,我如何确保它不被视为正常渠道?
  • 我可以单独传递,例如[x_train y_train g_train]吗?其他层如何处理这个问题,尤其是编译和验证?

我正在考虑用烤宽面条中的Theano做这个,而不是我对Keras的初衷,因为后者有更高的抽象层次。如果事物B过于复杂化,也可以忽略事物B的检测。

1 个答案:

答案 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。 (这不会更改已编译的模型)。