Keras如何在具有CNN和密集层的网络中设置尺寸?

时间:2018-10-04 23:07:45

标签: python tensorflow machine-learning keras conv-neural-network

我需要一些帮助来了解这里的情况。

我的目标是拥有一个接收foreach($row as $val){ $key = substr($val['date'],0,7); if (!array_key_exists($key, $result)) { $result[$key] = 0; } $result[$key] += $val['rating']; } 图像并返回sizeXsize二进制矩阵的网络。网络的输出应为二进制sizeXsize矩阵,该矩阵指示像素是否具有特征。

例如,考虑一个拐角检测网络,其中输出层会判断一个像素是否恰好是拐角的尖端。也就是说,我们只想检测此角的像素:

enter image description here

网络中的第一层定义如下:

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)

如果我对其进行测试:

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))

如果我阅读了Dense文档:

  

单位:正整数,输出空间的维数。

那么如果我放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)的输出层怎么办?

2 个答案:

答案 0 :(得分:1)

诀窍不是使用常规的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)

答案 1 :(得分:1)

您的困惑源于Dense层当前实现为it is applied on the last axis of input data的事实。这就是为什么将具有b_out形状的MaxPooling层(即(size, size, 5))的输出馈送到具有一个单位的密集层时会得到形状为(size, size, 1)的输出的原因。在这种情况下,尽管具有相同的权重,但Dense层中的单个神经元已连接到输出数组中的5个元素中的每个元素(这就是为什么如果查看summary()输出,您会看到密集层有6个参数,5个权重和一个偏置参数)。

您可以将Dense层(带有一个单元)或Conv2D层(带有一个滤镜)用作最后一层。如果您问哪个更好,答案是:它取决于您正在处理的特定问题和所拥有的数据。但是,您可以从图像分割网络中获取一些想法,在这些图像分割网络中,首先使用Conv2D和MaxPooling2D层的组合来处理图像(随着模型的进行,其尺寸会减小),然后使用一些上采样层和Conv2D层取回与输入图像相同大小的图像。 Here是一个草图(不过,您的案例不需要使用TimeDistributedLSTM层)。