代码之家  ›  专栏  ›  技术社区  ›  Jules

对神经元子集应用softmax

  •  0
  • Jules  · 技术社区  · 7 年前

    我正在Keras中构建一个卷积网络,为一个图像分配多个类。鉴于图像已经 9 兴趣点可以用我想添加的三种方式之一进行分类 27 具有softmax激活的输出神经元,将计算每个连续三重神经元的概率。

    有可能做到吗?我知道我可以简单地添加一个大的softmax层,但这将导致所有输出神经元的概率分布,这对于我的应用来说太宽了。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Daniel Möller    7 年前

    在最简单的实现中,您可以重塑数据,您将得到您所描述的:“每个连续三元组的概率”。

    你把输出分成27个类,形状像 (batch_size,27) 并对其进行重塑:

    model.add(Reshape((9,3)))
    model.add(Activation('softmax'))
    

    y_true 数据也是如此。或者在模型中添加另一个重塑以恢复原始形状:

    model.add(Reshape((27,))
    

    在更精细的解决方案中,您可能会根据位置(如果它们具有大致静态的位置)分离insterest的9个点,并创建并行路径。例如,假设您的9个位置是等距矩形,并且您希望对这些线段使用相同的网络和类:

    inputImage = Input((height,width,channels))
    
    #supposing the width and height are multiples of 3, for easiness in this example
    recHeight = height//3
    recWidth = width//3
    
    #create layers here without calling them
    someConv1 = Conv2D(...)
    someConv2 = Conv2D(...)
    flatten = Flatten()
    classificator = Dense(..., activation='softmax')
    
    outputs = []
    for i in range(3):
        for j in range(3):
            fromH = i*recHeight
            toH = fromH + recHeight
            fromW = j*recWidth
            toW = fromW + recWidth
            imagePart = Lambda(
                               lambda x: x[:,fromH:toH, fromW:toW,:], 
                               output_shape=(recHeight,recWidth,channels)
                              )(inputImage)
    
            #using the same net and classes for all segments
            #if this is not true, create new layers here instead of using the same
            output = someConv1(imagePart)
            output = someConv2(output)
            output = flatten(output)
            output = classificator(output)
            outputs.append(output)
    
    outputs = Concatenate()(outputs)
    
    model = Model(inputImage,outputs)