keras疑问

为什么共享图层后,输出向量的形状还不一样

# 这一层可以输入一个矩阵,并返回一个 64 维的向量
shared_lstm = LSTM(64)

# 当我们重用相同的图层实例多次,图层的权重也会被重用 (它其实就是同一层)
encoded_a = shared_lstm(tweet_a)
encoded_b = shared_lstm(tweet_b)

这里重用了shared_lstm 层,但是如果要我们获取输出形状时,有文章指出图层的权重是一样的,但是输出形状不一样,这里不太理解

assert shared_lstm.get_output_at(0) == encoded_a
assert shared_lstm.get_output_at(1) == encoded_b

虽然我们可以通过shared_lstm 的方法来获取图层,但是我不太理解,我的理解是输出已经定义好了,所有的输入的输出都是一样的,写个代码可以了解一下。


a = Input(shape=(280, 128))
b = Input(shape=(250, 128))

lstm = LSTM(32)
encoded_a = lstm(a)
encoded_b = lstm(b)

print(lstm.get_input_shape_at(0))
print(lstm.get_input_shape_at(1))

print(lstm.get_output_shape_at(0))
print(lstm.get_output_shape_at(1))

输出结果:

(None, 280, 128)
(None, 250, 128)
(None, 32)
(None, 32)

其中如果a、b的input中,shape的后一维向量不一样就会报错,根据矩阵运算来说,后一维矩阵关系到后一个向量的行维数,如果不同,则两次输入得到的向量维数都是不一样的,这是我的理解,也不知道对不对,
疑问:

  • 1、如果两次调用通一个层,同一个输入维数,用的是也是两个层,那么权重怎么共享?
  • 2、对这个共享还是不太理解,我觉得共享就是权重也是共享的,这个权重对于同一个维数的输入来说应该是一样的。

Embedding层和Input层有啥区别

这两个层都是作为网络模型的第一层,当然模型也可以不用这个层,所以我就很奇怪,这两个层作为第一层的作用是什么?他们之间有什么区别?

Input层 很多资料就说实例化一个keras张量,如下:

x = Input(shape=(32,))

明显很多layers的输出都是返回一个向量,

Embedding层:嵌入层将正整数(下标)转换为具有固定大小的向量,如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]
是不是很奇怪,这个怎么转换的?其实这里的embeding 是词向量化,但我不清楚 是不是用的word2vec,但大概是用的skip-word算法来构建的,将输入作为语料集,一定长度的窗口来滑动,训练模型从而得到指定长度的输出词的相似性,输出的是相关性较高的词的概率,一共有窗口大小的长度,
如果输入数据不需要词的语义特征语义,简单使用Embedding层就可以得到一个对应的词向量矩阵,但如果需要语义特征,我们大可把训练好的词向量权重直接扔到Embedding层中即可
大家可以看下这个定义:

keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None)

  • input_dim: int > 0。词汇表大小, 即最大整数 index + 1,类似语料集分词后词汇大小。
  • output_dim: int >= 0。词向量的维度。
  • input_length: 输入序列的长度,当它是固定的时。 如果你需要连接 Flatten 和 Dense 层,则这个参数是必须的 (没有它,dense 层的输出尺寸就无法计算)
model = Sequential()
model.add(Embedding(4, 5, input_length=7))
model.compile('rmsprop','mse')
model.predict(np.array([[0,1,0,1,1,0,3]]))

输出结果:

array([[[-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [ 0.02410911, -0.03580334,  0.02348015,  0.02070605,
          0.01584761],
        [-0.03462106,  0.01587335, -0.04886673,  0.01961641,
          0.01314208],
        [ 0.00639332, -0.03460374,  0.01854259,  0.02507687,
          0.03259133]]], dtype=float32)

参数分析:

  • 4:3+1,一共有3个词汇,0、1、3
  • 5:词向量的维度
  • 7:输入的长度

具体可以看下参考博客。

dot()

全称是 tf.keras.backend.dot,表示两个矩阵相乘得到一个新的矩阵。

  # dot product between tensors
    >>> x = K.placeholder(shape=(2, 3))
    >>> y = K.placeholder(shape=(3, 4))
    >>> xy = K.dot(x, y)
    >>> xy
    <tf.Tensor 'MatMul_9:0' shape=(2, 4) dtype=float32>

不过这些都是只有形状,也就是说并不知道这个矩阵的具体值是多少,可能跟我们线性代数里的具体的矩阵不太一样,毕竟这里只是定义这么一个相乘的操作。

Model类与Layer的区别

这里的Layer包括我们自己定义的Layer Class。通常,我们使用Layer类来定义内部计算块,并使用Model类来定义外部模型 - 即要训练的对象。

Model类与Layer的区别:

它公开了内置的训练,评估和预测循环(model.fit(),model.evaluate(),model.predict())。
它通过model.layers属性公开其内层列表。
它公开了保存和序列化API。

参考博客

keras中文

keras:3Embedding层详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值