我正在构建一个模型,该模型使用递归层(GRU)将一个字符串转换为另一个字符串。我试过将稠密层和时间分布(稠密)层作为最后一层,但当使用return\u sequences=True时,我不理解这两个层之间的区别,尤其是因为它们似乎具有相同数量的参数。
我的简化模型如下:
InputSize = 15
MaxLen = 64
HiddenSize = 16
inputs = keras.layers.Input(shape=(MaxLen, InputSize))
x = keras.layers.recurrent.GRU(HiddenSize, return_sequences=True)(inputs)
x = keras.layers.TimeDistributed(keras.layers.Dense(InputSize))(x)
predictions = keras.layers.Activation('softmax')(x)
网络的总结是:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 15) 0
_________________________________________________________________
gru_1 (GRU) (None, 64, 16) 1536
_________________________________________________________________
time_distributed_1 (TimeDist (None, 64, 15) 255
_________________________________________________________________
activation_1 (Activation) (None, 64, 15) 0
=================================================================
这对我来说是有意义的,因为我对时间分布的理解是它在所有时间点应用相同的层,因此密集层有16*15 15=255参数(权重偏差)。
但是,如果我切换到一个简单的密集层:
inputs = keras.layers.Input(shape=(MaxLen, InputSize))
x = keras.layers.recurrent.GRU(HiddenSize, return_sequences=True)(inputs)
x = keras.layers.Dense(InputSize)(x)
predictions = keras.layers.Activation('softmax')(x)
我仍然只有255个参数:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 15) 0
_________________________________________________________________
gru_1 (GRU) (None, 64, 16) 1536
_________________________________________________________________
dense_1 (Dense) (None, 64, 15) 255
_________________________________________________________________
activation_1 (Activation) (None, 64, 15) 0
=================================================================
我想知道这是否是因为Dense()将只使用形状中的最后一个维度,并有效地将所有其他维度视为类似于批次的维度。但我不再确定密集和时间分布(密集)之间的区别。
更新看看https://github.com/fchollet/keras/blob/master/keras/layers/core.pyDense似乎只使用最后一个维度来调整自己的大小:
def build(self, input_shape):
assert len(input_shape) >= 2
input_dim = input_shape[-1]
self.kernel = self.add_weight(shape=(input_dim, self.units),
它还使用keras。dot应用权重:
def call(self, inputs):
output = K.dot(inputs, self.kernel)
凯拉斯的文件。点意味着它可以很好地处理n维张量。我想知道它的确切行为是否意味着实际上会在每个时间步调用Dense()。如果是这样,问题仍然是TimeDistributed()在这种情况下实现了什么。
下面是一段代码,用于验证时间分布(密集(X))是否与密集(X)相同:
import numpy as np
from keras.layers import Dense, TimeDistributed
import tensorflow as tf
X = np.array([ [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
],
[[3, 1, 7],
[8, 2, 5],
[11, 10, 4],
[9, 6, 12]
]
]).astype(np.float32)
print(X.shape)
(2、4、3)
dense_weights = np.array([[0.1, 0.2, 0.3, 0.4, 0.5],
[0.2, 0.7, 0.9, 0.1, 0.2],
[0.1, 0.8, 0.6, 0.2, 0.4]])
bias = np.array([0.1, 0.3, 0.7, 0.8, 0.4])
print(dense_weights.shape)
(3、5)
dense = Dense(input_dim=3, units=5, weights=[dense_weights, bias])
input_tensor = tf.Variable(X, name='inputX')
output_tensor1 = dense(input_tensor)
output_tensor2 = TimeDistributed(dense)(input_tensor)
print(output_tensor1.shape)
print(output_tensor2.shape)
(2、4、5)
(2,?,5)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
output1 = sess.run(output_tensor1)
output2 = sess.run(output_tensor2)
print(output1 - output2)
区别在于:
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]]
时间分布密度
在GRU/LSTM单元展开期间对每个时间步应用相同的密度。因此错误函数将在预测的标签序列和实际的标签序列之间。(这通常是序列对序列标记问题的要求)。
但是,对于return_sequences=False
,Dense
层仅在最后一个单元格应用一次。当RNN用于分类问题时通常会出现这种情况。如果return_sequences=True
,则Dense
层就像时间分布密度
一样应用于每个时间步。
因此,根据您的模型,两者都是相同的,但如果您将第二个模型更改为“return\u sequences=False”,则仅在最后一个单元格中应用“Dense”。尝试更改它,模型将作为错误抛出,因为这样,Y的大小将是Batch\u size,InputSize,这不再是一个序列到序列的问题,而是一个完整的序列到标签的问题。
from keras.models import Sequential
from keras.layers import Dense, Activation, TimeDistributed
from keras.layers.recurrent import GRU
import numpy as np
InputSize = 15
MaxLen = 64
HiddenSize = 16
OutputSize = 8
n_samples = 1000
model1 = Sequential()
model1.add(GRU(HiddenSize, return_sequences=True, input_shape=(MaxLen, InputSize)))
model1.add(TimeDistributed(Dense(OutputSize)))
model1.add(Activation('softmax'))
model1.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model2 = Sequential()
model2.add(GRU(HiddenSize, return_sequences=True, input_shape=(MaxLen, InputSize)))
model2.add(Dense(OutputSize))
model2.add(Activation('softmax'))
model2.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model3 = Sequential()
model3.add(GRU(HiddenSize, return_sequences=False, input_shape=(MaxLen, InputSize)))
model3.add(Dense(OutputSize))
model3.add(Activation('softmax'))
model3.compile(loss='categorical_crossentropy', optimizer='rmsprop')
X = np.random.random([n_samples,MaxLen,InputSize])
Y1 = np.random.random([n_samples,MaxLen,OutputSize])
Y2 = np.random.random([n_samples, OutputSize])
model1.fit(X, Y1, batch_size=128, nb_epoch=1)
model2.fit(X, Y1, batch_size=128, nb_epoch=1)
model3.fit(X, Y2, batch_size=128, nb_epoch=1)
print(model1.summary())
print(model2.summary())
print(model3.summary())
在上述示例中,模型1和模型2的体系结构是示例(序列到序列模型),模型3是完整的序列到标签模型。
ResNet中的跨层连接设计引申出了数个后续工作。本节我们介绍其中的一个:稠密连接网络(DenseNet) [1]。 它与ResNet的主要区别如图5.10所示。 图5.10中将部分前后相邻的运算抽象为模块$A$和模块$B$。与ResNet的主要区别在于,DenseNet里模块$B$的输出不是像ResNet那样和模块$A$的输出相加,而是在通道维上连结。这样模块$A$的输出可以直接传入模块$B$后
图形对于建模真实世界的现象和关系非常有用。 从广义上讲,图数据结构和算法分为两类: 那些对稀疏图有用的(例如邻接列表,约翰逊算法) 那些对稠密图有用的(例如邻接矩阵、Floyd-Warisher)。 然而,在我能想到的每种情况下,现实世界的图表都是稀疏的。例如: Web网络形成稀疏图(每个站点都链接到其他几个站点) 社交网络形成稀疏图(每个人都认识几个其他人) 电气网络形成稀疏图(大多数电路元件只
我正在训练一个神经网络来计算3x3矩阵的逆。我使用的是一个具有1层和9个神经元的Keras密集模型。第一层上的激活函数为“relu”,输出层上的激活函数为线性。我正在使用10000个行列式1的矩阵。我得到的结果不是很好(RMSE有数百个)。我一直在尝试更多的层次、更多的神经元和其他激活功能,但收获很小。代码如下: 我在网上查过,似乎有关于逆矩阵近似问题的论文。然而,在更改模型之前,我想知道是否还有
问题内容: This is my test code: The output is: 但是发生了什么? 文件上说: 注意:如果层的输入的秩大于2,则为 在初始点积之前先展平带核。 当输出被重塑时? 问题答案: 目前,与文件中所述相反的是, 层[应用在输入张量的最后一个轴上](网址:keras.com/https://github- 团队/KERA/问题/10736#问题建议-406589140):
我正在研究在.Net和Java(在Android上)中加密(后来解密)字符串,使用带有密码和初始化向量的AES加密。我让每一端各自的en-和解密单独运行良好,但相比之下,我不断得到不同的结果,因此不允许在一个系统上加密而在另一个系统上解密。我特别不明白为什么加密字节数组的前半部分是相同的,而后半部分是不同的(而所有其他字节数组是完全相同的)? 以下是我从使用的两个加密代码中得到的字节数组: Jav
谁能给我一个提示如何解决这个问题?我这样做是为了通过servlet链接执行电子邮件确认,如果有人可以建议我另一个解决方案将非常感谢。