(Keras # Custom activation function (Radial Basis Function - RBF)
l2_norm = lambda a, b: K.sqrt(((a - b) ** 2).sum())
def rbf(x, gamma=1.0):
return K.exp(-1 * gamma * l2_norm(x[0], x[1]) ** 2)
,Tensorflow model = Sequential()
# Some other layers go here
model.add(Dense(n_classes, activation=rbf))
)
我正在尝试实现自己的激活功能:
/raid/home/user/anaconda2/envs/tensorflow/lib/python2.7/site-packages/tensorflow/python/framework/tensor_shape.pyc in assert_has_rank(self, rank)
619 """
620 if self.ndims not in (None, rank):
--> 621 raise ValueError("Shape %s must have rank %d" % (self, rank))
622
623 def with_rank(self, rank):
ValueError: Shape (?, 12) must have rank 1
以下是我的模型的相关部分,其中我指定了自定义激活功能:
return K.exp(-1 * gamma * l2_norm(x[0], x[1]) ** 2)
我收到以下错误:
x
尝试将(?, 12)
(形状为x[0]
)切片为x[1]
和slice
时,{{1}}行发生错误。
为什么Tensorflow {{1}}方法会抛出此错误?
答案 0 :(得分:1)
如错误所示,形状(?, 12)
不是等级1.张量等级(有时称为顺序或度数或n维)是张量的维数。例如,以下张量(定义为Python列表)的等级为2:
t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
在TensorFlow中,切片操作的灵活性略低于python numpy。切片中指定的维数必须等于张量的等级。
tf.slice(input, begin, size, name=None)
此操作从张量输入中提取一个大小为size
的切片,该张量从begin
指定的位置开始。切片size
表示为张量形状,其中size[i]
是要切片的第i个维度维度的元素数。切片的起始位置(开始)表示为输入的每个维度中的偏移。换句话说,begin[i]
是您要切片的输入的第i维度的偏移量。
begin
从零开始; size
是一个基础。如果size [i]为-1,则维度i中的所有剩余元素都包含在切片中。
简而言之,运算符要求开始和大小向量(定义要切片的子向量)与输入中的维数相同。例如,要切片三维张量,必须传递三个数字的向量(或列表)作为tf.slice()的第二个和第三个参数。
例如:
# 'input' is [[[1, 1, 1], [2, 2, 2]],
# [[3, 3, 3], [4, 4, 4]],
# [[5, 5, 5], [6, 6, 6]]]
tf.slice(input, [1, 0, 0], [1, 1, 3]) ==> [[[3, 3, 3]]]
tf.slice(input, [1, 0, 0], [1, 2, 3]) ==> [[[3, 3, 3],
[4, 4, 4]]]
tf.slice(input, [1, 0, 0], [2, 1, 3]) ==> [[[3, 3, 3]],
[[5, 5, 5]]]
因此,您可以按照以下方式修改rbf()
函数,它应该可以正常工作:
def rbf(x, gamma=1.0):
return K.exp(-1 * gamma * l2_norm(x[0, :], x[1, :]) ** 2)
答案 1 :(得分:0)
N.B。我无法使用最新版本的TensorFlow重现此问题。我怀疑您正在使用TensorFlow 0.10或更早版本的候选版本之一,因为在发布的版本中可以编写以下内容:
x = tf.placeholder(tf.float32, shape=[None, 12])
print(x[0].get_shape()) # ==> (12,)
print(x[1].get_shape()) # ==> (12,)
在旧版本的TensorFlow中,您必须在使用tf.slice()
op或[]
Python切片运算符时明确指定切片的每个维度。如果您无法升级到最新版本(我们通常建议使用!),则rbf()
功能的以下修改版本应该有效:
def rbf(x, gamma=1.0):
return K.exp(-1 * gamma * l2_norm(x[0, :], x[1, :]) ** 2)