#python #python-3.x #tensorflow #keras #tensorflow2.0
#python #python-3.x #тензорный поток #keras #tensorflow2.0
Вопрос:
Я пытаюсь реализовать пользовательский регуляризатор в keras. Идея заключается в том, что область регуляризации ограничена двумя столбцами из набора данных. Вот игрушечный набор данных:
# dataset
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
x = data.data # x.shape() == (569, 30)
y = data.target
Вот как я написал регуляризатор:
import tensorflow as tf # tf.__version__ == 2.0.0
class MyRegularizer(tf.keras.regularizers.Regularizer):
def __init__(self, strength):
self.strength = strength
def __call__(self, x):
# print(tf.shape(x))
return self.strength * tf.reduce_sum(tf.subtract(tf.gather(params=x,indices=[29],axis=1),
tf.gather(params=x,indices=[28],axis=1)
)
)
Вот игрушечная модель:
# model
inputs = tf.keras.layers.Input(shape=x.shape[1])
dense = tf.keras.layers.Dense(1, kernel_regularizer=MyRegularizer(0.01)
)(inputs)
model = tf.keras.models.Model(inputs = inputs, outputs = dense)
model.compile(loss='binary_crossentropy')
model.summary()
model.fit(x,y)
Ошибка, которую я получаю, выглядит следующим образом:
InvalidArgumentError: segment_ids[0] = 28 находится вне диапазона [0, 1)
Я пытался проверить функцию вывода регуляризатора вне модели
tf.reduce_sum(tf.subtract(tf.gather(x,[29],axis=1),tf.gather(x,[28],axis=1)))
и он работает нормально.
Так что, вероятно, есть проблема с формой тензора, который отправляется регуляризатору. Я понятия не имею, как это решить (играл с именами переменных, типами данных, формами ввода, все без удачи). Модель без регуляризатора подходит без каких-либо ошибок.
Потоки в Интернете, касающиеся вышеупомянутой ошибки, вращаются вокруг встраивания измерений, и мне не удалось найти решение, которое сработало бы для меня.
Ответ №1:
В вашем подклассе аргумент «x», переданный в методе ‘call ()’, является ядром слоя (веса). Поскольку у вас есть одна ячейка в слое Dence, метод «tf.gather» не может найти элемент index [28] на второй оси в ядре.
InvalidArgumentError: segment_ids[0] = 28 находится вне диапазона [0, 1)
если вы хотите получить вес, соответствующий вводу [28]; Я думаю, приведенный ниже код может работать (измените значение оси на ноль):
import tensorflow as tf # tf.__version__ == 2.0.0
class MyRegularizer(tf.keras.regularizers.Regularizer):
def __init__(self, strength):
self.strength = strength
def __call__(self, x):
# print(tf.shape(x))
return self.strength * tf.reduce_sum(tf.subtract(tf.gather(params=x,indices=[29],axis=0),
tf.gather(params=x,indices=[28],axis=0)
)
)