Keras 密集层输出形状
Keras Dense layer Output Shape
我无法理解获取第一个隐藏层的输出形状背后的逻辑。我随便举了一些例子如下;
示例 1:
model.add(Dense(units=4,activation='linear',input_shape=(784,)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_7 (Dense) (None, 4) 3140
_________________________________________________________________
dense_8 (Dense) (None, 10) 50
=================================================================
Total params: 3,190
Trainable params: 3,190
Non-trainable params: 0
示例 2:
model.add(Dense(units=4,activation='linear',input_shape=(784,1)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_6"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_11 (Dense) (None, 784, 4) 8
_________________________________________________________________
dense_12 (Dense) (None, 784, 10) 50
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0
示例 3:
model.add(Dense(units=4,activation='linear',input_shape=(32,28)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_8"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_15 (Dense) (None, 32, 4) 116
_________________________________________________________________
dense_16 (Dense) (None, 32, 10) 50
=================================================================
Total params: 166
Trainable params: 166
Non-trainable params: 0
示例 4:
model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_9"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_17 (Dense) (None, 32, 28, 4) 8
_________________________________________________________________
dense_18 (Dense) (None, 32, 28, 10) 50
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0
请帮助我理解逻辑。
另外,我觉得input_shape=(784,)
和input_shape=(784,1)
的排名是一样的,那为什么他们的Output Shape
不一样呢?
密集层要求输入为(batch_size,input_size),大多数时候我们跳过batch_size并在训练时定义它。
如果您的输入形状是一维的,在您的第一种情况下 (784,) 模型将采用形状 (~, 784) 的输入数组和形状 (~,4) 的输出数组。默认情况下,它将添加偏差 4(因为 4 个单位)。因此总参数将为
parameters -> 784*4 + 4 = 3140
如果您的输入形状是二维的,在第二种情况下 (784,1) 模型将作为输入形状数组 (784,1) 和形状数组输出 (None,784,4 ).None
是批量维度。默认情况下,它将添加偏差 4(因为 4 个单位)。因此总参数将为
parameters -> 4(output units) + 4(bias) = 8
根据 Keras 的官方文档,对于 Dense 层,当您将输入作为 input_shape=(input_units,)
时,模态将输入形状为 (*, input_units)
的数组并输出形状为 (*, output_units)
的数组 [在你的情况下 input_shape=(784,)
被视为 input shape=(*, 784)
并且输出是 output_shape=(*,4)
]
通常对于 (batch_size, ..., input_dim)
的输入维度,模态给出大小 (batch_size, ..., units)
的输出。
因此,当您将输入作为 input_shape=(784,)
时,模态将作为形状为 (*, 784)
的输入数组,其中 *
是批量大小,784
作为 input_dim, 输出形状为 (*, 4)
.
当输入为(784,1)
时,模态将其视为(*, 784, 1)
,其中*
是批量大小,784
是...
,1
是 input_dim =>(batch_size, ..., input_dim)
并输出为 (*, 784, 4)
=> (batch_size, ..., units)
.
同样适用于 input_shape=(32,28)=>(*,32,28)
,给出输出 (*,32,4)
和输入 input_shape=(32,28,1)=>(*,32,28,1)
,其中 *
又是 batch_size,32,28
是 ...
而 1
是 input_dim =>(batch_size, ..., input_dim)
关于None是什么意思请查看
逻辑非常简单:密集层独立应用于前一层的最后一个维度。因此,通过具有 m
个单元的密集层输入形状 (d1, ..., dn, d)
会产生形状 (d1, ..., dn, m)
的输出,并且该层具有 d*m+m
个参数(m
偏见)。
请注意,相同的权重是独立应用的,因此您的示例 4 的工作方式如下:
for i in range(32):
for j in range(28):
output[i, j, :] = input[i, j, :] @ layer.weights + layer.bias
其中@
是矩阵乘法。 input[i, j]
是形状为 (1,)
的向量,layer.weights
的大小为 (1,4)
,layer.bias
是 (1,)
.
的向量
这也解释了为什么(784,)
和(784,1)
给出不同的结果:它们最后的维度不同,784和1。
图层的输出形状取决于所用图层的类型。例如,Dense
层的输出形状基于层中定义的 units
,而 Conv
层的输出形状取决于 filters
.
另一件要记住的事情是,默认情况下,任何输入的最后一个维度都被视为通道数。在输出形状估计过程中,通道数被层中定义的 units
代替。对于input_shape=(784,)
这样的一维输入,重要的是最后要用,
。
例1(一维),例2(2维,channel=1),例3(2维,channel=28),例4(3维,channel=1)。如上所述,最后一个维度被 Dense
层中定义的 units
替换。
这个 答案中非常清楚地提到了有关维度、轴、通道、input_dim 等的更多详细信息。
keras 是一个高级 api,它负责很多抽象。以下示例可能会帮助您更好地理解。在你的问题中,它最接近于 keras 抽象的原始张量流:
import tensorflow as tf
from pprint import pprint
for shape in [(None,784,), (None, 784,1), (None, 32,28), (None, 32,28,1)]:
shapes_list = []
input_layer_1 = tf.compat.v1.placeholder(dtype=tf.float32, shape=shape, name=None)
shapes_list.append(input_layer_1.shape)
d1 = tf.compat.v1.layers.dense(
inputs=input_layer_1, units=4, activation=None, use_bias=True, kernel_initializer=None,
bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, trainable=True, name=None, reuse=None
)
shapes_list.append(d1.shape)
d2 = tf.compat.v1.layers.dense(
inputs=d1, units=10, activation=tf.compat.v1.nn.softmax, use_bias=True, kernel_initializer=None,
bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, trainable=True, name=None, reuse=None
)
shapes_list.append(d2.shape)
print('++++++++++++++++++++++++++')
pprint(shapes_list)
print('++++++++++++++++++++++++++')
Dense
函数用于制作密集连接层或Perceptron。
根据您的代码片段,您似乎已经创建了一个多层感知器(具有线性激活函数 f(x)=x),隐藏层 1 有 4 个神经元,输出层定制为 10 classes/labels 待预测。
每一层的神经元数量由units参数决定。而 layer_L 中每个神经元的形状由前面 layer_L-1.[=18= 的输出决定]
如果密集层的输入是(BATCH_SIZE, N, l)
,那么输出的形状将是(BATCH_SIZE, N, value_passed_to_argument_units_in_Dense)
如果输入是(BATCH_SIZE, N, M, l)
,那么输出形状是(BATCH_SIZE, N, M, value_passed_to_argument_units_in_Dense)
等等。
注意:
这仅在 Dense
神经元的情况下发生,因为它不会改变 batch_size 和 last_channel 之间的中间维度。
然而,对于其他神经元,如 Conv2D->(Max/Avg)pooling,中间维度可能(取决于传递的参数)也会发生变化,因为这些神经元也对这些维度采取行动。
根据keras
Dense layer is applied on the last axis independently. [1]
https://github.com/keras-team/keras/issues/10736#issuecomment-406589140
第一个例子:
input_shape=(784,)
model.add(Dense(units=4,activation='linear',input_shape=(784,)))
它说输入只有 784 行..模型的第一层有 4 个单元。密集层中的每个单元都连接到所有 784 行。
这就是为什么
Output shape= (None, 4)
None代表batch_size,这里不知道。
第二个例子
此处输入2阶张量
input_shape=(784,1)
Units = 4
所以现在输入是 784 行和 1 列。
现在,密集层的每个单元连接到总共 784 行中每一行的 1 个元素。
输出形状 =(None, 784, 4)
None 批量大小。
第三个例子
input_shape=(32,28)
现在密集层的每个单元连接到 32 行中每一行的 28 个元素。所以
output_shape=(None,32,4)
最后一个例子
model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))
再次将致密层应用于最后一个轴,输出形状变为
Output Shape =(None,32,28,4)
备注
rank is 1 at (784,) 逗号不代表另一个维度。
在 (784,1)
处排名为 2
post 中的图表可能会进一步帮助您。
我无法理解获取第一个隐藏层的输出形状背后的逻辑。我随便举了一些例子如下;
示例 1:
model.add(Dense(units=4,activation='linear',input_shape=(784,)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_7 (Dense) (None, 4) 3140
_________________________________________________________________
dense_8 (Dense) (None, 10) 50
=================================================================
Total params: 3,190
Trainable params: 3,190
Non-trainable params: 0
示例 2:
model.add(Dense(units=4,activation='linear',input_shape=(784,1)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_6"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_11 (Dense) (None, 784, 4) 8
_________________________________________________________________
dense_12 (Dense) (None, 784, 10) 50
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0
示例 3:
model.add(Dense(units=4,activation='linear',input_shape=(32,28)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_8"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_15 (Dense) (None, 32, 4) 116
_________________________________________________________________
dense_16 (Dense) (None, 32, 10) 50
=================================================================
Total params: 166
Trainable params: 166
Non-trainable params: 0
示例 4:
model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_9"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_17 (Dense) (None, 32, 28, 4) 8
_________________________________________________________________
dense_18 (Dense) (None, 32, 28, 10) 50
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0
请帮助我理解逻辑。
另外,我觉得input_shape=(784,)
和input_shape=(784,1)
的排名是一样的,那为什么他们的Output Shape
不一样呢?
密集层要求输入为(batch_size,input_size),大多数时候我们跳过batch_size并在训练时定义它。
如果您的输入形状是一维的,在您的第一种情况下 (784,) 模型将采用形状 (~, 784) 的输入数组和形状 (~,4) 的输出数组。默认情况下,它将添加偏差 4(因为 4 个单位)。因此总参数将为
parameters -> 784*4 + 4 = 3140
如果您的输入形状是二维的,在第二种情况下 (784,1) 模型将作为输入形状数组 (784,1) 和形状数组输出 (None,784,4 ).None
是批量维度。默认情况下,它将添加偏差 4(因为 4 个单位)。因此总参数将为
parameters -> 4(output units) + 4(bias) = 8
根据 Keras 的官方文档,对于 Dense 层,当您将输入作为 input_shape=(input_units,)
时,模态将输入形状为 (*, input_units)
的数组并输出形状为 (*, output_units)
的数组 [在你的情况下 input_shape=(784,)
被视为 input shape=(*, 784)
并且输出是 output_shape=(*,4)
]
通常对于 (batch_size, ..., input_dim)
的输入维度,模态给出大小 (batch_size, ..., units)
的输出。
因此,当您将输入作为 input_shape=(784,)
时,模态将作为形状为 (*, 784)
的输入数组,其中 *
是批量大小,784
作为 input_dim, 输出形状为 (*, 4)
.
当输入为(784,1)
时,模态将其视为(*, 784, 1)
,其中*
是批量大小,784
是...
,1
是 input_dim =>(batch_size, ..., input_dim)
并输出为 (*, 784, 4)
=> (batch_size, ..., units)
.
同样适用于 input_shape=(32,28)=>(*,32,28)
,给出输出 (*,32,4)
和输入 input_shape=(32,28,1)=>(*,32,28,1)
,其中 *
又是 batch_size,32,28
是 ...
而 1
是 input_dim =>(batch_size, ..., input_dim)
关于None是什么意思请查看
逻辑非常简单:密集层独立应用于前一层的最后一个维度。因此,通过具有 m
个单元的密集层输入形状 (d1, ..., dn, d)
会产生形状 (d1, ..., dn, m)
的输出,并且该层具有 d*m+m
个参数(m
偏见)。
请注意,相同的权重是独立应用的,因此您的示例 4 的工作方式如下:
for i in range(32):
for j in range(28):
output[i, j, :] = input[i, j, :] @ layer.weights + layer.bias
其中@
是矩阵乘法。 input[i, j]
是形状为 (1,)
的向量,layer.weights
的大小为 (1,4)
,layer.bias
是 (1,)
.
这也解释了为什么(784,)
和(784,1)
给出不同的结果:它们最后的维度不同,784和1。
图层的输出形状取决于所用图层的类型。例如,Dense
层的输出形状基于层中定义的 units
,而 Conv
层的输出形状取决于 filters
.
另一件要记住的事情是,默认情况下,任何输入的最后一个维度都被视为通道数。在输出形状估计过程中,通道数被层中定义的 units
代替。对于input_shape=(784,)
这样的一维输入,重要的是最后要用,
。
例1(一维),例2(2维,channel=1),例3(2维,channel=28),例4(3维,channel=1)。如上所述,最后一个维度被 Dense
层中定义的 units
替换。
这个
keras 是一个高级 api,它负责很多抽象。以下示例可能会帮助您更好地理解。在你的问题中,它最接近于 keras 抽象的原始张量流:
import tensorflow as tf
from pprint import pprint
for shape in [(None,784,), (None, 784,1), (None, 32,28), (None, 32,28,1)]:
shapes_list = []
input_layer_1 = tf.compat.v1.placeholder(dtype=tf.float32, shape=shape, name=None)
shapes_list.append(input_layer_1.shape)
d1 = tf.compat.v1.layers.dense(
inputs=input_layer_1, units=4, activation=None, use_bias=True, kernel_initializer=None,
bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, trainable=True, name=None, reuse=None
)
shapes_list.append(d1.shape)
d2 = tf.compat.v1.layers.dense(
inputs=d1, units=10, activation=tf.compat.v1.nn.softmax, use_bias=True, kernel_initializer=None,
bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, trainable=True, name=None, reuse=None
)
shapes_list.append(d2.shape)
print('++++++++++++++++++++++++++')
pprint(shapes_list)
print('++++++++++++++++++++++++++')
Dense
函数用于制作密集连接层或Perceptron。
根据您的代码片段,您似乎已经创建了一个多层感知器(具有线性激活函数 f(x)=x),隐藏层 1 有 4 个神经元,输出层定制为 10 classes/labels 待预测。
每一层的神经元数量由units参数决定。而 layer_L 中每个神经元的形状由前面 layer_L-1.[=18= 的输出决定]
如果密集层的输入是(BATCH_SIZE, N, l)
,那么输出的形状将是(BATCH_SIZE, N, value_passed_to_argument_units_in_Dense)
如果输入是(BATCH_SIZE, N, M, l)
,那么输出形状是(BATCH_SIZE, N, M, value_passed_to_argument_units_in_Dense)
等等。
注意:
这仅在 Dense
神经元的情况下发生,因为它不会改变 batch_size 和 last_channel 之间的中间维度。
然而,对于其他神经元,如 Conv2D->(Max/Avg)pooling,中间维度可能(取决于传递的参数)也会发生变化,因为这些神经元也对这些维度采取行动。
根据keras
Dense layer is applied on the last axis independently. [1]
https://github.com/keras-team/keras/issues/10736#issuecomment-406589140
第一个例子:
input_shape=(784,)
model.add(Dense(units=4,activation='linear',input_shape=(784,)))
它说输入只有 784 行..模型的第一层有 4 个单元。密集层中的每个单元都连接到所有 784 行。
这就是为什么
Output shape= (None, 4)
None代表batch_size,这里不知道。
第二个例子
此处输入2阶张量
input_shape=(784,1)
Units = 4
所以现在输入是 784 行和 1 列。
现在,密集层的每个单元连接到总共 784 行中每一行的 1 个元素。
输出形状 =(None, 784, 4)
None 批量大小。
第三个例子
input_shape=(32,28)
现在密集层的每个单元连接到 32 行中每一行的 28 个元素。所以
output_shape=(None,32,4)
最后一个例子
model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))
再次将致密层应用于最后一个轴,输出形状变为
Output Shape =(None,32,28,4)
备注
rank is 1 at (784,) 逗号不代表另一个维度。 在 (784,1)
处排名为 2