Керас: проблема с градиентами, пользовательский слой не работает в последовательной модели - PullRequest
1 голос
/ 28 мая 2020

Это сообщение об ошибке, которое я получаю с приведенным ниже кодом:
ValueError: не предусмотрены градиенты для какой-либо переменной: ['Variable: 0'].
сразу после того, как он проходит build () всего слоя в model.fit ().

Он печатает входные данные и скаляр после прохождения build () и до появления ошибки, но оба тензора пусты:

Tensor("IteratorGetNext:0", shape=(None, 1), dtype=float32)  
<tf.Variable 'Variable:0' shape=(1,) dtype=float>

Моей целью было написать собственный слой (basi c) и вставить его в модель (basi c). Мой пользовательский слой работает сам по себе, но я не могу подогнать модель. Слой берет тензор и умножает его на скаляр. Я хочу, чтобы моя модель давала мне входные данные * (скаляр, который я выбрал на раннем этапе).

До сих пор я получил много предупреждений об ошибках относительно типа dtype различных тензоров (у меня был int32 вместо float32), поэтому я написал много приведений, и у меня была модель более сложная, но я разделил ее до костей для отладки (это мало помогло…).

Я пробовал с и без "build ()", с и без использования "to_categorical" на этикетках, с векторными входами и скалярными входами и прочими, вероятно, незначительными вещами.

Вот код слоя:

from tensorflow.python.keras import layers
import tensorflow as tf
from tensorflow.python.ops import math_ops
from tensorflow.python.framework import tensor_shape
import h5py
import numpy as np


class MyBasicLayer(layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(self)
        self._set_dtype_policy('float32')
        self.w = self.add_weight(shape=(1,), initializer='zeros', trainable=True)

    def build(self, input_shape):
        input_shape = tensor_shape.TensorShape(input_shape)
        if tensor_shape.dimension_value(input_shape[-1]) is None:
            raise ValueError('The last dimension of the inputs to `MyBasicLayer` should be defined. Found `None`.')
        super().build(input_shape)

    def call(self, inputs):
        print(inputs)
        print(self.w)
        return tf.math.multiply(tf.dtypes.cast(inputs,dtype='float32'),self.w)

А вот код модели:

import numpy as np
import tensorflow as tf
import os
from tensorflow.keras import Sequential
from my_basic_layer import MyBasicLayer
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from tensorflow.python.keras.layers import Activation
from tensorflow.keras import activations



k = 2.

# load the dataset
inset = np.array([[i] for i in range(40)], dtype='float32')
outset = inset * k
#outset = to_categorical(outset, num_classes =256)

# define the model
model = Sequential()
model.add(MyBasicLayer(input_shape=(1,))) #input_shape=(4,)
#model.add(Activation(activations.softmax))

# compile the model
model.compile()

# fit the model
model.fit(inset, outset)
model.summary()

Возможно, актуально для всех, что я знаю:
Я хотел иметь model.summary () перед компиляцией, но получил
Эта модель еще не был построен. Сначала постройте модель, вызвав build() или вызвав fit() с некоторыми данными, или укажите аргумент input_shape в первом слое (ах) для автоматической c сборки.
даже после добавления el famoso input_shape аргумент в первом слое.

Спасибо

1 Ответ

0 голосов
/ 01 июня 2020

Указание решения здесь (раздел ответов), даже если оно присутствует в разделах комментариев, для преимущества сообщества .

Ошибка, ValueError: No gradients provided for any variable: ['Variable:0']. в приведенном выше случае потому что Функция потерь не была предоставлена ​​, когда Model равно Compiled.

Итак, заменив

model.compile()

на

model.compile(loss='categorical_crossentropy')

исправит ошибку.

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

from tensorflow.python.keras import layers
import tensorflow as tf
from tensorflow.python.ops import math_ops
from tensorflow.python.framework import tensor_shape
import h5py
import numpy as np


class MyBasicLayer(layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(self)
        self._set_dtype_policy('float32')
        self.w = self.add_weight(shape=(1,), initializer='zeros', trainable=True)

    def build(self, input_shape):
        input_shape = tensor_shape.TensorShape(input_shape)
        if tensor_shape.dimension_value(input_shape[-1]) is None:
            raise ValueError('The last dimension of the inputs to `MyBasicLayer` should be defined. Found `None`.')
        super().build(input_shape)

    def call(self, inputs):
        print(inputs)
        print(self.w)
        return tf.math.multiply(tf.dtypes.cast(inputs,dtype='float32'),self.w)

import numpy as np
import tensorflow as tf
import os
from tensorflow.keras import Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from tensorflow.python.keras.layers import Activation
from tensorflow.keras import activations



k = 2.

# load the dataset
inset = np.array([[i] for i in range(40)], dtype='float32')
outset = inset * k
#outset = to_categorical(outset, num_classes =256)

# define the model
model = Sequential()
model.add(MyBasicLayer(input_shape=(1,))) #input_shape=(4,)

# compile the model
model.compile(loss='categorical_crossentropy')

# fit the model
model.fit(inset, outset)
model.summary()

Вывод вышеуказанного кода показан ниже:

Tensor("IteratorGetNext:0", shape=(None, 1), dtype=float32)
<tf.Variable 'Variable:0' shape=(1,) dtype=float32>
Tensor("IteratorGetNext:0", shape=(None, 1), dtype=float32)
<tf.Variable 'Variable:0' shape=(1,) dtype=float32>
2/2 [==============================] - 0s 2ms/step - loss: nan
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
my_basic_layer_3 (MyBasicLay multiple                  1         
=================================================================
Total params: 1
Trainable params: 1
Non-trainable params: 0

Надеюсь, это поможет. Удачного обучения!

...