[英]How does Keras set the dimensions in this network which has CNN and dense layers?
我需要一些帮助以了解此处的情况。
我的目标是拥有一个接收sizeXsize
图像并返回sizeXsize
二进制矩阵的网络。 网络的输出应为二进制sizeXsize
矩阵,该矩阵指示像素是否具有特征。
例如,考虑一个拐角检测网络,其中输出层会判断像素是否正好位于拐角的尖端。 即,我们只想检测此角的像素:
网络中的第一层定义如下:
from keras import models, layers
import numpy as np
size=5
input_image = layers.Input(shape=(size, size, 1))
b = layers.Conv2D(5, (3,3), activation='relu', padding='same')(input_image)
b = layers.MaxPooling2D((2,2), strides=1, padding='same')(b)
b = layers.Conv2D(5, (3,3), activation='relu', padding='same')(b)
b_out = layers.MaxPooling2D((2,2),strides=1 ,padding='same')(b)
直到现在,我仍保留原始输入层的尺寸( sizeXsize
)。
现在,我想将密集层作为具有sizeXsize
像素的输出层。
如果我使用output = layers.Dense(size, activation='sigmoid')(b_out)
则构建的图层为sizeXsizeXsize
,如果我使用output = layers.Dense(1, activation='sigmoid')(b_out)
则尺寸为sizeXsize
,怎么来的?
这是代码的构建和编译部分:
model = models.Model(input_image, output)
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
我在这里想念什么? output = layers.Dense(1, activation='sigmoid')(b_out)
不是output = layers.Dense(1, activation='sigmoid')(b_out)
只是单个神经元吗?
问题是,如果我训练:
n_images=100
data = np.random.randint(0,2,(n_images,size,size,1))
labels = np.random.randint(0,2,(n_images,size,size,1))
labels = data
model.fit(data, labels, verbose=1, batch_size=4, epochs=20)
如果我测试它:
data1 = np.random.randint(0,2,(n_images,size,size,1))
score, acc = model.evaluate(data1,data1, verbose=1)
print('Test score:', score)
print('Test accuracy:', acc)
a=np.random.randint(0,2,(1,size,size,1))
prediction = model.predict(a)
print(a==np.round(prediction))
我得到了很好的准确性,并且看来输出层的大小是正确的:
100/100 [==============================] - 0s 349us/step
Test score: 0.187119951248
Test accuracy: 0.926799981594
[[[[ True]
[ True]
[ True]
[ True]
[ True]]
[[ True]
[ True]
[ True]
[ True]
[ True]]
[[ True]
[ True]
[ True]
[ True]
[ True]]
[[ True]
[ True]
[ True]
[ True]
[ True]]
[[ True]
[ True]
[ True]
[ True]
[ True]]]]
如果我阅读密集文档:
单位:正整数,输出空间的维数。
所以,如果我把怎么弄layers.Dense(1, activation='sigmoid')(b_out)
我得到的输出层sizeXsize
?
诀窍不是使用常规的Dense
层,而是使用内核大小为(1,1)
的卷积层,即您需要以下内容:
b = layers.Conv2D(5, (3,3), activation='relu', padding='same')(input_image)
b = layers.MaxPooling2D((2,2), strides=1, padding='same')(b)
b = layers.Conv2D(5, (3,3), activation='relu', padding='same')(b)
b = layers.MaxPooling2D((2,2),strides=1 ,padding='same')(b)
# not use Dense, but Conv2D
binary_out = layers.Conv2D(1, (1,1), activation='sigmoid', padding='same')(b)
造成混淆的原因是,当前已实现了Dense
层,以便将其应用于输入数据的最后一个轴 。 这就是为什么将具有形状(size, size, 5)
的MaxPooling层的输出(即b_out
)馈送到具有一个单位的Dense层时会得到形状(size, size, 1)
的输出的原因。 在这种情况下,虽然具有相同的权重,但Dense层中的单个神经元连接到输出数组中的5个元素中的每一个(这就是为什么如果您查看summary()
输出,您会看到Dense层有6个参数,5个权重和一个偏置参数)。
您可以将Dense层(带有一个单元)或Conv2D层(带有一个滤镜)用作最后一层。 如果您问哪个更好,答案是:它取决于您正在处理的特定问题和所拥有的数据。 但是,您可以从图像分割网络中获取一些想法,在这种网络中,首先使用Conv2D和MaxPooling2D层的组合来处理图像(随着模型的进行,其尺寸会减小),然后使用一些上采样层和Conv2D层取回与输入图像相同大小的图像。 这是一个草图(不过,您的案例不需要使用TimeDistributed
和LSTM
层)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.