在 Keras(tf 后端)中返回标量点积真的那么难吗?

Posted

技术标签:

【中文标题】在 Keras(tf 后端)中返回标量点积真的那么难吗?【英文标题】:Is it really that difficult to return a scalar dot product in Keras (tf backend)? 【发布时间】:2018-01-21 09:34:16 【问题描述】:

我已经在Keras issues 上问过这个问题,但由于我在那里没有得到任何答案,所以我决定在这里试试运气。

我正在使用自定义优化器运行 mnist mlp example,该优化器暂时只是来自 optimizers.py 的 SGD 的抄本,即

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import Optimizer
from keras import backend as K
from legacy import interfaces
import numpy as np

class testsgd(Optimizer):
..... [everything same as sgd] .....

myopt = testsgd()

....[define model]....

model.compile(loss='categorical_crossentropy',
              optimizer=myopt,
              metrics=['accuracy'])

history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_data=(x_test, y_test))

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

现在,在我的自定义优化器中,我需要计算梯度与速度的点积,即在 optimizers.py 中的 168 行之后,我需要类似于

angle = K.dot(g,v) 要么 angle = K.dot(K.transpose(g),v) 要么 angle = K.dot(g, K.transpose(v))

不幸的是,以上都不起作用,我只是得到错误

ValueError:形状必须为 2 级,但对于输入形状为 [512]、[512] 的“MatMul”(操作:“MatMul”)为 1 级。

我知道 gv 是张量,可能需要将其展平为 numpy 数组,以便将 numpy 用于点积。

我最接近的是通过检查优化器.py 中的75 行,它计算梯度的范数,即

norm = K.sqrt(sum([K.sum(K.square(g)) for g in grads]))

然而,即便如此,声明

print(norm)

仍然返回一个张量!

我也试过了

angle = K.sum(g * v,axis=-1,keepdims=True)

按照here 的建议,但结果仍然是一个我无法解释为正确与否的张量:

张量("Sum_2:0", shape=(1,), dtype=float32)

当我尝试时

print (K.get_value(angle)) 

我刚刚得到

InvalidArgumentError(参见上文的回溯):形状 [-1,784] 具有负尺寸 [[节点:dense_4_input = Placeholderdtype=DT_FLOAT, shape=[?,784], _device="/job:localhost/replica:0/task:0/gpu:0"]]

非常感谢您的任何帮助

【问题讨论】:

不知道keras是如何实现这些功能的。在numpy transpose 的一维数组中没有任何变化(与自身交换一维)。 dot 对于一维数组进行向量内积,给出一个标量。 matmul (@) 代表一维数组的 dot 您找到解决问题的方法了吗?我面临着类似的事情 【参考方案1】:

使用K.get_value(x) 获取张量的标量。

tf.keras.backend.get_value

【讨论】:

以上是关于在 Keras(tf 后端)中返回标量点积真的那么难吗?的主要内容,如果未能解决你的问题,请参考以下文章

Keras:为啥损失函数必须为每个批次项目返回一个标量,而不仅仅是一个标量?

keras 的指标返回啥值?标量还是张量?

TypeError:只有整数、切片、省略号、tf.newaxis 和标量 tf.int32/tf.int64 张量是有效的索引

深度学习 - 36.TF x Keras TF 常用矩阵计算方法大全

keras loss 必须每批输出一个标量还是整批输出一个标量?

为啥numpy点积函数在传递两个TensorFlow变量对象时会返回错误?