shenweichen / DeepMatch

A deep matching model library for recommendations & advertising. It's easy to train models and to export representation vectors which can be used for ANN search.
https://deepmatch.readthedocs.io/en/latest/
Apache License 2.0
2.19k stars 525 forks source link

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

Open disheng34 opened 2 years ago

disheng34 commented 2 years ago

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(运行环境):

WoNiuHu commented 1 year ago

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