Нет атрибута ‘compile’, как я могу изменить класс, чтобы он работал?

#python #tensorflow #keras #deep-learning #neural-network

#python #тензорный поток #keras #глубокое обучение #нейронная сеть

Вопрос:

neuMF Класс не является Keras классом a и, следовательно, не предоставляет никакого метода компиляции. Я бы лучше использовал keras.Model вместо nn.Blocks .

К сожалению, я не совсем понимаю, что такое nn.Что такое блоки и как я мог бы заменить его в классе. Как я должен модифицировать свой код, чтобы он работал keras.Model и мог использовать Keras метод?

Вот мой код:

 from d2l import mxnet as d2l
from mxnet import autograd, gluon, np, npx
from mxnet.gluon import nn
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


    class NeuMF(nn.Block):
        def init(self, num_factors, num_users, num_items, nums_hiddens,
                     kwargs):
            super(NeuMF, self).init(kwargs)
            self.P = nn.Embedding(num_users, num_factors)
            self.Q = nn.Embedding(num_items, num_factors)
            self.U = nn.Embedding(num_users, num_factors)
            self.V = nn.Embedding(num_items, num_factors)
            self.mlp = nn.Sequential()
            for num_hiddens in nums_hiddens:
                self.mlp.add(nn.Dense(num_hiddens, activation='relu',
                                      use_bias=True))
            self.prediction_layer = nn.Dense(1, activation='sigmoid', use_bias=False)
    
        def forward(self, user_id, item_id):
            p_mf = self.P(user_id)
            q_mf = self.Q(item_id)
            gmf = p_mf * q_mf
            p_mlp = self.U(user_id)
            q_mlp = self.V(item_id)
            mlp = self.mlp(np.concatenate([p_mlp, q_mlp], axis=1))
            con_res = np.concatenate([gmf, mlp], axis=1)
            return self.prediction_layer(con_res)
    
    
    hidden = [5,5,5]
    
    model = NeuMF(5, num_users, num_items, hidden)
    model.compile(
         #loss=tf.keras.losses.BinaryCrossentropy(),
        loss=tf.keras.losses.MeanSquaredError(),
        optimizer=keras.optimizers.Adam(lr=0.001)
    )
  

И я получаю следующую ошибку:

 ---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-5979072369bd> in <module>()
      2 
      3 model = NeuMF(5, num_users, num_items, hidden)
