Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDM加载之前存储的模型后报错AttributeError: 'Functional' object has no attribute 'user_input' #58

Open
disheng34 opened this issue Aug 18, 2021 · 1 comment
Labels
question Further information is requested

Comments

@disheng34
Copy link

Please refer to the FAQ in doc and search for the related issues before you ask the question.

Describe the question(问题描述)
对deepmatch中的sdm模型进行模型存储和加载的尝试,出现
AttributeError: 'Functional' object has no attribute 'user_input'的错误,求助各路大神.谢谢~

Additional context

样例代码:
import pandas as pd
from deepctr.feature_column import SparseFeat, VarLenSparseFeat
from preprocess import gen_data_set_sdm, gen_model_input_sdm
from sklearn.preprocessing import LabelEncoder
from tensorflow.python.keras import backend as K
from tensorflow.python.keras import optimizers
from tensorflow.python.keras.models import Model

from deepmatch.models import SDM
from deepmatch.utils import sampledsoftmaxloss

if name == "main":
data = pd.read_csvdata = pd.read_csv("./movielens_sample.txt")

sparse_features = ["movie_id", "user_id",
                   "gender", "age", "occupation", "zip", "genres"]

SEQ_LEN_short = 5
SEQ_LEN_prefer = 50

# 1.Label Encoding for sparse features,and process sequence features with `gen_date_set` and `gen_model_input`

features = ['user_id', 'movie_id', 'gender', 'age', 'occupation', 'zip', 'genres']
feature_max_idx = {}
for feature in features:
    lbe = LabelEncoder()
    data[feature] = lbe.fit_transform(data[feature]) + 1
    feature_max_idx[feature] = data[feature].max() + 1

user_profile = data[["user_id", "gender", "age", "occupation", "zip", "genres"]].drop_duplicates('user_id')
item_profile = data[["movie_id"]].drop_duplicates('movie_id')
user_profile.set_index("user_id", inplace=True)

# user_item_list = data.groupby("user_id")['movie_id'].apply(list)

train_set, test_set = gen_data_set_sdm(data, seq_short_len=SEQ_LEN_short, seq_prefer_len=SEQ_LEN_prefer)

train_model_input, train_label = gen_model_input_sdm(train_set, user_profile, SEQ_LEN_short, SEQ_LEN_prefer)
test_model_input, test_label = gen_model_input_sdm(test_set, user_profile, SEQ_LEN_short, SEQ_LEN_prefer)

# 2.count #unique features for each sparse field and generate feature config for sequence feature

embedding_dim = 32
# for sdm,we must provide `VarLenSparseFeat` with name "prefer_xxx" and "short_xxx" and their length
user_feature_columns = [SparseFeat('user_id', feature_max_idx['user_id'], 16),
                        SparseFeat("gender", feature_max_idx['gender'], 16),
                        SparseFeat("age", feature_max_idx['age'], 16),
                        SparseFeat("occupation", feature_max_idx['occupation'], 16),
                        SparseFeat("zip", feature_max_idx['zip'], 16),
                        VarLenSparseFeat(SparseFeat('short_movie_id', feature_max_idx['movie_id'], embedding_dim,
                                                    embedding_name="movie_id"), SEQ_LEN_short, 'mean',
                                         'short_sess_length'),
                        VarLenSparseFeat(SparseFeat('prefer_movie_id', feature_max_idx['movie_id'], embedding_dim,
                                                    embedding_name="movie_id"), SEQ_LEN_prefer, 'mean',
                                         'prefer_sess_length'),
                        VarLenSparseFeat(SparseFeat('short_genres', feature_max_idx['genres'], embedding_dim,
                                                    embedding_name="genres"), SEQ_LEN_short, 'mean',
                                         'short_sess_length'),
                        VarLenSparseFeat(SparseFeat('prefer_genres', feature_max_idx['genres'], embedding_dim,
                                                    embedding_name="genres"), SEQ_LEN_prefer, 'mean',
                                         'prefer_sess_length'),
                        ]

item_feature_columns = [SparseFeat('movie_id', feature_max_idx['movie_id'], embedding_dim)]

K.set_learning_phase(True)

import tensorflow as tf

if tf.__version__ >= '2.0.0':
    tf.compat.v1.disable_eager_execution()

# units must be equal to item embedding dim!
model = SDM(user_feature_columns, item_feature_columns, history_feature_list=['movie_id', 'genres'],
            units=embedding_dim, num_sampled=100, )

model.compile(optimizer='adam', loss=sampledsoftmaxloss)  # "binary_crossentropy")

history = model.fit(train_model_input, train_label,  # train_label,
                    batch_size=512, epochs=1, verbose=1, validation_split=0.0, )
model_name = './sdm_model.h5'
model.save(filepath=model_name)

K.set_learning_phase(False)
# from keras_bert import get_custom_objects

from deepmatch.layers import *
from deepctr.layers.utils import *

loaded_model = tf.keras.models.load_model(model_name,
                                          custom_objects={'EmbeddingIndex': EmbeddingIndex,
                                                          'AttentionSequencePoolingLayer': AttentionSequencePoolingLayer,
                                                          'DynamicMultiRNN': DynamicMultiRNN,
                                                          'SelfMultiHeadAttention': SelfMultiHeadAttention,
                                                          'UserAttention': UserAttention,
                                                          'PoolingLayer': PoolingLayer,
                                                          'SampledSoftmaxLayer': SampledSoftmaxLayer,
                                                          'NoMask': NoMask,
                                                          'sampledsoftmaxloss': sampledsoftmaxloss
                                                          })

# # 3.Define Model,train,predict and evaluate
test_user_model_input = test_model_input
all_item_model_input = {"movie_id": item_profile['movie_id'].values, }

user_embedding_model = Model(inputs=loaded_model.user_input, outputs=loaded_model.user_embedding)
item_embedding_model = Model(inputs=loaded_model.item_input, outputs=loaded_model.item_embedding)

user_embs = user_embedding_model.predict(test_user_model_input, batch_size=2 ** 12)
# user_embs = user_embs[:, i, :]  # i in [0,k_max) if MIND
item_embs = item_embedding_model.predict(all_item_model_input, batch_size=2 ** 12)

print(user_embs)
print(item_embs.shape)

报错信息:
Traceback (most recent call last):
File "C:/Users/HP/Desktop/DeepMatch-master/examples/run_sdm_test.py", line 107, in
user_embedding_model = Model(inputs=loaded_model.user_input, outputs=loaded_model.user_embedding)
AttributeError: 'Functional' object has no attribute 'user_input'

Operating environment(运行环境):

  • python version [3.7.5]
  • tensorflow version [2.4.0,]
  • deepmatch version [0.2.0,]
@disheng34 disheng34 added the question Further information is requested label Aug 18, 2021
@WoNiuHu
Copy link

WoNiuHu commented Oct 14, 2022

你好,请问这个问题解决了吗》

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants