当前位置: 首页 > 知识库问答 >
问题:

如何将Keras中的致密层转换为等效卷积层?

武晨
2023-03-14

我想做一些类似于完全卷积网络的论文(https://people.eecs.berkeley.edu/~jonlong/long\u shelhamer\u fcn。pdf)使用Keras。我有一个网络,它最终将要素地图展平,并将其穿过几个密集的图层。我想将权重从这样的网络加载到一个网络中,在这个网络中,密集层被等效卷积所取代。

Keras附带的VGG16网络可以作为一个示例,其中最后一个MaxPoolig2D()的7x7x512输出被展平,然后进入一个密集(4096)层。在这种情况下,密集(4096)将替换为7x7x4096卷积。

我的真实网络略有不同,有一个GlobalAveragePoolig2D()层,而不是MaxPoolig2D()和Flatte()。GlobalAveragePoolig2D()的输出是一个2D张量,无需再将其展平,因此所有密集层(包括第一层)都将替换为1x1卷积。

我见过这个问题:Python keras如何将密集层转换为卷积层,这看起来非常相似,如果不完全相同的话。问题是我无法让建议的解决方案工作,因为(a)我使用TensorFlow作为后端,所以权重重新排列/过滤器“旋转”是不正确的,并且(b)我不知道如何加载权重。使用model.load_weights(by_name=True)将旧的权重文件加载到新网络中不起作用,因为名称不匹配(即使它们确实维度不同)。

使用TensorFlow时应该如何重新排列?

如何装载重物?我是否创建每个模型中的一个,调用模型。在两者上加载\u weights()以加载相同的权重,然后复制一些需要重新排列的额外权重?

共有2个答案

汪阿苏
2023-03-14

a、 无需进行复杂的旋转。只需重塑即可

b.使用get_weights()并初始化新层

遍历model.layers,使用set_weights或如下所示创建具有配置和加载权重的相同层。

下面这段伪代码对我有用。(Keras 2.0)

伪代码:

# find input dimensions of Flatten layer
f_dim =  flatten_layer.input_shape

# Creating new Conv layer and putting dense layers weights 
m_layer = model.get_layer(layer.name)
input_shape = m_layer.input_shape
output_dim =  m_layer.get_weights()[1].shape[0]
W,b = layer.get_weights()
if first dense layer :
    shape = (f_dim[1],f_dim[2],f_dim[3],output_dim)
    new_W = W.reshape(shape)
    new_layer = Convolution2D(output_dim,(f_dim[1],f_dim[2]),strides=(1,1),activation='relu',padding='valid',weights=[new_W,b])

else: (not first dense layer)
    shape = (1,1,input_shape[1],output_dim)
    new_W = W.reshape(shape)
    new_layer = Convolution2D(output_dim,(1,1),strides=(1,1),activation='relu',padding='valid',weights=[new_W,b])
            
饶明亮
2023-03-14

根据hars的答案,我创建了这个函数来将任意cnn转换为fcn:

from keras.models import Sequential
from keras.layers.convolutional import Convolution2D
from keras.engine import InputLayer
import keras

def to_fully_conv(model):

    new_model = Sequential()

    input_layer = InputLayer(input_shape=(None, None, 3), name="input_new")

    new_model.add(input_layer)

    for layer in model.layers:

        if "Flatten" in str(layer):
            flattened_ipt = True
            f_dim = layer.input_shape

        elif "Dense" in str(layer):

            input_shape = layer.input_shape
            output_dim =  layer.get_weights()[1].shape[0]
            W,b = layer.get_weights()

            if flattened_ipt:
                shape = (f_dim[1],f_dim[2],f_dim[3],output_dim)
                new_W = W.reshape(shape)
                new_layer = Convolution2D(output_dim,
                                          (f_dim[1],f_dim[2]),
                                          strides=(1,1),
                                          activation=layer.activation,
                                          padding='valid',
                                          weights=[new_W,b])
                flattened_ipt = False

            else:
                shape = (1,1,input_shape[1],output_dim)
                new_W = W.reshape(shape)
                new_layer = Convolution2D(output_dim,
                                          (1,1),
                                          strides=(1,1),
                                          activation=layer.activation,
                                          padding='valid',
                                          weights=[new_W,b])


        else:
            new_layer = layer

        new_model.add(new_layer)

    return new_model
model = keras.applications.vgg16.VGG16()
new_model = to_fully_conv(model)
 类似资料:
  • 为了将密集层转换为卷积层,我很难找到权重的正确映射。 这是我正在制作的ConvNet的摘录: 在MaxPooling之后,输入是形状(512,7,7)。我想将密集层转换为卷积层,使其看起来像这样: 但是,我不知道我需要如何重塑权重才能将扁平化的权重正确映射到卷积层所需的(4096,512,7,7)结构?现在,密集层的权重是维度(25088,4096)。我需要以某种方式将这25088个元素映射到(5

  • 我正在使用MNIST数据集,我正在使用keras来训练卷积神经网络。关于权重矩阵,有些东西我不明白。 输入层有28x28=784个神经元。然后我使用: 在我训练模型后,把W=模型。get\u weights(),I打印W[I]。每个i的形状并获得: 据我所知,这意味着对于第一个隐藏层有32个8x8=64的图像(因为(28-7)/3 1=8)因此第一个隐藏层中有64x32=2048个神经元。 下一部

  • 我对神经网络和keras有点陌生。我有一些大小为6*7的图像,过滤器的大小为15。我想有几个过滤器,并在每个上分别训练一个卷积层,然后组合它们。我在这里看了一个例子: 此型号使用一个过滤器。有谁能给我一些关于如何修改模型以处理并行卷积层的提示吗。 谢啦

  • 我在一维输入信号上实现了一个具有批量归一化的卷积神经网络。我的模型有一个相当好的精度约80%。以下是我的图层顺序:(Conv1D,Batch,ReLU,MaxPooling)重复6次,Conv1D,Batch,ReLU,Dense,Softmax。 我看过几篇文章说我不应该在卷积层上使用dropout,而是应该使用批处理规范化,所以我想通过用dropout层替换所有批处理规范化层来试验我的模型,看

  • 根据文档网站(https://keras.io/layers/convolutional/)keras卷积层的内核大小定义为高度x宽度: kernel\u size:一个整数或2个整数的元组/列表,指定2D卷积窗口的高度和宽度。可以是单个整数,以便为所有空间标注指定相同的值。 然而,在代码文档中,其定义正好相反: kernel_size:2个整数的整数或元组/列表,指定2D卷积窗口的宽度和高度。可

  • 卷积神经网络有一个批量过滤器, 持续不断的在图片上滚动收集图片里的信息,每一次收集的时候都只是收集一小块像素区域, 然后把收集来的信息进行整理, 这时候整理出来的信息有了一些实际上的呈现, 比如这时的神经网络能看到一些边缘的图片信息, 然后在以同样的步骤, 用类似的批量过滤器扫过产生的这些边缘信息, 神经网络从这些边缘信息里面总结出更高层的信息结构,比如说总结的边缘能够画出眼睛,鼻子等等. 再经过