如何构建具有密集层和 Conv2D 层的两分支 Keras 模型?

问题描述 投票:0回答:1

这是一个简单的示例,在我尝试部署的网络中重现我的问题。

我有一个图像输入层(我需要维护),然后是一个密集层、Conv2D 层和一个密集层。

想法是输入是 10x10 图像,标签是 10x10 图像。受到我的代码和这个示例的启发。

import numpy as np
from keras.models import Model
from keras.layers import Input, Conv2D

#Building model
size=10
a = Input(shape=(size,size,1))
hidden = Dense(size)(a)
hidden = Conv2D(kernel_size = (3,3), filters = size*size, activation='relu', padding='same')(hidden)
outputs = Dense(size, activation='sigmoid')(hidden)

model = Model(inputs=a, outputs=outputs)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

#Create random data and accounting for 1 channel of data
n_images=55
data = np.random.randint(0,2,(n_images,size,size,1))
labels = np.random.randint(0,2,(n_images,size,size,1))

#Fit model
model.fit(data, labels, verbose=1, batch_size=10, epochs=20)

print(model.summary())

我收到以下错误:

ValueError: Error when checking target: expected dense_92 to have shape (10, 10, 10) but got array with shape (10, 10, 1)


如果我更改,我不会收到错误:

outputs = Dense(size, activation='sigmoid')(hidden)

与:

outputs = Dense(1, activation='sigmoid')(hidden)

不知道

Dense(1)
如何有效以及它如何允许10x10输出信号,如
model.summary()
所示:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_26 (InputLayer)        (None, 10, 10, 1)         0         
_________________________________________________________________
dense_93 (Dense)             (None, 10, 10, 10)        20        
_________________________________________________________________
conv2d_9 (Conv2D)            (None, 10, 10, 100)       9100      
_________________________________________________________________
dense_94 (Dense)             (None, 10, 10, 1)         101       
=================================================================
Total params: 9,221
Trainable params: 9,221
Non-trainable params: 0
_________________________________________________________________
None

编辑(从旧评论中移走):

  1. 我想做的不是标准的。我有一组图像,对于每个图像,我想找到一个大小相同的二进制图像,如果 其像素值为1表示该特征存在于输入图像中

  2. 了解像素是否具有特征应该从局部信息(由卷积层提取)和全局信息中获取 密集层提取的信息。

python tensorflow keras conv-neural-network
1个回答
5
投票

嗯,根据您的评论:

我想做的不是标准的。我有一组图像和 每个图像我想找到一个相同大小的二值图像,如果 其像素值为1表示该特征存在于输入图像中

关于像素是否具有特征的见解应该来自 局部信息(由卷积层提取)和全局信息 密集层提取的信息。

我猜你正在寻找创建一个两分支模型,其中一个分支由卷积层组成,另一个分支只是一个或多个彼此之上的密集层(尽管,我应该提到,在我看来,一个卷积网络可以实现什么你正在寻找,因为池化层和卷积层的组合,然后可能是最后的一些上采样层以某种方式保留了本地和全局信息)。要定义这样的模型,您可以使用Keras功能API,如下所示:

from keras import models
from keras import layers

input_image = layers.Input(shape=(10, 10, 1))

# branch one: dense layers
b1 = layers.Flatten()(input_image)
b1 = layers.Dense(64, activation='relu')(b1)
b1_out = layers.Dense(32, activation='relu')(b1)

# branch two: conv + pooling layers
b2 = layers.Conv2D(32, (3,3), activation='relu')(input_image)
b2 = layers.MaxPooling2D((2,2))(b2)
b2 = layers.Conv2D(64, (3,3), activation='relu')(b2)
b2_out = layers.MaxPooling2D((2,2))(b2)

# merge two branches
flattened_b2 = layers.Flatten()(b2_out)
merged = layers.concatenate([b1_out, flattened_b2])

# add a final dense layer
output = layers.Dense(10*10, activation='sigmoid')(merged)
output = layers.Reshape((10,10))(output)

# create the model
model = models.Model(input_image, output)

model.compile(optimizer='rmsprop', loss='binary_crossentropy')
model.summary()

型号总结:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 10, 10, 1)    0                                            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 8, 8, 32)     320         input_1[0][0]                    
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 4, 4, 32)     0           conv2d_1[0][0]                   
__________________________________________________________________________________________________
flatten_1 (Flatten)             (None, 100)          0           input_1[0][0]                    
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 2, 2, 64)     18496       max_pooling2d_1[0][0]            
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 64)           6464        flatten_1[0][0]                  
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, 1, 1, 64)     0           conv2d_2[0][0]                   
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 32)           2080        dense_1[0][0]                    
__________________________________________________________________________________________________
flatten_2 (Flatten)             (None, 64)           0           max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 96)           0           dense_2[0][0]                    
                                                                 flatten_2[0][0]                  
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 100)          9700        concatenate_1[0][0]              
__________________________________________________________________________________________________
reshape_1 (Reshape)             (None, 10, 10)       0           dense_3[0][0]                    
==================================================================================================
Total params: 37,060
Trainable params: 37,060
Non-trainable params: 0
__________________________________________________________________________________________________

请注意,这是实现您正在寻找的目标的一种方法,它可能对特定问题和您正在处理的数据有效,也可能无效。您可以修改此模型(例如删除池化层或添加更密集的层)或完全使用具有不同类型层的另一种架构(例如上采样、conv2dtrans)以达到更好的精度。最后,您必须进行实验才能找到完美的解决方案。

编辑:

为了完整起见,这里介绍如何生成数据和拟合网络:

n_images=10
data = np.random.randint(0,2,(n_images,size,size,1))
labels = np.random.randint(0,2,(n_images,size,size,1))
model.fit(data, labels, verbose=1, batch_size=32, epochs=20)
© www.soinside.com 2019 - 2024. All rights reserved.