概述
模型搭建
import pickle
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
读取数据
title_count, title_set, genres2int, features, targets_values, ratings, users, movies, data, movies_orig, users_orig = pickle.load(open('preprocess.p', mode='rb'))
模型设计
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VOYn4LJz-1580741339497)(attachment:image.png)]
类别数据(UserID,MovieID,Geners,Age,Sex)的处理一般有两种方式:
- onehot encode
- label encode
在类别数据的种类过多时,onehot会使数据过于稀疏,因此只好使用label encode(虽然label encode处理后会出现大小的差异,这样也是不完美的)
所以在预处理数据时将这些字段转成了数字,我们用这个数字当做嵌入矩阵的索引,在网络的第一层使用了嵌入层,维度是(N,32)和(N,16)。
电影类型的处理要多一步,有时一个电影有多个电影类型,这样从嵌入矩阵索引出来是一个(n,32)的矩阵,因为有多个类型嘛,我们要将这个矩阵求和,变成(1,32)的向量。
电影名的处理比较特殊,没有使用循环神经网络,而是用了文本卷积网络,下文会进行说明。
从嵌入层索引出特征以后,将各特征传入全连接层,将输出再次传入全连接层,最终分别得到(1,200)的用户特征和电影特征两个特征向量。
我们的目的就是要训练出用户特征和电影特征,在实现推荐功能时使用。得到这两个特征以后,就可以选择任意的方式来拟合评分了。我使用了两种方式,一个是上图中画出的将两个特征做向量乘法,将结果与真实评分做回归,采用MSE优化损失。因为本质上这是一个回归问题,另一种方式是,将两个特征作为输入,再次传入全连接层,输出一个值,将输出值回归到真实评分,采用MSE优化损失。
实际上第二个方式的MSE loss在0.8附近,第一个方式在1附近,5次迭代的结果
文本卷积网络
CNN的卷积和池化过程就是一个抽取特征的过程,当我们可以准确抽取关键词的特征时,就能准确的提炼出文档或句子的中心思想。
卷积神经网络首次应用于文本分类可以说是在2004年Yoon Kim 在 “Convolutional Neural Networks for Sentence Classification” 一文中提出(虽然第一个用的并不是他,但是在这篇文章中提出了4种Model Variations,并有详细的调参),本文也是基于对这篇文章的理解。接下来将介绍text-CNN模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BDJBXWRP-1580741339498)(attachment:image.png)]
论文使用的模型主要包括五层,第一层是embedding layer,第二层是convolutional layer,第三层是max-pooling layer,第四层是fully connected layer,最后一层是softmax layer.
下图描述了更具体的步骤
输入层
首先输入一个一维的由7个单词构成的句子,为了使其可以进行卷积,首先需要将其转化为二维矩阵表示,通常使用word2vec、glove等word embedding实现。d=5表示每个词转化为5维的向量,矩阵的形状是[sentence_matrix × 5],即[7 × 5]。
卷积层
在处理图像数据时,CNN使用的卷积核的宽度和高度的一样的,但是在text-CNN中,卷积核的宽度是与词向量的维度一致。这是因为我们输入的每一行向量代表一个词,在抽取特征的过程中,词做为文本的最小粒度,如果我们使用卷积核的宽度小于词向量的维度就已经不是以词作为最小粒度了。而高度和CNN一样,可以自行设置(通常取值2,3,4,5)。由于我们的输入是一个句子,句子中相邻的词之间关联性很高,因此,当我们用卷积核进行卷积时,不仅考虑了词义而且考虑了词序及其上下文。(类似于skip-gram和CBOW模型的思想)。
本推荐系统模型所使用的网络
网络的第一层是词嵌入层,由每一个单词的嵌入向量组成的嵌入矩阵。下一层使用多个不同尺寸(窗口大小)的卷积核在嵌入矩阵上做卷积,窗口大小指的是每次卷积覆盖几个单词。这里跟对图像做卷积不太一样,图像的卷积通常用2x2、3x3、5x5之类的尺寸,而文本卷积要覆盖整个单词的嵌入向量,所以尺寸是(单词数,向量维度),比如每次滑动3个,4个或者5个单词。第三层网络是max pooling得到一个长向量,最后使用dropout做正则化,最终得到了电影Title的特征。
辅助函数
import tensorflow as tf
import os
import pickle
def save_params(params):
pickle.dump(params,open('params.p','wb'))
def load_params():
return pickle.load(open('params.p','rb'))
编码实现
#嵌入矩阵的维度
embed_dim = 32
#用户ID个数
uid_max = max(features.take(0,1)) + 1 # 6040
#性别个数
gender_max = max(features.take(2,1)) + 1 # 1 + 1 = 2
#年龄类别个数
age_max = max(features.take(3,1)) + 1 # 6 + 1 = 7
#职业个数
job_max = max(features.take(4,1)) + 1# 20 + 1 = 21
#电影ID个数
movie_id_max = max(features.take(1,1)) + 1 # 3952
#电影类型个数
movie_categories_max = max(genres2int.values()) + 1 # 18 + 1 = 19
#电影名单词个数
movie_title_max = len(title_set) # 5216
#对电影类型嵌入向量做加和操作的标志,考虑过使用mean做平均,但是没实现mean
combiner = "sum"
#电影名长度
sentences_size = title_count # = 15
#文本卷积滑动窗口,分别滑动2, 3, 4, 5个单词
window_sizes = {2, 3, 4, 5}
#文本卷积核数量
filter_num = 8
#电影ID转下标的字典,数据集中电影ID跟下标不一致,比如第5行的数据电影ID不一定是5
movieid2idx = {val[0]:i for i, val in enumerate(movies.values)}
超参
# Number of Epochs
num_epochs = 5
# Batch Size
batch_size = 256
dropout_keep = 0.5
# Learning Rate
learning_rate = 0.0001
# Show stats for every n number of batches
show_every_n_batches = 20
save_dir = './save'
输入
定义输入数据的占位符
def get_inputs():
uid = tf.keras.layers.Input(shape=(1,), dtype='int32', name='uid')
user_gender = tf.keras.layers.Input(shape=(1,), dtype='int32', name='user_gender')
user_age = tf.keras.layers.Input(shape=(1,), dtype='int32', name='user_age')
user_job = tf.keras.layers.Input(shape=(1,), dtype='int32', name='user_job')
movie_id = tf.keras.layers.Input(shape=(1,), dtype='int32', name='movie_id')
movie_categories = tf.keras.layers.Input(shape=(18,), dtype='int32', name='movie_categories')
movie_titles = tf.keras.layers.Input(shape=(15,), dtype='int32', name='movie_titles')
return uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles
构建神经网络
定义User的嵌入矩阵
def get_user_embedding(uid, user_gender, user_age, user_job):
uid_embed_layer = tf.keras.layers.Embedding(uid_max, embed_dim, input_length=1, name='uid_embed_layer')(uid)
gender_embed_layer = tf.keras.layers.Embedding(gender_max, embed_dim // 2, input_length=1, name='gender_embed_layer')(user_gender)
age_embed_layer = tf.keras.layers.Embedding(age_max, embed_dim // 2, input_length=1, name='age_embed_layer')(user_age)
job_embed_layer = tf.keras.layers.Embedding(job_max, embed_dim // 2, input_length=1, name='job_embed_layer')(user_job)
return uid_embed_layer, gender_embed_layer, age_embed_layer, job_embed_layer
将User的嵌入矩阵一起全连接生成User的特征
def get_user_feature_layer(uid_embed_layer, gender_embed_layer, age_embed_layer, job_embed_layer):
#第一层全连接
uid_fc_layer = tf.keras.layers.Dense(embed_dim, name="uid_fc_layer", activation='relu')(uid_embed_layer)
gender_fc_layer = tf.keras.layers.Dense(embed_dim, name="gender_fc_layer", activation='relu')(gender_embed_layer)
age_fc_layer = tf.keras.layers.Dense(embed_dim, name="age_fc_layer", activation='relu')(age_embed_layer)
job_fc_layer = tf.keras.layers.Dense(embed_dim, name="job_fc_layer", activation='relu')(job_embed_layer)
#第二层全连接
user_combine_layer = tf.keras.layers.concatenate([uid_fc_layer, gender_fc_layer, age_fc_layer, job_fc_layer], 2) #(?, 1, 128)
user_combine_layer = tf.keras.layers.Dense(200, activation='tanh')(user_combine_layer) #(?, 1, 200)
user_combine_layer_flat = tf.keras.layers.Reshape([200], name="user_combine_layer_flat")(user_combine_layer)
return user_combine_layer, user_combine_layer_flat
定义Movie ID的嵌入矩阵
def get_movie_id_embed_layer(movie_id):
movie_id_embed_layer = tf.keras.layers.Embedding(movie_id_max, embed_dim, input_length=1, name='movie_id_embed_layer')(movie_id)
return movie_id_embed_layer
合并电影类型的多个嵌入向量
def get_movie_categories_layers(movie_categories):
movie_categories_embed_layer = tf.keras.layers.Embedding(movie_categories_max, embed_dim, input_length=18, name='movie_categories_embed_layer')(movie_categories)
movie_categories_embed_layer = tf.keras.layers.Lambda(lambda layer: tf.reduce_sum(layer, axis=1, keepdims=True))(movie_categories_embed_layer)
# movie_categories_embed_layer = tf.keras.layers.Reshape([1, 18 * embed_dim])(movie_categories_embed_layer)
return movie_categories_embed_layer
Movie Title的文本卷积网络实现
def get_movie_cnn_layer(movie_titles):
#从嵌入矩阵中得到电影名对应的各个单词的嵌入向量
movie_title_embed_layer = tf.keras.layers.Embedding(movie_title_max, embed_dim, input_length=15, name='movie_title_embed_layer')(movie_titles)
sp=movie_title_embed_layer.shape
movie_title_embed_layer_expand = tf.keras.layers.Reshape([sp[1], sp[2], 1])(movie_title_embed_layer)
#对文本嵌入层使用不同尺寸的卷积核做卷积和最大池化
pool_layer_lst = []
for window_size in window_sizes:
conv_layer = tf.keras.layers.Conv2D(filter_num, (window_size, embed_dim), 1, activation='relu')(movie_title_embed_layer_expand)
maxpool_layer = tf.keras.layers.MaxPooling2D(pool_size=(sentences_size - window_size + 1 ,1), strides=1)(conv_layer)
pool_layer_lst.append(maxpool_layer)
#Dropout层
pool_layer = tf.keras.layers.concatenate(pool_layer_lst, 3, name ="pool_layer")
max_num = len(window_sizes) * filter_num
pool_layer_flat = tf.keras.layers.Reshape([1, max_num], name = "pool_layer_flat")(pool_layer)
dropout_layer = tf.keras.layers.Dropout(dropout_keep, name = "dropout_layer")(pool_layer_flat)
return pool_layer_flat, dropout_layer
将Movie的各个层一起做全连接
def get_movie_feature_layer(movie_id_embed_layer, movie_categories_embed_layer, dropout_layer):
#第一层全连接
movie_id_fc_layer = tf.keras.layers.Dense(embed_dim, name="movie_id_fc_layer", activation='relu')(movie_id_embed_layer)
movie_categories_fc_layer = tf.keras.layers.Dense(embed_dim, name="movie_categories_fc_layer", activation='relu')(movie_categories_embed_layer)
#第二层全连接
movie_combine_layer = tf.keras.layers.concatenate([movie_id_fc_layer, movie_categories_fc_layer, dropout_layer], 2)
movie_combine_layer = tf.keras.layers.Dense(200, activation='tanh')(movie_combine_layer)
movie_combine_layer_flat = tf.keras.layers.Reshape([200], name="movie_combine_layer_flat")(movie_combine_layer)
return movie_combine_layer, movie_combine_layer_flat
构建计算图
import tensorflow as tf
import datetime
from tensorflow import keras
from tensorflow.python.ops import summary_ops_v2
import time
MODEL_DIR = "./models"
class mv_network(object):
def __init__(self, batch_size=256):
self.batch_size = batch_size
self.best_loss = 9999
self.losses = {'train': [], 'test': []}
# 获取输入占位符
uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles = get_inputs()
# 获取User的4个嵌入向量
uid_embed_layer, gender_embed_layer, age_embed_layer, job_embed_layer = get_user_embedding(uid, user_gender,
user_age, user_job)
# 得到用户特征
user_combine_layer, user_combine_layer_flat = get_user_feature_layer(uid_embed_layer, gender_embed_layer,
age_embed_layer, job_embed_layer)
# 获取电影ID的嵌入向量
movie_id_embed_layer = get_movie_id_embed_layer(movie_id)
# 获取电影类型的嵌入向量
movie_categories_embed_layer = get_movie_categories_layers(movie_categories)
# 获取电影名的特征向量
pool_layer_flat, dropout_layer = get_movie_cnn_layer(movie_titles)
# 得到电影特征
movie_combine_layer, movie_combine_layer_flat = get_movie_feature_layer(movie_id_embed_layer,
movie_categories_embed_layer,
dropout_layer)
# 计算出评分
# 将用户特征和电影特征做矩阵乘法得到一个预测评分的方案
inference = tf.keras.layers.Lambda(lambda layer:
tf.reduce_sum(layer[0] * layer[1], axis=1), name="inference")((user_combine_layer_flat, movie_combine_layer_flat))
inference = tf.keras.layers.Lambda(lambda layer: tf.expand_dims(layer, axis=1))(inference)
# 将用户特征和电影特征作为输入,经过全连接,输出一个值的方案
# inference_layer = tf.keras.layers.concatenate([user_combine_layer_flat, movie_combine_layer_flat],
# 1) # (?, 400)
# 你可以使用下面这个全连接层,试试效果
#inference_dense = tf.keras.layers.Dense(64, kernel_regularizer=tf.nn.l2_loss, activation='relu')(
# inference_layer)
# inference = tf.keras.layers.Dense(1, name="inference")(inference_layer) # inference_dense
self.model = tf.keras.Model(
inputs=[uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles],
outputs=[inference])
self.model.summary()
self.optimizer = tf.keras.optimizers.Adam(learning_rate)
# MSE损失,将计算值回归到评分
self.ComputeLoss = tf.keras.losses.MeanSquaredError()
self.ComputeMetrics = tf.keras.metrics.MeanAbsoluteError()
if tf.io.gfile.exists(MODEL_DIR):
# print('Removing existing model dir: {}'.format(MODEL_DIR))
# tf.io.gfile.rmtree(MODEL_DIR)
pass
else:
tf.io.gfile.makedirs(MODEL_DIR)
train_dir = os.path.join(MODEL_DIR, 'summaries', 'train')
test_dir = os.path.join(MODEL_DIR, 'summaries', 'eval')
# self.train_summary_writer = summary_ops_v2.create_file_writer(train_dir, flush_millis=10000)
# self.test_summary_writer = summary_ops_v2.create_file_writer(test_dir, flush_millis=10000, name='test')
checkpoint_dir = os.path.join(MODEL_DIR, 'checkpoints')
self.checkpoint_prefix = os.path.join(checkpoint_dir, 'ckpt')
self.checkpoint = tf.train.Checkpoint(model=self.model, optimizer=self.optimizer)
# Restore variables on creation if a checkpoint exists.
self.checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
def compute_loss(self, labels, logits):
return tf.reduce_mean(tf.keras.losses.mse(labels, logits))
def compute_metrics(self, labels, logits):
return tf.keras.metrics.mae(labels, logits) #
@tf.function
def train_step(self, x, y):
# Record the operations used to compute the loss, so that the gradient
# of the loss with respect to the variables can be computed.
# metrics = 0
with tf.GradientTape() as tape:
logits = self.model([x[0],
x[1],
x[2],
x[3],
x[4],
x[5],
x[6]], training=True)
loss = self.ComputeLoss(y, logits)
# loss = self.compute_loss(labels, logits)
self.ComputeMetrics(y, logits)
# metrics = self.compute_metrics(labels, logits)
grads = tape.gradient(loss, self.model.trainable_variables)
self.optimizer.apply_gradients(zip(grads, self.model.trainable_variables))
return loss, logits
def training(self, features, targets_values, epochs=5, log_freq=50):
for epoch_i in range(epochs):
# 将数据集分成训练集和测试集,随机种子不固定
train_X, test_X, train_y, test_y = train_test_split(features,
targets_values,
test_size=0.2,
random_state=0)
train_batches = get_batches(train_X, train_y, self.batch_size)
batch_num = (len(train_X) // self.batch_size)
train_start = time.time()
# with self.train_summary_writer.as_default():
if True:
start = time.time()
# Metrics are stateful. They accumulate values and return a cumulative
# result when you call .result(). Clear accumulated values with .reset_states()
avg_loss = tf.keras.metrics.Mean('loss', dtype=tf.float32)
# avg_mae = tf.keras.metrics.Mean('mae', dtype=tf.float32)
# Datasets can be iterated over like any other Python iterable.
for batch_i in range(batch_num):
x, y = next(train_batches)
categories = np.zeros([self.batch_size, 18])
for i in range(self.batch_size):
categories[i] = x.take(6, 1)[i]
titles = np.zeros([self.batch_size, sentences_size])
for i in range(self.batch_size):
titles[i] = x.take(5, 1)[i]
loss, logits = self.train_step([np.reshape(x.take(0, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(2, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(3, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(4, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(1, 1), [self.batch_size, 1]).astype(np.float32),
categories.astype(np.float32),
titles.astype(np.float32)],
np.reshape(y, [self.batch_size, 1]).astype(np.float32))
avg_loss(loss)
# avg_mae(metrics)
self.losses['train'].append(loss)
if tf.equal(self.optimizer.iterations % log_freq, 0):
# summary_ops_v2.scalar('loss', avg_loss.result(), step=self.optimizer.iterations)
# summary_ops_v2.scalar('mae', self.ComputeMetrics.result(), step=self.optimizer.iterations)
# summary_ops_v2.scalar('mae', avg_mae.result(), step=self.optimizer.iterations)
rate = log_freq / (time.time() - start)
print('Step #{}tEpoch {:>3} Batch {:>4}/{} Loss: {:0.6f} mae: {:0.6f} ({} steps/sec)'.format(
self.optimizer.iterations.numpy(),
epoch_i,
batch_i,
batch_num,
loss, (self.ComputeMetrics.result()), rate))
# print('Step #{}tLoss: {:0.6f} mae: {:0.6f} ({} steps/sec)'.format(
# self.optimizer.iterations.numpy(), loss, (avg_mae.result()), rate))
avg_loss.reset_states()
self.ComputeMetrics.reset_states()
# avg_mae.reset_states()
start = time.time()
train_end = time.time()
print(
'nTrain time for epoch #{} ({} total steps): {}'.format(epoch_i + 1, self.optimizer.iterations.numpy(),
train_end - train_start))
# with self.test_summary_writer.as_default():
self.testing((test_X, test_y), self.optimizer.iterations)
# self.checkpoint.save(self.checkpoint_prefix)
self.export_path = os.path.join(MODEL_DIR, 'export')
tf.saved_model.save(self.model, self.export_path)
def testing(self, test_dataset, step_num):
test_X, test_y = test_dataset
test_batches = get_batches(test_X, test_y, self.batch_size)
"""Perform an evaluation of `model` on the examples from `dataset`."""
avg_loss = tf.keras.metrics.Mean('loss', dtype=tf.float32)
# avg_mae = tf.keras.metrics.Mean('mae', dtype=tf.float32)
batch_num = (len(test_X) // self.batch_size)
for batch_i in range(batch_num):
x, y = next(test_batches)
categories = np.zeros([self.batch_size, 18])
for i in range(self.batch_size):
categories[i] = x.take(6, 1)[i]
titles = np.zeros([self.batch_size, sentences_size])
for i in range(self.batch_size):
titles[i] = x.take(5, 1)[i]
logits = self.model([np.reshape(x.take(0, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(2, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(3, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(4, 1), [self.batch_size, 1]).astype(np.float32),
np.reshape(x.take(1, 1), [self.batch_size, 1]).astype(np.float32),
categories.astype(np.float32),
titles.astype(np.float32)], training=False)
test_loss = self.ComputeLoss(np.reshape(y, [self.batch_size, 1]).astype(np.float32), logits)
avg_loss(test_loss)
# 保存测试损失
self.losses['test'].append(test_loss)
self.ComputeMetrics(np.reshape(y, [self.batch_size, 1]).astype(np.float32), logits)
# avg_loss(self.compute_loss(labels, logits))
# avg_mae(self.compute_metrics(labels, logits))
print('Model test set loss: {:0.6f} mae: {:0.6f}'.format(avg_loss.result(), self.ComputeMetrics.result()))
# print('Model test set loss: {:0.6f} mae: {:0.6f}'.format(avg_loss.result(), avg_mae.result()))
# summary_ops_v2.scalar('loss', avg_loss.result(), step=step_num)
# summary_ops_v2.scalar('mae', self.ComputeMetrics.result(), step=step_num)
# summary_ops_v2.scalar('mae', avg_mae.result(), step=step_num)
if avg_loss.result() < self.best_loss:
self.best_loss = avg_loss.result()
print("best loss = {}".format(self.best_loss))
self.checkpoint.save(self.checkpoint_prefix)
def forward(self, xs):
predictions = self.model(xs)
# logits = tf.nn.softmax(predictions)
return predictions
取得batch
def get_batches(Xs, ys, batch_size):
for start in range(0, len(Xs), batch_size):
end = min(start + batch_size, len(Xs))
yield Xs[start:end], ys[start:end]
训练网络
将用户特征和电影特征作为输入,经过全连接,输出一个值的训练
mv_net=mv_network()
mv_net.training(features, targets_values, epochs=5)
Model: "model_3"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
movie_titles (InputLayer) [(None, 15)] 0
__________________________________________________________________________________________________
movie_title_embed_layer (Embedd (None, 15, 32) 166880 movie_titles[0][0]
__________________________________________________________________________________________________
reshape_3 (Reshape) (None, 15, 32, 1) 0 movie_title_embed_layer[0][0]
__________________________________________________________________________________________________
conv2d_12 (Conv2D) (None, 14, 1, 8) 520 reshape_3[0][0]
__________________________________________________________________________________________________
conv2d_13 (Conv2D) (None, 13, 1, 8) 776 reshape_3[0][0]
__________________________________________________________________________________________________
conv2d_14 (Conv2D) (None, 12, 1, 8) 1032 reshape_3[0][0]
__________________________________________________________________________________________________
conv2d_15 (Conv2D) (None, 11, 1, 8) 1288 reshape_3[0][0]
__________________________________________________________________________________________________
movie_categories (InputLayer) [(None, 18)] 0
__________________________________________________________________________________________________
max_pooling2d_12 (MaxPooling2D) (None, 1, 1, 8) 0 conv2d_12[0][0]
__________________________________________________________________________________________________
max_pooling2d_13 (MaxPooling2D) (None, 1, 1, 8) 0 conv2d_13[0][0]
__________________________________________________________________________________________________
max_pooling2d_14 (MaxPooling2D) (None, 1, 1, 8) 0 conv2d_14[0][0]
__________________________________________________________________________________________________
max_pooling2d_15 (MaxPooling2D) (None, 1, 1, 8) 0 conv2d_15[0][0]
__________________________________________________________________________________________________
uid (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
user_gender (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
user_age (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
user_job (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
movie_id (InputLayer) [(None, 1)] 0
__________________________________________________________________________________________________
movie_categories_embed_layer (E (None, 18, 32) 608 movie_categories[0][0]
__________________________________________________________________________________________________
pool_layer (Concatenate) (None, 1, 1, 32) 0 max_pooling2d_12[0][0]
max_pooling2d_13[0][0]
max_pooling2d_14[0][0]
max_pooling2d_15[0][0]
__________________________________________________________________________________________________
uid_embed_layer (Embedding) (None, 1, 32) 193312 uid[0][0]
__________________________________________________________________________________________________
gender_embed_layer (Embedding) (None, 1, 16) 32 user_gender[0][0]
__________________________________________________________________________________________________
age_embed_layer (Embedding) (None, 1, 16) 112 user_age[0][0]
__________________________________________________________________________________________________
job_embed_layer (Embedding) (None, 1, 16) 336 user_job[0][0]
__________________________________________________________________________________________________
movie_id_embed_layer (Embedding (None, 1, 32) 126496 movie_id[0][0]
__________________________________________________________________________________________________
lambda_6 (Lambda) (None, 1, 32) 0 movie_categories_embed_layer[0][0
__________________________________________________________________________________________________
pool_layer_flat (Reshape) (None, 1, 32) 0 pool_layer[0][0]
__________________________________________________________________________________________________
uid_fc_layer (Dense) (None, 1, 32) 1056 uid_embed_layer[0][0]
__________________________________________________________________________________________________
gender_fc_layer (Dense) (None, 1, 32) 544 gender_embed_layer[0][0]
__________________________________________________________________________________________________
age_fc_layer (Dense) (None, 1, 32) 544 age_embed_layer[0][0]
__________________________________________________________________________________________________
job_fc_layer (Dense) (None, 1, 32) 544 job_embed_layer[0][0]
__________________________________________________________________________________________________
movie_id_fc_layer (Dense) (None, 1, 32) 1056 movie_id_embed_layer[0][0]
__________________________________________________________________________________________________
movie_categories_fc_layer (Dens (None, 1, 32) 1056 lambda_6[0][0]
__________________________________________________________________________________________________
dropout_layer (Dropout) (None, 1, 32) 0 pool_layer_flat[0][0]
__________________________________________________________________________________________________
concatenate_6 (Concatenate) (None, 1, 128) 0 uid_fc_layer[0][0]
gender_fc_layer[0][0]
age_fc_layer[0][0]
job_fc_layer[0][0]
__________________________________________________________________________________________________
concatenate_7 (Concatenate) (None, 1, 96) 0 movie_id_fc_layer[0][0]
movie_categories_fc_layer[0][0]
dropout_layer[0][0]
__________________________________________________________________________________________________
dense_6 (Dense) (None, 1, 200) 25800 concatenate_6[0][0]
__________________________________________________________________________________________________
dense_7 (Dense) (None, 1, 200) 19400 concatenate_7[0][0]
__________________________________________________________________________________________________
user_combine_layer_flat (Reshap (None, 200) 0 dense_6[0][0]
__________________________________________________________________________________________________
movie_combine_layer_flat (Resha (None, 200) 0 dense_7[0][0]
__________________________________________________________________________________________________
inference (Lambda) (None,) 0 user_combine_layer_flat[0][0]
movie_combine_layer_flat[0][0]
__________________________________________________________________________________________________
lambda_7 (Lambda) (None, 1) 0 inference[0][0]
==================================================================================================
Total params: 541,392
Trainable params: 541,392
Non-trainable params: 0
__________________________________________________________________________________________________
Step #18800 Epoch 0 Batch 49/3125 Loss: 0.848101 mae: 0.691804 (27.637772944410063 steps/sec)
Step #18850 Epoch 0 Batch 99/3125 Loss: 0.947761 mae: 0.682926 (97.27970550089155 steps/sec)
Step #18900 Epoch 0 Batch 149/3125 Loss: 0.746948 mae: 0.693619 (94.22213516055017 steps/sec)
Step #18950 Epoch 0 Batch 199/3125 Loss: 0.792230 mae: 0.693281 (94.88800226592596 steps/sec)
Step #19000 Epoch 0 Batch 249/3125 Loss: 0.853272 mae: 0.691730 (94.83132146030555 steps/sec)
Step #19050 Epoch 0 Batch 299/3125 Loss: 0.751092 mae: 0.691599 (101.01586561480342 steps/sec)
Step #19100 Epoch 0 Batch 349/3125 Loss: 0.843071 mae: 0.694882 (101.83058405828346 steps/sec)
Step #19150 Epoch 0 Batch 399/3125 Loss: 0.874644 mae: 0.695321 (101.51983099649716 steps/sec)
Step #19200 Epoch 0 Batch 449/3125 Loss: 0.786772 mae: 0.698967 (98.81082232255979 steps/sec)
Step #19250 Epoch 0 Batch 499/3125 Loss: 0.760961 mae: 0.686922 (97.884092537404 steps/sec)
Step #19300 Epoch 0 Batch 549/3125 Loss: 0.752310 mae: 0.686976 (98.99852103058629 steps/sec)
Step #19350 Epoch 0 Batch 599/3125 Loss: 0.685646 mae: 0.697807 (96.76298892450912 steps/sec)
Step #19400 Epoch 0 Batch 649/3125 Loss: 0.715844 mae: 0.693816 (96.13379460763798 steps/sec)
Step #19450 Epoch 0 Batch 699/3125 Loss: 0.768952 mae: 0.693204 (97.33149111525822 steps/sec)
Step #19500 Epoch 0 Batch 749/3125 Loss: 0.745624 mae: 0.683436 (95.30070259292735 steps/sec)
Step #19550 Epoch 0 Batch 799/3125 Loss: 0.821963 mae: 0.691857 (102.57208871915968 steps/sec)
Step #19600 Epoch 0 Batch 849/3125 Loss: 0.850824 mae: 0.691828 (103.89249070757201 steps/sec)
Step #19650 Epoch 0 Batch 899/3125 Loss: 0.845563 mae: 0.689795 (97.78815221765309 steps/sec)
Step #19700 Epoch 0 Batch 949/3125 Loss: 0.674638 mae: 0.691894 (103.42582459718882 steps/sec)
Step #19750 Epoch 0 Batch 999/3125 Loss: 0.847141 mae: 0.687374 (105.39066598857019 steps/sec)
Step #19800 Epoch 0 Batch 1049/3125 Loss: 0.838690 mae: 0.698633 (103.69963799235833 steps/sec)
Step #19850 Epoch 0 Batch 1099/3125 Loss: 0.739785 mae: 0.690680 (104.66621782071482 steps/sec)
Step #19900 Epoch 0 Batch 1149/3125 Loss: 0.703950 mae: 0.697995 (105.42616329866972 steps/sec)
Step #19950 Epoch 0 Batch 1199/3125 Loss: 0.824220 mae: 0.687212 (103.49937766687756 steps/sec)
Step #20000 Epoch 0 Batch 1249/3125 Loss: 0.868953 mae: 0.693830 (97.82332065811619 steps/sec)
Step #20050 Epoch 0 Batch 1299/3125 Loss: 0.730640 mae: 0.699454 (93.00487297794476 steps/sec)
Step #20100 Epoch 0 Batch 1349/3125 Loss: 0.803740 mae: 0.677289 (98.04966835245015 steps/sec)
Step #20150 Epoch 0 Batch 1399/3125 Loss: 0.786500 mae: 0.693733 (97.83203685346085 steps/sec)
Step #20200 Epoch 0 Batch 1449/3125 Loss: 0.737920 mae: 0.692194 (100.51230239884435 steps/sec)
Step #20250 Epoch 0 Batch 1499/3125 Loss: 0.805032 mae: 0.691858 (97.52258504938787 steps/sec)
Step #20300 Epoch 0 Batch 1549/3125 Loss: 0.854445 mae: 0.691005 (98.68922723041723 steps/sec)
Step #20350 Epoch 0 Batch 1599/3125 Loss: 0.768004 mae: 0.687592 (96.64294930875576 steps/sec)
Step #20400 Epoch 0 Batch 1649/3125 Loss: 0.820738 mae: 0.693461 (97.56441599344966 steps/sec)
Step #20450 Epoch 0 Batch 1699/3125 Loss: 0.810527 mae: 0.687126 (104.0909700059065 steps/sec)
Step #20500 Epoch 0 Batch 1749/3125 Loss: 0.785807 mae: 0.689348 (104.86331505067027 steps/sec)
Step #20550 Epoch 0 Batch 1799/3125 Loss: 0.852628 mae: 0.690730 (100.98035816778955 steps/sec)
Step #20600 Epoch 0 Batch 1849/3125 Loss: 0.745395 mae: 0.692310 (100.04140660330376 steps/sec)
Step #20650 Epoch 0 Batch 1899/3125 Loss: 0.860758 mae: 0.689794 (103.83014876291656 steps/sec)
Step #20700 Epoch 0 Batch 1949/3125 Loss: 0.729740 mae: 0.682986 (104.72894049659993 steps/sec)
Step #20750 Epoch 0 Batch 1999/3125 Loss: 0.843179 mae: 0.691823 (104.53922578786306 steps/sec)
Step #20800 Epoch 0 Batch 2049/3125 Loss: 0.728389 mae: 0.698972 (105.46375291990717 steps/sec)
Step #20850 Epoch 0 Batch 2099/3125 Loss: 0.808849 mae: 0.679972 (104.75865544992755 steps/sec)
Step #20900 Epoch 0 Batch 2149/3125 Loss: 0.742408 mae: 0.680288 (98.92170421676859 steps/sec)
Step #20950 Epoch 0 Batch 2199/3125 Loss: 0.676885 mae: 0.686084 (95.43749024419213 steps/sec)
Step #21000 Epoch 0 Batch 2249/3125 Loss: 0.738224 mae: 0.685648 (102.49558914808244 steps/sec)
Step #21050 Epoch 0 Batch 2299/3125 Loss: 0.811326 mae: 0.699091 (104.40786312956938 steps/sec)
Step #21100 Epoch 0 Batch 2349/3125 Loss: 0.744082 mae: 0.691439 (98.69243182268463 steps/sec)
Step #21150 Epoch 0 Batch 2399/3125 Loss: 0.715450 mae: 0.689829 (98.54250365337356 steps/sec)
Step #21200 Epoch 0 Batch 2449/3125 Loss: 0.733722 mae: 0.681757 (97.19778292029201 steps/sec)
Step #21250 Epoch 0 Batch 2499/3125 Loss: 0.895794 mae: 0.691461 (93.82907166061841 steps/sec)
Step #21300 Epoch 0 Batch 2549/3125 Loss: 0.594887 mae: 0.695868 (91.97760768538483 steps/sec)
Step #21350 Epoch 0 Batch 2599/3125 Loss: 0.896662 mae: 0.690421 (99.11315046856753 steps/sec)
Step #21400 Epoch 0 Batch 2649/3125 Loss: 0.857583 mae: 0.692567 (102.56140400640265 steps/sec)
Step #21450 Epoch 0 Batch 2699/3125 Loss: 0.758102 mae: 0.687871 (98.85618904722645 steps/sec)
Step #21500 Epoch 0 Batch 2749/3125 Loss: 0.856856 mae: 0.685238 (99.84911830144058 steps/sec)
Step #21550 Epoch 0 Batch 2799/3125 Loss: 0.798290 mae: 0.694276 (100.47767755758721 steps/sec)
Step #21600 Epoch 0 Batch 2849/3125 Loss: 0.779489 mae: 0.686759 (88.33807145471769 steps/sec)
Step #21650 Epoch 0 Batch 2899/3125 Loss: 0.822600 mae: 0.685006 (94.11055146491282 steps/sec)
Step #21700 Epoch 0 Batch 2949/3125 Loss: 0.837273 mae: 0.689872 (99.90215348088753 steps/sec)
Step #21750 Epoch 0 Batch 2999/3125 Loss: 0.706622 mae: 0.687190 (103.2946995484817 steps/sec)
Step #21800 Epoch 0 Batch 3049/3125 Loss: 0.730821 mae: 0.679799 (95.09064923570253 steps/sec)
Step #21850 Epoch 0 Batch 3099/3125 Loss: 0.830290 mae: 0.684865 (100.44442358323519 steps/sec)
Train time for epoch #1 (21875 total steps): 32.83831572532654
Model test set loss: 0.788444 mae: 0.700780
best loss = 0.7884443998336792
Step #21900 Epoch 1 Batch 24/3125 Loss: 0.678443 mae: 0.700345 (170.22752177406917 steps/sec)
Step #21950 Epoch 1 Batch 74/3125 Loss: 0.812340 mae: 0.681441 (95.51281700943126 steps/sec)
Step #22000 Epoch 1 Batch 124/3125 Loss: 0.659081 mae: 0.690085 (91.39661512741866 steps/sec)
Step #22050 Epoch 1 Batch 174/3125 Loss: 0.768032 mae: 0.687947 (95.5915741473845 steps/sec)
Step #22100 Epoch 1 Batch 224/3125 Loss: 0.636173 mae: 0.691459 (95.35816285375337 steps/sec)
Step #22150 Epoch 1 Batch 274/3125 Loss: 0.764309 mae: 0.687606 (96.18635225136346 steps/sec)
Step #22200 Epoch 1 Batch 324/3125 Loss: 0.744969 mae: 0.689999 (94.08859569153022 steps/sec)
Step #22250 Epoch 1 Batch 374/3125 Loss: 0.763131 mae: 0.691957 (97.47227214777158 steps/sec)
Step #22300 Epoch 1 Batch 424/3125 Loss: 0.831872 mae: 0.693085 (97.65564282511221 steps/sec)
Step #22350 Epoch 1 Batch 474/3125 Loss: 0.763018 mae: 0.689512 (94.82304598200075 steps/sec)
Step #22400 Epoch 1 Batch 524/3125 Loss: 0.835540 mae: 0.683687 (91.60585169139671 steps/sec)
Step #22450 Epoch 1 Batch 574/3125 Loss: 0.818543 mae: 0.689819 (94.79642846326554 steps/sec)
Step #22500 Epoch 1 Batch 624/3125 Loss: 0.592940 mae: 0.686780 (94.30895478894674 steps/sec)
Step #22550 Epoch 1 Batch 674/3125 Loss: 0.791231 mae: 0.690431 (94.42547366904402 steps/sec)
Step #22600 Epoch 1 Batch 724/3125 Loss: 0.644314 mae: 0.690026 (84.83425550695009 steps/sec)
Step #22650 Epoch 1 Batch 774/3125 Loss: 0.718745 mae: 0.681867 (89.78514349811302 steps/sec)
Step #22700 Epoch 1 Batch 824/3125 Loss: 0.786647 mae: 0.688625 (86.77908647320926 steps/sec)
Step #22750 Epoch 1 Batch 874/3125 Loss: 0.692773 mae: 0.686636 (88.38308191426324 steps/sec)
Step #22800 Epoch 1 Batch 924/3125 Loss: 0.861632 mae: 0.693288 (84.86120311272774 steps/sec)
Step #22850 Epoch 1 Batch 974/3125 Loss: 0.712722 mae: 0.687713 (85.69058664990843 steps/sec)
Step #22900 Epoch 1 Batch 1024/3125 Loss: 0.716715 mae: 0.684843 (81.83209442981173 steps/sec)
Step #22950 Epoch 1 Batch 1074/3125 Loss: 0.780225 mae: 0.689261 (85.32402879243311 steps/sec)
Step #23000 Epoch 1 Batch 1124/3125 Loss: 0.770114 mae: 0.693500 (87.99868074487561 steps/sec)
Step #23050 Epoch 1 Batch 1174/3125 Loss: 0.700080 mae: 0.690776 (89.22923358196857 steps/sec)
Step #23100 Epoch 1 Batch 1224/3125 Loss: 0.753743 mae: 0.682393 (86.86851950651322 steps/sec)
Step #23150 Epoch 1 Batch 1274/3125 Loss: 0.858793 mae: 0.697203 (85.37411670451299 steps/sec)
Step #23200 Epoch 1 Batch 1324/3125 Loss: 0.666164 mae: 0.684622 (98.41385446504661 steps/sec)
Step #23250 Epoch 1 Batch 1374/3125 Loss: 0.701718 mae: 0.682613 (94.23792790444777 steps/sec)
Step #23300 Epoch 1 Batch 1424/3125 Loss: 0.767711 mae: 0.688312 (95.42172709453028 steps/sec)
Step #23350 Epoch 1 Batch 1474/3125 Loss: 0.666887 mae: 0.689093 (91.94046968222995 steps/sec)
Step #23400 Epoch 1 Batch 1524/3125 Loss: 0.686597 mae: 0.683916 (96.19791205570175 steps/sec)
Step #23450 Epoch 1 Batch 1574/3125 Loss: 0.724204 mae: 0.691114 (97.00158697340443 steps/sec)
Step #23500 Epoch 1 Batch 1624/3125 Loss: 0.796998 mae: 0.682731 (93.58855526612791 steps/sec)
Step #23550 Epoch 1 Batch 1674/3125 Loss: 0.655430 mae: 0.689436 (94.92743126973551 steps/sec)
Step #23600 Epoch 1 Batch 1724/3125 Loss: 0.860071 mae: 0.685661 (93.87716367373761 steps/sec)
Step #23650 Epoch 1 Batch 1774/3125 Loss: 0.728770 mae: 0.689083 (92.59697361861907 steps/sec)
Step #23700 Epoch 1 Batch 1824/3125 Loss: 0.701443 mae: 0.686881 (87.97590381662738 steps/sec)
Step #23750 Epoch 1 Batch 1874/3125 Loss: 0.818099 mae: 0.689917 (95.95046990361269 steps/sec)
Step #23800 Epoch 1 Batch 1924/3125 Loss: 0.952441 mae: 0.684022 (87.49854492580687 steps/sec)
Step #23850 Epoch 1 Batch 1974/3125 Loss: 0.757475 mae: 0.680573 (90.24557755565387 steps/sec)
Step #23900 Epoch 1 Batch 2024/3125 Loss: 0.863990 mae: 0.692241 (97.66546623380917 steps/sec)
Step #23950 Epoch 1 Batch 2074/3125 Loss: 0.795743 mae: 0.682051 (97.1957557685231 steps/sec)
Step #24000 Epoch 1 Batch 2124/3125 Loss: 0.638063 mae: 0.685234 (88.90075842069096 steps/sec)
Step #24050 Epoch 1 Batch 2174/3125 Loss: 0.725783 mae: 0.679442 (95.6616023365831 steps/sec)
Step #24100 Epoch 1 Batch 2224/3125 Loss: 0.682556 mae: 0.684956 (90.38552212496175 steps/sec)
Step #24150 Epoch 1 Batch 2274/3125 Loss: 0.759051 mae: 0.685392 (86.45735636112232 steps/sec)
Step #24200 Epoch 1 Batch 2324/3125 Loss: 0.616159 mae: 0.694101 (90.38918408231241 steps/sec)
Step #24250 Epoch 1 Batch 2374/3125 Loss: 0.709371 mae: 0.683894 (99.02656902293784 steps/sec)
Step #24300 Epoch 1 Batch 2424/3125 Loss: 0.721422 mae: 0.684375 (87.43470493447042 steps/sec)
Step #24350 Epoch 1 Batch 2474/3125 Loss: 0.785628 mae: 0.680045 (84.47830672143998 steps/sec)
Step #24400 Epoch 1 Batch 2524/3125 Loss: 0.719284 mae: 0.689088 (83.60163380115495 steps/sec)
Step #24450 Epoch 1 Batch 2574/3125 Loss: 0.821281 mae: 0.693504 (90.1592526051642 steps/sec)
Step #24500 Epoch 1 Batch 2624/3125 Loss: 0.933031 mae: 0.688952 (93.38447659056034 steps/sec)
Step #24550 Epoch 1 Batch 2674/3125 Loss: 0.743384 mae: 0.689125 (87.3659350872742 steps/sec)
Step #24600 Epoch 1 Batch 2724/3125 Loss: 0.726583 mae: 0.679906 (96.08274704350488 steps/sec)
Step #24650 Epoch 1 Batch 2774/3125 Loss: 0.687935 mae: 0.684948 (94.66373562881144 steps/sec)
Step #24700 Epoch 1 Batch 2824/3125 Loss: 0.790933 mae: 0.695512 (101.71669031962044 steps/sec)
Step #24750 Epoch 1 Batch 2874/3125 Loss: 0.799906 mae: 0.676791 (92.94580504423803 steps/sec)
Step #24800 Epoch 1 Batch 2924/3125 Loss: 0.771244 mae: 0.685280 (100.01435485878586 steps/sec)
Step #24850 Epoch 1 Batch 2974/3125 Loss: 0.672207 mae: 0.686887 (102.39780004726461 steps/sec)
Step #24900 Epoch 1 Batch 3024/3125 Loss: 0.702219 mae: 0.677694 (102.82883843215284 steps/sec)
Step #24950 Epoch 1 Batch 3074/3125 Loss: 0.751962 mae: 0.680351 (100.43942054917271 steps/sec)
Step #25000 Epoch 1 Batch 3124/3125 Loss: 0.800776 mae: 0.680315 (98.22224532799028 steps/sec)
Train time for epoch #2 (25000 total steps): 33.96665096282959
Model test set loss: 0.784036 mae: 0.699112
best loss = 0.7840359210968018
Step #25050 Epoch 2 Batch 49/3125 Loss: 0.841394 mae: 0.698265 (90.52476819008047 steps/sec)
Step #25100 Epoch 2 Batch 99/3125 Loss: 0.917930 mae: 0.675593 (94.70960760909671 steps/sec)
Step #25150 Epoch 2 Batch 149/3125 Loss: 0.731097 mae: 0.686770 (95.71019392574121 steps/sec)
Step #25200 Epoch 2 Batch 199/3125 Loss: 0.766869 mae: 0.686221 (93.53821341134608 steps/sec)
Step #25250 Epoch 2 Batch 249/3125 Loss: 0.841341 mae: 0.686227 (89.86593933524594 steps/sec)
Step #25300 Epoch 2 Batch 299/3125 Loss: 0.738986 mae: 0.685498 (87.32911779831642 steps/sec)
Step #25350 Epoch 2 Batch 349/3125 Loss: 0.825709 mae: 0.688310 (87.90694360027665 steps/sec)
Step #25400 Epoch 2 Batch 399/3125 Loss: 0.866955 mae: 0.689053 (90.68918351487874 steps/sec)
Step #25450 Epoch 2 Batch 449/3125 Loss: 0.759929 mae: 0.692852 (88.27745989812416 steps/sec)
Step #25500 Epoch 2 Batch 499/3125 Loss: 0.751120 mae: 0.680172 (85.08168182568728 steps/sec)
Step #25550 Epoch 2 Batch 549/3125 Loss: 0.749131 mae: 0.679911 (86.89378677801966 steps/sec)
Step #25600 Epoch 2 Batch 599/3125 Loss: 0.662256 mae: 0.690591 (88.49661188460912 steps/sec)
Step #25650 Epoch 2 Batch 649/3125 Loss: 0.713749 mae: 0.686868 (91.26206240793404 steps/sec)
Step #25700 Epoch 2 Batch 699/3125 Loss: 0.751382 mae: 0.687611 (84.17108328801321 steps/sec)
Step #25750 Epoch 2 Batch 749/3125 Loss: 0.730248 mae: 0.677658 (86.24945301164387 steps/sec)
Step #25800 Epoch 2 Batch 799/3125 Loss: 0.792215 mae: 0.685663 (89.12756515360535 steps/sec)
Step #25850 Epoch 2 Batch 849/3125 Loss: 0.839750 mae: 0.686164 (93.40710341381113 steps/sec)
Step #25900 Epoch 2 Batch 899/3125 Loss: 0.845688 mae: 0.684292 (94.12170216432808 steps/sec)
Step #25950 Epoch 2 Batch 949/3125 Loss: 0.682219 mae: 0.686044 (91.55478176441261 steps/sec)
Step #26000 Epoch 2 Batch 999/3125 Loss: 0.835548 mae: 0.679832 (94.26893602943028 steps/sec)
Step #26050 Epoch 2 Batch 1049/3125 Loss: 0.825394 mae: 0.691863 (94.50261744715425 steps/sec)
Step #26100 Epoch 2 Batch 1099/3125 Loss: 0.727683 mae: 0.684240 (91.55422219040152 steps/sec)
Step #26150 Epoch 2 Batch 1149/3125 Loss: 0.683049 mae: 0.692138 (95.7884894971446 steps/sec)
Step #26200 Epoch 2 Batch 1199/3125 Loss: 0.796000 mae: 0.680490 (96.30658635117257 steps/sec)
Step #26250 Epoch 2 Batch 1249/3125 Loss: 0.838705 mae: 0.687717 (95.88821625180606 steps/sec)
Step #26300 Epoch 2 Batch 1299/3125 Loss: 0.705656 mae: 0.692004 (94.1591439098221 steps/sec)
Step #26350 Epoch 2 Batch 1349/3125 Loss: 0.779030 mae: 0.671063 (93.87880261051 steps/sec)
Step #26400 Epoch 2 Batch 1399/3125 Loss: 0.785823 mae: 0.688031 (95.40644658809057 steps/sec)
Step #26450 Epoch 2 Batch 1449/3125 Loss: 0.720694 mae: 0.684680 (97.78701228940247 steps/sec)
Step #26500 Epoch 2 Batch 1499/3125 Loss: 0.790368 mae: 0.685548 (98.16642895292519 steps/sec)
Step #26550 Epoch 2 Batch 1549/3125 Loss: 0.831634 mae: 0.684100 (98.15678016674678 steps/sec)
Step #26600 Epoch 2 Batch 1599/3125 Loss: 0.749523 mae: 0.680817 (96.42956002431485 steps/sec)
Step #26650 Epoch 2 Batch 1649/3125 Loss: 0.801523 mae: 0.686970 (97.63850207228171 steps/sec)
Step #26700 Epoch 2 Batch 1699/3125 Loss: 0.794450 mae: 0.680057 (96.53382604825053 steps/sec)
Step #26750 Epoch 2 Batch 1749/3125 Loss: 0.770107 mae: 0.683221 (97.93469438837982 steps/sec)
Step #26800 Epoch 2 Batch 1799/3125 Loss: 0.822275 mae: 0.684085 (97.58307454210937 steps/sec)
Step #26850 Epoch 2 Batch 1849/3125 Loss: 0.747708 mae: 0.684700 (97.58311994874117 steps/sec)
Step #26900 Epoch 2 Batch 1899/3125 Loss: 0.846560 mae: 0.683030 (94.89822145476529 steps/sec)
Step #26950 Epoch 2 Batch 1949/3125 Loss: 0.708278 mae: 0.677219 (98.29447772247063 steps/sec)
Step #27000 Epoch 2 Batch 1999/3125 Loss: 0.830324 mae: 0.685146 (95.49789869759779 steps/sec)
Step #27050 Epoch 2 Batch 2049/3125 Loss: 0.713161 mae: 0.692587 (92.06534980760746 steps/sec)
Step #27100 Epoch 2 Batch 2099/3125 Loss: 0.784691 mae: 0.674547 (97.8175259323592 steps/sec)
Step #27150 Epoch 2 Batch 2149/3125 Loss: 0.721927 mae: 0.674004 (98.35274607977578 steps/sec)
Step #27200 Epoch 2 Batch 2199/3125 Loss: 0.668375 mae: 0.680332 (98.05874588353784 steps/sec)
Step #27250 Epoch 2 Batch 2249/3125 Loss: 0.726950 mae: 0.678826 (96.12066416994112 steps/sec)
Step #27300 Epoch 2 Batch 2299/3125 Loss: 0.793177 mae: 0.692385 (99.10612471155214 steps/sec)
Step #27350 Epoch 2 Batch 2349/3125 Loss: 0.729357 mae: 0.683784 (97.88272194126995 steps/sec)
Step #27400 Epoch 2 Batch 2399/3125 Loss: 0.697055 mae: 0.682630 (97.50073108625237 steps/sec)
Step #27450 Epoch 2 Batch 2449/3125 Loss: 0.719842 mae: 0.675641 (96.70765876521986 steps/sec)
Step #27500 Epoch 2 Batch 2499/3125 Loss: 0.885442 mae: 0.685140 (96.35760646123506 steps/sec)
Step #27550 Epoch 2 Batch 2549/3125 Loss: 0.569982 mae: 0.688982 (96.15085190724339 steps/sec)
Step #27600 Epoch 2 Batch 2599/3125 Loss: 0.883556 mae: 0.683297 (98.5813215802705 steps/sec)
Step #27650 Epoch 2 Batch 2649/3125 Loss: 0.838301 mae: 0.684033 (96.97592979396074 steps/sec)
Step #27700 Epoch 2 Batch 2699/3125 Loss: 0.747114 mae: 0.682756 (98.4129769949943 steps/sec)
Step #27750 Epoch 2 Batch 2749/3125 Loss: 0.826727 mae: 0.678213 (96.69597613437784 steps/sec)
Step #27800 Epoch 2 Batch 2799/3125 Loss: 0.792681 mae: 0.686795 (98.76154371423863 steps/sec)
Step #27850 Epoch 2 Batch 2849/3125 Loss: 0.787148 mae: 0.681075 (95.59837189128376 steps/sec)
Step #27900 Epoch 2 Batch 2899/3125 Loss: 0.817012 mae: 0.678875 (97.75852271800272 steps/sec)
Step #27950 Epoch 2 Batch 2949/3125 Loss: 0.821596 mae: 0.682126 (98.38209078456025 steps/sec)
Step #28000 Epoch 2 Batch 2999/3125 Loss: 0.700930 mae: 0.679892 (99.07686144228825 steps/sec)
Step #28050 Epoch 2 Batch 3049/3125 Loss: 0.721152 mae: 0.673013 (97.36936063563608 steps/sec)
Step #28100 Epoch 2 Batch 3099/3125 Loss: 0.804983 mae: 0.677583 (95.00479519728262 steps/sec)
Train time for epoch #3 (28125 total steps): 33.18755841255188
Model test set loss: 0.779327 mae: 0.696082
best loss = 0.7793265581130981
Step #28150 Epoch 3 Batch 24/3125 Loss: 0.671083 mae: 0.695564 (171.26934296793078 steps/sec)
Step #28200 Epoch 3 Batch 74/3125 Loss: 0.792037 mae: 0.674184 (97.14375446136373 steps/sec)
Step #28250 Epoch 3 Batch 124/3125 Loss: 0.655678 mae: 0.682189 (92.6364035120655 steps/sec)
Step #28300 Epoch 3 Batch 174/3125 Loss: 0.774118 mae: 0.681569 (97.98278487352634 steps/sec)
Step #28350 Epoch 3 Batch 224/3125 Loss: 0.640327 mae: 0.683743 (96.37979250203936 steps/sec)
Step #28400 Epoch 3 Batch 274/3125 Loss: 0.750146 mae: 0.681639 (96.8823424517171 steps/sec)
Step #28450 Epoch 3 Batch 324/3125 Loss: 0.732256 mae: 0.683736 (96.14340236788117 steps/sec)
Step #28500 Epoch 3 Batch 374/3125 Loss: 0.743042 mae: 0.684646 (97.48745120170025 steps/sec)
Step #28550 Epoch 3 Batch 424/3125 Loss: 0.815393 mae: 0.686061 (96.54751409321202 steps/sec)
Step #28600 Epoch 3 Batch 474/3125 Loss: 0.765601 mae: 0.681953 (97.42124177298454 steps/sec)
Step #28650 Epoch 3 Batch 524/3125 Loss: 0.817163 mae: 0.675836 (97.35236541674423 steps/sec)
Step #28700 Epoch 3 Batch 574/3125 Loss: 0.789274 mae: 0.682267 (96.4514686971671 steps/sec)
Step #28750 Epoch 3 Batch 624/3125 Loss: 0.581383 mae: 0.680147 (95.3692642182902 steps/sec)
Step #28800 Epoch 3 Batch 674/3125 Loss: 0.782234 mae: 0.684234 (97.92870354502362 steps/sec)
Step #28850 Epoch 3 Batch 724/3125 Loss: 0.629306 mae: 0.682857 (95.06513098726391 steps/sec)
Step #28900 Epoch 3 Batch 774/3125 Loss: 0.693846 mae: 0.676542 (96.86851456409788 steps/sec)
Step #28950 Epoch 3 Batch 824/3125 Loss: 0.773958 mae: 0.682875 (95.78157719860334 steps/sec)
Step #29000 Epoch 3 Batch 874/3125 Loss: 0.684647 mae: 0.680135 (97.5185490366033 steps/sec)
Step #29050 Epoch 3 Batch 924/3125 Loss: 0.850243 mae: 0.686539 (94.78147606138972 steps/sec)
Step #29100 Epoch 3 Batch 974/3125 Loss: 0.696704 mae: 0.681376 (97.06808066295888 steps/sec)
Step #29150 Epoch 3 Batch 1024/3125 Loss: 0.723475 mae: 0.677778 (94.13716546022421 steps/sec)
Step #29200 Epoch 3 Batch 1074/3125 Loss: 0.757530 mae: 0.681978 (97.67006026509189 steps/sec)
Step #29250 Epoch 3 Batch 1124/3125 Loss: 0.748991 mae: 0.687987 (95.03368307906754 steps/sec)
Step #29300 Epoch 3 Batch 1174/3125 Loss: 0.664798 mae: 0.683524 (96.86860405229694 steps/sec)
Step #29350 Epoch 3 Batch 1224/3125 Loss: 0.742110 mae: 0.675986 (95.62334882711438 steps/sec)
Step #29400 Epoch 3 Batch 1274/3125 Loss: 0.842598 mae: 0.690012 (97.26982418953486 steps/sec)
Step #29450 Epoch 3 Batch 1324/3125 Loss: 0.642632 mae: 0.678084 (94.8816056586419 steps/sec)
Step #29500 Epoch 3 Batch 1374/3125 Loss: 0.706632 mae: 0.676122 (95.79640924256432 steps/sec)
Step #29550 Epoch 3 Batch 1424/3125 Loss: 0.742016 mae: 0.680312 (95.7289801791011 steps/sec)
Step #29600 Epoch 3 Batch 1474/3125 Loss: 0.641970 mae: 0.682409 (98.22155528203514 steps/sec)
Step #29650 Epoch 3 Batch 1524/3125 Loss: 0.659349 mae: 0.675746 (95.23033672405047 steps/sec)
Step #29700 Epoch 3 Batch 1574/3125 Loss: 0.703235 mae: 0.683202 (96.5951413908508 steps/sec)
Step #29750 Epoch 3 Batch 1624/3125 Loss: 0.772652 mae: 0.675448 (95.40458027074376 steps/sec)
Step #29800 Epoch 3 Batch 1674/3125 Loss: 0.632780 mae: 0.681941 (97.03668572248223 steps/sec)
Step #29850 Epoch 3 Batch 1724/3125 Loss: 0.851819 mae: 0.678916 (96.02089321803724 steps/sec)
Step #29900 Epoch 3 Batch 1774/3125 Loss: 0.684029 mae: 0.680845 (98.01236726409218 steps/sec)
Step #29950 Epoch 3 Batch 1824/3125 Loss: 0.680554 mae: 0.679434 (95.80441783048187 steps/sec)
Step #30000 Epoch 3 Batch 1874/3125 Loss: 0.798749 mae: 0.682511 (96.41745686930335 steps/sec)
Step #30050 Epoch 3 Batch 1924/3125 Loss: 0.929966 mae: 0.677670 (97.07050686850191 steps/sec)
Step #30100 Epoch 3 Batch 1974/3125 Loss: 0.737366 mae: 0.674866 (96.14053746779503 steps/sec)
Step #30150 Epoch 3 Batch 2024/3125 Loss: 0.855838 mae: 0.684689 (93.99531357288971 steps/sec)
Step #30200 Epoch 3 Batch 2074/3125 Loss: 0.774386 mae: 0.675527 (96.28850113040109 steps/sec)
Step #30250 Epoch 3 Batch 2124/3125 Loss: 0.626055 mae: 0.677924 (95.61227541634145 steps/sec)
Step #30300 Epoch 3 Batch 2174/3125 Loss: 0.723549 mae: 0.672728 (97.72176152958653 steps/sec)
Step #30350 Epoch 3 Batch 2224/3125 Loss: 0.681627 mae: 0.678353 (95.19955731101851 steps/sec)
Step #30400 Epoch 3 Batch 2274/3125 Loss: 0.736302 mae: 0.677233 (96.37434468357316 steps/sec)
Step #30450 Epoch 3 Batch 2324/3125 Loss: 0.584631 mae: 0.686699 (94.81027113681799 steps/sec)
Step #30500 Epoch 3 Batch 2374/3125 Loss: 0.698571 mae: 0.677499 (95.78105225466504 steps/sec)
Step #30550 Epoch 3 Batch 2424/3125 Loss: 0.706093 mae: 0.677204 (95.26126586096406 steps/sec)
Step #30600 Epoch 3 Batch 2474/3125 Loss: 0.777790 mae: 0.673271 (95.12079737835785 steps/sec)
Step #30650 Epoch 3 Batch 2524/3125 Loss: 0.703747 mae: 0.681530 (95.3811056311252 steps/sec)
Step #30700 Epoch 3 Batch 2574/3125 Loss: 0.807804 mae: 0.685983 (97.28015675025257 steps/sec)
Step #30750 Epoch 3 Batch 2624/3125 Loss: 0.912028 mae: 0.681242 (92.45042886924612 steps/sec)
Step #30800 Epoch 3 Batch 2674/3125 Loss: 0.733961 mae: 0.680752 (95.10548370127161 steps/sec)
Step #30850 Epoch 3 Batch 2724/3125 Loss: 0.720733 mae: 0.672703 (94.2092254559405 steps/sec)
Step #30900 Epoch 3 Batch 2774/3125 Loss: 0.668025 mae: 0.678066 (96.03896600503653 steps/sec)
Step #30950 Epoch 3 Batch 2824/3125 Loss: 0.771790 mae: 0.687630 (94.54270703442332 steps/sec)
Step #31000 Epoch 3 Batch 2874/3125 Loss: 0.795335 mae: 0.669771 (95.89514395117887 steps/sec)
Step #31050 Epoch 3 Batch 2924/3125 Loss: 0.768766 mae: 0.678650 (95.54924074157603 steps/sec)
Step #31100 Epoch 3 Batch 2974/3125 Loss: 0.657581 mae: 0.679598 (86.63522356836064 steps/sec)
Step #31150 Epoch 3 Batch 3024/3125 Loss: 0.710757 mae: 0.669819 (81.81546157234253 steps/sec)
Step #31200 Epoch 3 Batch 3074/3125 Loss: 0.752866 mae: 0.671728 (85.46792026832618 steps/sec)
Step #31250 Epoch 3 Batch 3124/3125 Loss: 0.789243 mae: 0.671955 (84.97295203488784 steps/sec)
Train time for epoch #4 (31250 total steps): 32.9474937915802
Model test set loss: 0.774264 mae: 0.693687
best loss = 0.7742644548416138
Step #31300 Epoch 4 Batch 49/3125 Loss: 0.849005 mae: 0.692671 (86.63508040945638 steps/sec)
Step #31350 Epoch 4 Batch 99/3125 Loss: 0.887145 mae: 0.667644 (93.65070150321479 steps/sec)
Step #31400 Epoch 4 Batch 149/3125 Loss: 0.715392 mae: 0.678084 (88.70357093762226 steps/sec)
Step #31450 Epoch 4 Batch 199/3125 Loss: 0.755828 mae: 0.678409 (93.64146002219191 steps/sec)
Step #31500 Epoch 4 Batch 249/3125 Loss: 0.835472 mae: 0.677886 (94.04458834371097 steps/sec)
Step #31550 Epoch 4 Batch 299/3125 Loss: 0.707785 mae: 0.678733 (94.06112318871456 steps/sec)
Step #31600 Epoch 4 Batch 349/3125 Loss: 0.784751 mae: 0.680859 (93.25856586992774 steps/sec)
Step #31650 Epoch 4 Batch 399/3125 Loss: 0.846286 mae: 0.681717 (97.06237506496969 steps/sec)
Step #31700 Epoch 4 Batch 449/3125 Loss: 0.738571 mae: 0.684823 (95.92308413587432 steps/sec)
Step #31750 Epoch 4 Batch 499/3125 Loss: 0.726846 mae: 0.673212 (92.13661943304719 steps/sec)
Step #31800 Epoch 4 Batch 549/3125 Loss: 0.719152 mae: 0.671284 (94.35966288550462 steps/sec)
Step #31850 Epoch 4 Batch 599/3125 Loss: 0.642589 mae: 0.682743 (94.95674506256186 steps/sec)
Step #31900 Epoch 4 Batch 649/3125 Loss: 0.702127 mae: 0.679642 (91.53791760875069 steps/sec)
Step #31950 Epoch 4 Batch 699/3125 Loss: 0.724501 mae: 0.679958 (94.65625839240458 steps/sec)
Step #32000 Epoch 4 Batch 749/3125 Loss: 0.717045 mae: 0.669120 (93.81786427502881 steps/sec)
Step #32050 Epoch 4 Batch 799/3125 Loss: 0.745565 mae: 0.679389 (91.53775778865695 steps/sec)
Step #32100 Epoch 4 Batch 849/3125 Loss: 0.828537 mae: 0.678774 (89.95494428945463 steps/sec)
Step #32150 Epoch 4 Batch 899/3125 Loss: 0.828524 mae: 0.676391 (85.42294122007868 steps/sec)
Step #32200 Epoch 4 Batch 949/3125 Loss: 0.674728 mae: 0.677796 (82.50033831735112 steps/sec)
Step #32250 Epoch 4 Batch 999/3125 Loss: 0.814002 mae: 0.672747 (87.36775492808826 steps/sec)
Step #32300 Epoch 4 Batch 1049/3125 Loss: 0.822413 mae: 0.683690 (92.12876708838405 steps/sec)
Step #32350 Epoch 4 Batch 1099/3125 Loss: 0.714512 mae: 0.676341 (92.99031543026298 steps/sec)
Step #32400 Epoch 4 Batch 1149/3125 Loss: 0.665886 mae: 0.684505 (92.53727918640166 steps/sec)
Step #32450 Epoch 4 Batch 1199/3125 Loss: 0.769309 mae: 0.671976 (91.53392227382241 steps/sec)
Step #32500 Epoch 4 Batch 1249/3125 Loss: 0.829105 mae: 0.680787 (91.2518171806407 steps/sec)
Step #32550 Epoch 4 Batch 1299/3125 Loss: 0.703187 mae: 0.684143 (89.1962161769028 steps/sec)
Step #32600 Epoch 4 Batch 1349/3125 Loss: 0.762131 mae: 0.663012 (90.23563692190127 steps/sec)
Step #32650 Epoch 4 Batch 1399/3125 Loss: 0.782941 mae: 0.680012 (92.17347046860901 steps/sec)
Step #32700 Epoch 4 Batch 1449/3125 Loss: 0.717813 mae: 0.676620 (90.84884445786405 steps/sec)
Step #32750 Epoch 4 Batch 1499/3125 Loss: 0.771077 mae: 0.677188 (91.24991134562761 steps/sec)
Step #32800 Epoch 4 Batch 1549/3125 Loss: 0.822044 mae: 0.674737 (90.50785164520731 steps/sec)
Step #32850 Epoch 4 Batch 1599/3125 Loss: 0.730982 mae: 0.672091 (86.22594164279556 steps/sec)
Step #32900 Epoch 4 Batch 1649/3125 Loss: 0.787307 mae: 0.678850 (89.30420163486811 steps/sec)
Step #32950 Epoch 4 Batch 1699/3125 Loss: 0.769659 mae: 0.672791 (80.95036639255419 steps/sec)
Step #33000 Epoch 4 Batch 1749/3125 Loss: 0.754821 mae: 0.674748 (83.31689231843737 steps/sec)
Step #33050 Epoch 4 Batch 1799/3125 Loss: 0.808317 mae: 0.675786 (81.94253419690415 steps/sec)
Step #33100 Epoch 4 Batch 1849/3125 Loss: 0.736969 mae: 0.676992 (88.07533023755097 steps/sec)
Step #33150 Epoch 4 Batch 1899/3125 Loss: 0.830447 mae: 0.676006 (90.29686872983861 steps/sec)
Step #33200 Epoch 4 Batch 1949/3125 Loss: 0.698865 mae: 0.670767 (90.06763816993418 steps/sec)
Step #33250 Epoch 4 Batch 1999/3125 Loss: 0.810068 mae: 0.675959 (89.52894623486988 steps/sec)
Step #33300 Epoch 4 Batch 2049/3125 Loss: 0.690710 mae: 0.684732 (91.52852912486824 steps/sec)
Step #33350 Epoch 4 Batch 2099/3125 Loss: 0.761189 mae: 0.667424 (89.95930462250931 steps/sec)
Step #33400 Epoch 4 Batch 2149/3125 Loss: 0.703904 mae: 0.666731 (92.74853656336074 steps/sec)
Step #33450 Epoch 4 Batch 2199/3125 Loss: 0.654756 mae: 0.673259 (90.60009029111323 steps/sec)
Step #33500 Epoch 4 Batch 2249/3125 Loss: 0.700377 mae: 0.670951 (88.25873548749843 steps/sec)
Step #33550 Epoch 4 Batch 2299/3125 Loss: 0.786276 mae: 0.683020 (90.4601443461547 steps/sec)
Step #33600 Epoch 4 Batch 2349/3125 Loss: 0.714943 mae: 0.675117 (93.2993914847008 steps/sec)
Step #33650 Epoch 4 Batch 2399/3125 Loss: 0.673051 mae: 0.675196 (91.91455940309393 steps/sec)
Step #33700 Epoch 4 Batch 2449/3125 Loss: 0.709089 mae: 0.667099 (92.24308183044161 steps/sec)
Step #33750 Epoch 4 Batch 2499/3125 Loss: 0.864663 mae: 0.676928 (92.42276405565941 steps/sec)
Step #33800 Epoch 4 Batch 2549/3125 Loss: 0.557530 mae: 0.679273 (92.74340948178455 steps/sec)
Step #33850 Epoch 4 Batch 2599/3125 Loss: 0.870227 mae: 0.675846 (90.21265759185366 steps/sec)
Step #33900 Epoch 4 Batch 2649/3125 Loss: 0.823046 mae: 0.675030 (93.99535570203884 steps/sec)
Step #33950 Epoch 4 Batch 2699/3125 Loss: 0.734765 mae: 0.674813 (88.93148319499136 steps/sec)
Step #34000 Epoch 4 Batch 2749/3125 Loss: 0.804615 mae: 0.669130 (95.49102827322206 steps/sec)
Step #34050 Epoch 4 Batch 2799/3125 Loss: 0.764164 mae: 0.678259 (90.9379151966753 steps/sec)
Step #34100 Epoch 4 Batch 2849/3125 Loss: 0.777574 mae: 0.673345 (90.35281141887147 steps/sec)
Step #34150 Epoch 4 Batch 2899/3125 Loss: 0.807234 mae: 0.671131 (94.95287563659545 steps/sec)
Step #34200 Epoch 4 Batch 2949/3125 Loss: 0.789137 mae: 0.675352 (96.48173144782037 steps/sec)
Step #34250 Epoch 4 Batch 2999/3125 Loss: 0.685636 mae: 0.670751 (97.09055016768549 steps/sec)
Step #34300 Epoch 4 Batch 3049/3125 Loss: 0.707665 mae: 0.663872 (97.26644064023301 steps/sec)
Step #34350 Epoch 4 Batch 3099/3125 Loss: 0.765113 mae: 0.668804 (95.97462096891188 steps/sec)
Train time for epoch #5 (34375 total steps): 34.385642290115356
Model test set loss: 0.769376 mae: 0.690253
best loss = 0.769376277923584
INFO:tensorflow:Assets written to: ./models/export/assets
将用户特征和电影特征做矩阵乘法得到一个预测评分的训练
显示训练Loss
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
plt.plot(mv_net.losses['train'], label='Training loss')
plt.legend()
_ = plt.ylim()
显示测试Loss
迭代次数再增加一些,下降的趋势会明显一些
plt.plot(mv_net.losses['test'], label='Test loss')
plt.legend()
_ = plt.ylim()
## 指定用户和电影进行评分
这部分就是对网络做正向传播,计算得到预测的评分
def rating_movie(mv_net, user_id_val, movie_id_val):
categories = np.zeros([1, 18])
categories[0] = movies.values[movieid2idx[movie_id_val]][2]
titles = np.zeros([1, sentences_size])
titles[0] = movies.values[movieid2idx[movie_id_val]][1]
inference_val = mv_net.model([np.reshape(users.values[user_id_val-1][0], [1, 1]),
np.reshape(users.values[user_id_val-1][1], [1, 1]),
np.reshape(users.values[user_id_val-1][2], [1, 1]),
np.reshape(users.values[user_id_val-1][3], [1, 1]),
np.reshape(movies.values[movieid2idx[movie_id_val]][0], [1, 1]),
categories,
titles])
return (inference_val.numpy())
rating_movie(mv_net, 234, 1401)
array([[4.4249763]], dtype=float32)
生成Movie特征矩阵
将训练好的电影特征组合成电影特征矩阵并保存到本地
movie_layer_model = keras.models.Model(inputs=[mv_net.model.input[4], mv_net.model.input[5], mv_net.model.input[6]],
outputs=mv_net.model.get_layer("movie_combine_layer_flat").output)
movie_matrics = []
for item in movies.values:
categories = np.zeros([1, 18])
categories[0] = item.take(2)
titles = np.zeros([1, sentences_size])
titles[0] = item.take(1)
movie_combine_layer_flat_val = movie_layer_model([np.reshape(item.take(0), [1, 1]), categories, titles])
movie_matrics.append(movie_combine_layer_flat_val)
pickle.dump((np.array(movie_matrics).reshape(-1, 200)), open('movie_matrics.p', 'wb'))
movie_matrics = pickle.load(open('movie_matrics.p', mode='rb'))
movie_matrics = pickle.load(open('movie_matrics.p', mode='rb'))
生成User特征矩阵
将训练好的用户特征组合成用户特征矩阵并保存到本地
user_layer_model = keras.models.Model(inputs=[mv_net.model.input[0], mv_net.model.input[1], mv_net.model.input[2], mv_net.model.input[3]],
outputs=mv_net.model.get_layer("user_combine_layer_flat").output)
users_matrics = []
for item in users.values:
user_combine_layer_flat_val = user_layer_model([np.reshape(item.take(0), [1, 1]),
np.reshape(item.take(1), [1, 1]),
np.reshape(item.take(2), [1, 1]),
np.reshape(item.take(3), [1, 1])])
users_matrics.append(user_combine_layer_flat_val)
pickle.dump((np.array(users_matrics).reshape(-1, 200)), open('users_matrics.p', 'wb'))
users_matrics = pickle.load(open('users_matrics.p', mode='rb'))
users_matrics = pickle.load(open('users_matrics.p', mode='rb'))
开始推荐电影
使用生产的用户特征矩阵和电影特征矩阵做电影推荐
推荐同类型的电影
思路是计算当前看的电影特征向量与整个电影特征矩阵的余弦相似度,取相似度最大的top_k个,这里加了些随机选择在里面,保证每次的推荐稍稍有些不同。
def recommend_same_type_movie(movie_id_val, top_k = 20):
norm_movie_matrics = tf.sqrt(tf.reduce_sum(tf.square(movie_matrics), 1, keepdims=True))
normalized_movie_matrics = movie_matrics / norm_movie_matrics
#推荐同类型的电影
probs_embeddings = (movie_matrics[movieid2idx[movie_id_val]]).reshape([1, 200])
probs_similarity = tf.matmul(probs_embeddings, tf.transpose(normalized_movie_matrics))
sim = (probs_similarity.numpy())
# results = (-sim[0]).argsort()[0:top_k]
# print(results)
print("您看的电影是:{}".format(movies_orig[movieid2idx[movie_id_val]]))
print("以下是给您的推荐:")
p = np.squeeze(sim)
p[np.argsort(p)[:-top_k]] = 0
p = p / np.sum(p)
results = set()
while len(results) != 5:
c = np.random.choice(3883, 1, p=p)[0]
results.add(c)
for val in (results):
print(val)
print(movies_orig[val])
return results
recommend_same_type_movie(1401, 20)
您看的电影是:[1401 'Ghosts of Mississippi (1996)' 'Drama']
以下是给您的推荐:
3040
[3109 'River, The (1984)' 'Drama']
1383
[1406 'C�r�monie, La (1995)' 'Drama']
1611
[1657 'Wonderland (1997)' 'Documentary']
2482
[2551 'Dead Ringers (1988)' 'Drama|Thriller']
3572
[3641 'Woman of Paris, A (1923)' 'Drama']
{1383, 1611, 2482, 3040, 3572}
推荐您喜欢的电影
思路是使用用户特征向量与电影特征矩阵计算所有电影的评分,取评分最高的top_k个,同样加了些随机选择部分。
def recommend_your_favorite_movie(user_id_val, top_k = 10):
#推荐您喜欢的电影
probs_embeddings = (users_matrics[user_id_val-1]).reshape([1, 200])
probs_similarity = tf.matmul(probs_embeddings, tf.transpose(movie_matrics))
sim = (probs_similarity.numpy())
# print(sim.shape)
# results = (-sim[0]).argsort()[0:top_k]
# print(results)
# sim_norm = probs_norm_similarity.eval()
# print((-sim_norm[0]).argsort()[0:top_k])
print("以下是给您的推荐:")
p = np.squeeze(sim)
p[np.argsort(p)[:-top_k]] = 0
p = p / np.sum(p)
results = set()
while len(results) != 5:
c = np.random.choice(3883, 1, p=p)[0]
results.add(c)
for val in (results):
print(val)
print(movies_orig[val])
return results
recommend_your_favorite_movie(234, 10)
以下是给您的推荐:
2434
[2503 'Apple, The (Sib) (1998)' 'Drama']
3366
[3435 'Double Indemnity (1944)' 'Crime|Film-Noir']
1194
[1212 'Third Man, The (1949)' 'Mystery|Thriller']
589
[593 'Silence of the Lambs, The (1991)' 'Drama|Thriller']
942
[954 'Mr. Smith Goes to Washington (1939)' 'Drama']
{589, 942, 1194, 2434, 3366}
看过这个电影的人还看了(喜欢)哪些电影
- 首先选出喜欢某个电影的top_k个人,得到这几个人的用户特征向量。
- 然后计算这几个人对所有电影的评分
- 选择每个人评分最高的电影作为推荐
- 同样加入了随机选择
import random
def recommend_other_favorite_movie(movie_id_val, top_k = 20):
probs_movie_embeddings = (movie_matrics[movieid2idx[movie_id_val]]).reshape([1, 200])
probs_user_favorite_similarity = tf.matmul(probs_movie_embeddings, tf.transpose(users_matrics))
favorite_user_id = np.argsort(probs_user_favorite_similarity.numpy())[0][-top_k:]
# print(normalized_users_matrics.numpy().shape)
# print(probs_user_favorite_similarity.numpy()[0][favorite_user_id])
# print(favorite_user_id.shape)
print("您看的电影是:{}".format(movies_orig[movieid2idx[movie_id_val]]))
print("喜欢看这个电影的人是:{}".format(users_orig[favorite_user_id-1]))
probs_users_embeddings = (users_matrics[favorite_user_id-1]).reshape([-1, 200])
probs_similarity = tf.matmul(probs_users_embeddings, tf.transpose(movie_matrics))
sim = (probs_similarity.numpy())
# results = (-sim[0]).argsort()[0:top_k]
# print(results)
# print(sim.shape)
# print(np.argmax(sim, 1))
p = np.argmax(sim, 1)
print("喜欢看这个电影的人还喜欢看:")
if len(set(p)) < 5:
results = set(p)
else:
results = set()
while len(results) != 5:
c = p[random.randrange(top_k)]
results.add(c)
for val in (results):
print(val)
print(movies_orig[val])
return results
recommend_other_favorite_movie(1401, 20)
您看的电影是:[1401 'Ghosts of Mississippi (1996)' 'Drama']
喜欢看这个电影的人是:[[209 'M' 35 1]
[1110 'F' 56 6]
[2921 'M' 50 1]
[287 'M' 50 13]
[74 'M' 35 14]
[64 'M' 18 1]
[5728 'F' 35 20]
[4253 'M' 45 11]
[5099 'M' 18 0]
[978 'M' 18 0]
[5996 'F' 25 0]
[4504 'F' 25 0]
[2338 'M' 45 17]
[277 'F' 35 1]
[4506 'M' 50 16]
[1636 'F' 25 19]
[2496 'M' 50 1]
[1985 'M' 45 12]
[1855 'M' 18 4]
[2154 'M' 25 12]]
喜欢看这个电影的人还喜欢看:
2434
[2503 'Apple, The (Sib) (1998)' 'Drama']
589
[593 'Silence of the Lambs, The (1991)' 'Drama|Thriller']
{589, 2434}
这个结果里面20个人最喜欢这两个电影,所以只输出了两个结果
最后
以上就是简单黑裤为你收集整理的个性化推荐系统——3. 模型搭建与训练模型搭建的全部内容,希望文章能够帮你解决个性化推荐系统——3. 模型搭建与训练模型搭建所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复