Неужели так сложно вернуть скалярный скалярный продукт в Keras (tf backend)?

Я уже задавал этот вопрос по проблемам с Keras, но так как я не получил там ответов Решил попытать счастья здесь.

Я запускаю пример mnist mlp с настраиваемым оптимизатором, который на данный момент это просто точная копия SGD из optimizers.py, т.е.

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])

Теперь в моем настраиваемом оптимизаторе мне нужно вычислить точечное произведение градиента на скорость, то есть после строки 168 в optimizers.py, мне нужно что-то похожее на

angle = K.dot(g,v) or angle = K.dot(K.transpose(g),v) or angle = K.dot(g, K.transpose(v))

К сожалению, ничего из вышеперечисленного не работает, я просто получаю сообщение об ошибке

ValueError: Форма должна иметь ранг 2, но ранг 1 для 'MatMul' (op: 'MatMul') с входными формами: [512], [512].

Я понимаю, что g и v - это тензоры, которые, возможно, потребуется сгладить до numpy массивов, чтобы использовать numpy для скалярного произведения.

Ближе всего я подошел к проверке строки 75 в optimizers.py, который вычисляет норму градиента, т.е.

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

Однако даже тогда заявление

print(norm)

по-прежнему возвращает тензор!

Точно так же я пробовал

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

как было предложено здесь, но все же результатом является тензор что я не могу интерпретировать как правильное или нет:

Тензор ("Sum_2: 0", shape = (1,), dtype = float32)

Когда я пытаюсь

print (K.get_value(angle)) 

Я просто получаю

InvalidArgumentError (трассировку см. Выше): фигура [-1,784] имеет отрицательные размеры [[Node: densityangle = K.dot(g, K.transpose(v)) input = Placeholderdtype = DT_FLOAT, shape = [?, 784], _device = "/ job: localhost / replica: 0 / task: 0 / gpu: 0 "]]

Большое спасибо за любую помощь


person Nicholas    schedule 13.08.2017    source источник
comment
Я не знаю, как keras реализует эти функции. В numpy transpose 1d массива ничего не меняет (меняя местами одно измерение с собой). dot для 1d массивов выполняет вектор внутреннего произведения, давая скаляр. matmul (@) относится к dot для 1d массивов.   -  person hpaulj    schedule 13.08.2017
comment
Вы нашли решение проблемы? Я сталкиваюсь с чем-то похожим   -  person AEndrs    schedule 21.11.2018


Ответы (1)


Используйте K.get_value(x), чтобы получить скаляр тензора.

tf.keras.backend.get_value

person rosefun    schedule 29.04.2019