----> 4 model.compile(
      5      #loss=tf.keras.losses.BinaryCrossentropy(),
      6     loss=tf.keras.losses.MeanSquaredError(),

AttributeError: 'NeuMF' object has no attribute 'compile'
  

Заранее большое вам спасибо!

Редактировать:

Я заменил nn на layers

 class NeuMF(keras.Model):
    def __init__(self, num_factors, num_users, num_items, nums_hiddens,
                 **kwargs):
        super(NeuMF, self).__init__(**kwargs)
        self.P = layers.Embedding(num_users, num_factors)
        self.Q = layers.Embedding(num_items, num_factors)
        self.U = layers.Embedding(num_users, num_factors)
        self.V = layers.Embedding(num_items, num_factors)
        self.mlp = layers.Sequential()
        for num_hiddens in nums_hiddens:
            self.mlp.add(layers.Dense(num_hiddens, activation='relu',
                                  use_bias=True))
        self.prediction_layer = layers.Dense(1, activation='sigmoid', use_bias=False)

    def forward(self, user_id, item_id):
        p_mf = self.P(user_id)
        q_mf = self.Q(item_id)
        gmf = p_mf * q_mf
        p_mlp = self.U(user_id)
        q_mlp = self.V(item_id)
        mlp = self.mlp(np.concatenate([p_mlp, q_mlp], axis=1))
        con_res = np.concatenate([gmf, mlp], axis=1)
        return self.prediction_layer(con_res)
  

Затем я получил новую ошибку:

 ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-26-7e09b0f80300> in <module>()
      1 hidden = [1,1,1]
      2 
----> 3 model = NeuMF(1, num_users, num_items, hidden)
      4 model.compile(
      5      #loss=tf.keras.losses.BinaryCrossentropy(),

1 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/layers/embeddings.py in __init__(self, input_dim, output_dim, embeddings_initializer, embeddings_regularizer, activity_regularizer, embeddings_constraint, mask_zero, input_length, **kwargs)
    102       else:
    103         kwargs['input_shape'] = (None,)
--> 104     if input_dim <= 0 or output_dim <= 0:
    105       raise ValueError('Both `input_dim` and `output_dim` should be positive, '
    106                        'found input_dim {} and output_dim {}'.format(

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
  

Комментарии:

1. Ну, что вы хотите, чтобы произошло , когда вы используете метод? Теперь прочитайте документацию для класса. Описывает ли он способ делать то, что вы хотите? Может быть, это происходит автоматически? Или, может быть, есть другой подход?

2. @KarlKnechtel Спасибо за быстрый комментарий! Класс NeuMF можно найти здесь d2l.ai/chapter_recommender-systems/neumf.html . Я хотел бы работать с Keras.Model тем, чтобы я мог использовать метод compile и практиковать компиляцию модели. К сожалению, у меня нет действительно хорошего описания модели, отсюда и вопрос.

3. Запросы всегда предоставляют все необходимые import инструкции.

4. Я изменил все nn на layers . Например nn.Embedding , для layers.Embedding . Примерно сейчас я получаю эту ошибку ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

5. @Alperino спасибо! Я отредактировал его. Пожалуйста, посмотрите.

Ответ №1:

После уже довольно продолжительного обсуждения в комментариях, все еще есть несколько проблем с вашим кодом, и с вашей стороны требуются разъяснения:

  1. подклассы keras.Model должны реализовывать __call__ метод, но не forward метод.
  2. вы не можете просто создавать numpy операции, как np.concatenate внутри вашей модели, всегда используйте keras -layers like tf.keras.layers.Concatenate .
  3. как уже отмечалось, ошибка, которую вы опубликовали, скорее всего, связана с num_factors тем, что , num_users , num_items не является целым числом, хотя здесь я могу только догадываться, поскольку вы не предоставили их нам.
  4. кроме того, в настоящее время я могу только догадываться, чего вы пытаетесь достичь, поскольку это совсем не ясно из того, что вы опубликовали.

Давайте подойдем к проблемам по-другому. Следующий фрагмент кода выполняется без ошибок и может быть хорошей отправной точкой для вас:

 import tensorflow as tf

class NeuMF(tf.keras.Model):
    def __init__(self, num_factors, num_users, num_items, nums_hiddens,
                 **kwargs):
        super(NeuMF, self).__init__(**kwargs)
        self.P = tf.keras.layers.Embedding(num_users, num_factors)
        self.Q = tf.keras.layers.Embedding(num_items, num_factors)
        self.U = tf.keras.layers.Embedding(num_users, num_factors)
        self.V = tf.keras.layers.Embedding(num_items, num_factors)
        self.mlp = tf.keras.Sequential()
        for num_hiddens in nums_hiddens:
            self.mlp.add(
                tf.keras.layers.Dense(
                    num_hiddens,
                    activation='relu',
                    use_bias=True
                    )
                )
        self.prediction_layer = tf.keras.layers.Dense(1, activation='sigmoid', use_bias=False)

    def __call__(self, inputs):
        x  = self.P(inputs[0])
        x1 = self.Q(inputs[1])
        x  = tf.keras.layers.Multiply()([x,x1])

        y = self.U(inputs[0])
        y1 = self.V(inputs[1])
        y = tf.keras.layers.Concatenate()([y,y1])
        y = self.mlp(y)
        x = tf.keras.layers.Concatenate()([x,y])
        return self.prediction_layer(x)

if __name__ == '__main__':
    #replace these with values of your choice:
    num_factors = 2
    num_users   = 3
    num_items   = 4 
    nums_hidden = [5,5,5]

    model = NeuMF(num_users, num_items, num_items, nums_hidden)
    model.compile(
        loss = tf.keras.losses.MeanSquaredError(),
        optimizer = tf.keras.optimizers.Adam(lr=0.001)
        )