Welcome back to the second part of our recommender engine tutorial series. In the first part, you learned how to train a recommender model using a variant of collaborative filtering and neural network embeddings.

欢迎回到我们的推荐器引擎教程系列的第二部分。 在第一部分中 ,您学习了如何使用协作过滤和神经网络嵌入的变体来训练推荐模型。

In this part, you’re going to create a simple book web application that displays a set of books and also recommends new books to any selected user. Below is the end-goal of this tutorial:

在这一部分中,您将创建一个简单的书本网络应用程序,该应用程序将显示一组书本,并向任何选定的用户推荐新书本。 以下是本教程的最终目标:

Book Recommender Web app
Book Recommender Web应用程序

Link to Source Code

链接到源代码

目录 (Table of Contents)

  • Introducing the App Architecture
    介绍应用架构
  • Initializing the App and Creating Code Directories
    初始化应用程序并创建代码目录
  • Converting the Saved Model to JavaScript Format
    将保存的模型转换为JavaScript格式
  • Creating the Entry Point and Routes
    创建入口点和路线
  • Loading the Saved Model and Making Recommendations
    加载保存的模型并提出建议
  • Creating the UI and Displaying Recommendations
    创建用户界面并显示建议
  • Testing the Application
    测试应用
  • Conclusion
    结论

介绍应用架构 (Introducing the App Architecture)

Our web app is going to be pretty simple. We’ll create a basic Node app project using express-generator. If you don’t have Node.js installed on your system, you should first install it before moving to the next step.

我们的网络应用将非常简单。 我们将使用express-generator创建一个基本的Node应用程序项目。 如果您的系统上未安装Node.js,则应先安装它,然后再进行下一步。

Book App Architecture
图书应用架构

Our app architecture will be comprised of three main parts:

我们的应用程序架构将由三个主要部分组成:

  • app.js: This will be the main entry point of our application. It will contain code to initialize the app, create routes that will map to the UI, call the model to make recommendations, and also start the server.

    app.js:这将是我们应用程序的主要入口点。 它将包含用于初始化应用程序,创建将映射到UI的路由,调用模型以提出建议以及启动服务器的代码。

  • model.js: The model.js file, as the name suggests, will handle model loading and making recommendations. We’ll be using TensorFlow.js for loading our model, so this file will import the library and also process the input data from app.js to the format accepted by the model.

    model.js:顾名思义,model.js文件将处理模型加载并提出建议。 我们将使用TensorFlow.js加载我们的模型,因此该文件将导入库,并将app.js中的输入数据处理为模型接受的格式。

  • UI: The UI will contain HTML and CSS code for the app frontend. It will display the available books on a page by page basis (12 books per page), as well as contain buttons for going to the next or previous page. It will also contain an interface for inputting user IDs when making recommendations.

    UI :UI将包含应用程序前端HTML和CSS代码。 它将逐页显示可用的书籍(每页12本书),并包含用于转到下一页或上一页的按钮。 它还将包含一个在提出建议时用于输入用户ID的界面。

Note that in a production app, you will be making a recommendation based on the logged-in user, and not explicitly asking the user to supply their ID.

请注意 ,在正式版应用中,您将根据已登录的用户提出建议,而不是明确要求用户提供其ID。

初始化应用程序并创建代码目录 (Initializing the App and Creating Code Directories)

To easily create our directories and server, we will use the express-generator library, which will allow us to quickly create an application skeleton.

为了轻松创建目录和服务器,我们将使用express-generator库,该库将使我们能够快速创建应用程序框架。

In your preferred app folder, open a terminal/command prompt to install the library:

在首选的应用程序文件夹中,打开终端/命令提示符以安装库:

npm install -g express-generator

Once installed, you can use it by running the command below:

安装后,可以通过运行以下命令来使用它:

express --view=handlebars book-app
Directory created by express
快递创建的目录

Next, open the created folder in your code editor. I use VScode, so I can simply type code . in the terminal to open the directory.

接下来,在代码编辑器中打开创建的文件夹。 我使用VScode,所以我只需键入code . 在终端中打开目录。

There are lots of files and folders created by express by default—we won’t be using most of them. So we can get rid of the public folder, as our UI will be served from the views folder. You can also get rid of the routes folder, as our application is relatively simple, and we really don’t need routes.

默认情况下,express创建了许多文件和文件夹-我们不会使用其中的大多数。 因此,我们可以摆脱公共文件夹的,因为我们的用户界面将提供从views文件夹。 您还可以摆脱路由文件夹,因为我们的应用程序相对简单,并且我们确实不需要路由。

When you’re done removing these files, you should be left with a directory structure similar to the one below:

删除完这些文件后,应该使用类似于以下内容的目录结构:

Next, create the following files/scripts:

接下来,创建以下文件/脚本:

  • In the home folder, create a script model.js.

    在主文件夹中,创建脚本model.js。

  • In the views folder, create another folder called layouts, and inside the layouts folder, create a file called layouts.hbs.

    在里面 views文件夹,创建另一个名为layouts的文件夹, 在layouts文件夹中,创建一个名为layouts.hbs的文件。

  • In the views folder again, create the main UI page index.hbs. Note the extension is .hbs and not .html. This is because we’re using a view engine called handlebars. This helps us render objects sent from the backend in the frontend.

    再次在views文件夹中,创建主UI页面index.hbs。 请注意,扩展名是.hbs而不是.html 。 这是因为我们使用的是称为handlebars的视图引擎。 这有助于我们在前端渲染从后端发送的对象。

  • In the home folder, create a new folder called model. This will hold our converted model.

    在主文件夹中,创建一个名为model的新文件夹 这将保留我们的转换模型。

  • And finally, in the home folder as well, create another folder called data. Remember the book data we exported and saved in the first part of this tutorial? We’ll copy it here. This will help us load and display books to the user before and after a recommendation.

    最后,同样在主文件夹中,创建另一个名为data的文件夹 还记得我们在本教程的第一部分中导出并保存的图书数据吗? 我们将在这里复制。 这将有助于我们在推荐前后向用户加载和显示图书。

Now before you move to the next section, copy the book data file (web_book_data.json) you saved in the previous tutorial in the data folder.

现在你之前移动到下一个部分,复制图书数据文件( web_book_data.json )保存在数据文件夹前面的教程。

When you’re done creating these files and folders, you should have a directory structure similar to the one below:

创建完这些文件和文件夹后,您应该具有类似于以下内容的目录结构:

将保存的模型转换为JavaScript格式 (Converting the Saved Model to JavaScript Format)

Converting the saved model into JavaScript format is pretty straight forward. We just need to install and work with the TensorFlow.js converter.

将保存的模型转换为JavaScript格式非常简单。 我们只需要安装和使用TensorFlow.js转换器即可 。

To install it, I’d advise creating a new Python environment. I wrote about how to convert any TensorFlow model to Javascript format here. You can read it for better understanding before proceeding.

要安装它,我建议创建一个新的Python环境。 我在此处撰写了有关如何将任何TensorFlow模型转换为Javascript格式的文章。 在继续之前,您可以阅读它以更好地理解。

In a new terminal, run the command:

在新的终端中,运行以下命令:

pip install tensorflowjs

After successful installation, still in your terminal, navigate to where you have your saved Keras model and run the command below:

成功安装后,仍在终端中,导航到保存了Keras模型的位置,然后运行以下命令:

tensorflowjs_wizard

The tensorflowjs_wizard starts a simple interactive prompt that helps you find and convert your model.

tensorflowjs_wizard 启动一个简单的交互式提示,以帮助您查找和转换模型。

The first command asks for the Keras model folder. If you used the same name as I did in the first tutorial, then your model folder name is model. You can specify this in the prompt:

第一个命令要求输入Keras模型文件夹。 如果您使用的名称与我在第一个教程中使用的名称相同,则您的模型文件夹名称为model。 您可以在提示中指定:

On clicking enter, the next command asks you what type of model you’re converting. The model name with a * is the auto-detected one. You can click enter to proceed, as it already chose the right one.

单击回车后,下一个命令将询问您要转换的模型类型。 带*的型号名称是自动检测到的。 您可以单击Enter继续,因为它已经选择了正确的一个。

In the next prompt, click Enter to choose No compression. And finally, it asks for a folder name to save the converted model to. You can type in converted-model/ and click enter to start the conversion.

在下一个提示中,单击Enter以选择“ 无压缩”。 最后,它要求一个文件夹名称来保存转换后的模型。 您可以输入converted-model / ,然后单击Enter开始转换

When it’s done converting, navigate to the folder you specified (converted-model). You will find the model files below:

转换完成后,导航到您指定的文件夹( conversion-model )。 您将在下面找到模型文件:

Now that you’ve converted the model, copy these two files (group1-shared1of1.bin, model.json), and paste them into the model folder of your application. Your app directory should look like the one below:

现在,您已经转换了模型,请复制这两个文件( group1-shared1of1.bin,model.json ),然后将它们粘贴到应用程序的model文件夹中。 您的应用程序目录应类似于以下目录:

Next, we’ll create our routes.

接下来,我们将创建路线。

Machine learning is rapidly moving closer to where data is collected — edge devices. Subscribe to the Fritz AI Newsletter to learn more about this transition and how it can help scale your business.

机器学习正Swift向收集数据的地方(边缘设备)靠近。 订阅Fritz AI新闻通讯以了解有关此过渡及其如何帮助您扩展业务的更多信息 。

创建入口点和路线 (Creating the Entry Point and Routes)

As aforementioned, the app.js file is the entry point of our application. If you open the file in your code editor, you’ll find some default code. This code was generated by express-generator. We’ll remove some the less useful code for our purposes, and also add some of our own.

如前所述,app.js文件是我们应用程序的入口。 如果您在代码编辑器中打开文件,则会找到一些默认代码。 这段代码是由express-generator生成的。 为了我们的目的,我们将删除一些不太有用的代码,并添加一些我们自己的代码。

Remove all existing code in the app.js file and paste the code below:

删除app.js文件中的所有现有代码,然后粘贴以下代码:

In the first five lines (1–5), we import some important libraries we’ll be using.

在前五行(1-5)中,我们导入了一些将要使用的重要库。

  • express handles all low-level app routing and server creation

    express处理所有低级应用程序路由和服务器创建

  • body_parser ensures we can easily parse and read form data from the frontend

    body_parser确保我们可以轻松地从前端解析和读取表单数据

  • express-handlebars is a variant of handlebars and is used for rendering views

    express-handlebarsexpress-handlebars的一种变体,用于呈现视图

We also load the book data, which is in JSON format, using the Node.js require function. Note that in a production application, you’ll be reading a file like this from a database. And finally, we require the model module. This gives us access to the model functions.

我们还使用Node.js require函数加载JSON格式的图书数据。 请注意,在生产应用程序中,您将从数据库中读取这样的文件。 最后,我们需要model模块。 这使我们可以访问模型功能。

All other functions before app.get are configuration settings, and if you’re familiar with express, and you should already be aware of them.

app.get之前的所有其他功能都是配置设置,如果您熟悉express,则应该已经意识到它们。

  • In line 20, we create our first route. This route renders the first UI page (index) of our application.
    在第20行中,我们创建了第一条路线。 此路由呈现我们应用程序的第一个UI页面(索引)。

Navigate to the index.hbs file and add a simple Hello World before we test our application.

导航到index.hbs文件,然后添加一个简单的Hello World。 测试我们的应用程序。

Also, we’ll have to install some of the modules we’ll need for our application. To install these and other modules we’ll be using, open your package.json file and add the following modules to your dependencies:

另外,我们必须安装应用程序所需的一些模块。 要安装我们将要使用的这些模块和其他模块,请打开package.json文件,并将以下模块添加到您的依赖项中:

"dependencies": {    "@tensorflow/tfjs-node": "1.7.4",    "cookie-parser": "~1.4.4",    "express": "~4.16.1",    "express-handlebars": "^3.0.0",    "handlebars": "^4.7.6  }

With your terminal opened in your app directory, run the command:

在应用程序目录中打开终端的情况下,运行以下命令:

npm install

This installs all the modules specified in the dependencies section of package.json

这将安装package.jsondependencies部分中指定的所有模块

Installation might take some time, especially the TensorFlow.js package. Once the installation is done, before you start the app, navigate to the layouts folder and in the layouts.hbs file, add the text below:

安装可能需要一些时间,尤其是TensorFlow.js软件包。 安装完成后,在启动应用程序之前,导航到layouts文件夹,然后在layouts.hbs文件中添加以下文本:

{{{body}}}

The layout.hbs file is the base of our application, and every other file inherits from it. If we had sections like headers and footers that are the same for all pages across our application, we can easily add them in the layouts.hbs file, and they will appear in all files.

layout.hbs文件是我们应用程序的基础,其他所有文件都继承自该文件。 如果我们的页眉和页脚之类的部分与应用程序中所有页面的内容相同,则可以轻松地将它们添加到layouts.hbs文件中,它们将出现在所有文件中。

The command {{{body}}} instructs express to render any page in the specified position. You can read more about layouts here.

命令{{{body}}}指示express渲染指定位置的任何页面。 您可以在此处阅读有关布局的更多信息。

Now, you can start your app to test it. In your terminal, run the following command:

现在,您可以启动您的应用进行测试。 在您的终端中,运行以下命令:

npm start

This starts a server on port 3000—you can open your browser and point it to the address below:

这将在端口3000上启动服务器-您可以打开浏览器并将其指向下面的地址:

localhost:3000

This should render the text “Hello World” in the browser.

这应该在浏览器中显示文本“ Hello World ”。

Next, we’re going to add more functionality to the code. Change the home route code to:

接下来,我们将向代码添加更多功能。 将原路线代码更改为:

app.get("/", (req, res) => {    res.render("index", { books: books.slice(0, 12), pg_start: 0, pg_end: 12 })});

What we’re basically doing here is passing a slice (12) of the books we loaded to the index route. We’re passing two additional variables, pg_start and pg_end. These variables are initialized to 0 and 12, respectively. They’ll be used to keep track of the user’s current page.

我们在这里基本上要做的是传递加载到索引路径的一小部分书籍(12)。 我们将传递两个附加变量pg_startpg_end 。 这些变量分别初始化为0和12。 它们将用于跟踪用户的当前页面。

Next, we’ll create another two routes: get-next and get-prev. These routes will control the page viewed by a user. Specifically, when the user clicks a next or prev button, it will call one of these routes with the specific page start and end numbers, and we’ll make another slice of the book data and return it back to the user.

接下来,我们将创建另外两个路由: get-nextget-prev 。 这些路由将控制用户查看的页面。 具体来说,当用户单击“下一个”或“上一个”按钮时,它将使用特定的页面开始和结束编号调用这些路由之一,我们将制作另一部分图书数据并将其返回给用户。

Copy and paste the code below under the home route:

将以下代码复制并粘贴到家庭路线下:

In the get-next route, first, we get the pg_start and pg_end numbers from the query object. These numbers will be sent from a form object in the UI. Notice that the new pg_start becomes the old pg_end, while we add 12 to the old pg_start ,and that becomes the new pg_end. So basically, we’re shifting our book slice by 12.

get-next路由中,首先,我们从查询对象获取pg_startpg_end编号。 这些数字将从UI中的表单对象发送。 注意,新的pg_start变成了旧的pg_end ,而我们在旧的pg_start加了12,这又变成了新的pg_end 。 因此,基本上,我们将书本的页数偏移了12。

In the get-prev route, we do the opposite. That is, the old pg_start becomes the new pg_end, while we subtract 12 from the old pg_end and assign it to pg_start. Then, we do a few test checks—that is, we confirm whether or not the user is on the first page when clicking prev. This ensures that we do not try to slice negatively from the books.

get-prev路线中,我们做相反的事情。 也就是说,旧的pg_start变为新的pg_end ,而我们从旧的pg_end减去12并将其分配给pg_start 。 然后,我们进行了一些测试检查-即,在单击prev时,确认用户是否在首页上。 这样可以确保我们不会试图从书本中消极地对待。

Next, we will create a recommend route. This route will accept a user ID and call the model from the model module (which we've yet to write) to make a recommendation.

接下来,我们将创建一条recommend路线。 该路由将接受用户ID,并从模型模块(我们尚未编写)中调用model以提出建议。

Copy and paste the code below, just under your get-prev route:

复制并粘贴下面的代码,就在您的get-prev路由下:

In the recommend route, we first get the userId from the request object, then we perform a basic test to ensure the ID is not above 53424 (the number of unique users in the dataset), and not less than zero.

recommend路线中,我们首先从请求对象获取userId ,然后执行基本测试以确保ID不大于53424(数据集中唯一用户的数量)且不小于零。

In the else part of the if statement, we call the recommend function from the model module we imported. This function takes the userId as an argument, and returns a promise object with the recommendations. As soon as the promise resolves, we pass the recommendation to the index route to display. The extra argument forUser allows us to differentiate between when we’re making a recommendation and when we’re not.

if语句的else部分中,我们从导入的模型模块中调用recommend函数。 此函数将userId作为参数,并返回带有建议的Promise对象。 承诺解决后,我们会将建议传递到index路径以显示。 额外的参数forUser允许我们区分何时提出建议和何时不提出建议。

Now that we’re done with the entry point, we’ll move to the next section, where we load the model and make actual recommendations.

现在我们已经完成了入口点,我们将进入下一部分,在那儿我们加载模型并提出实际建议。

加载保存的模型并提出建议 (Loading the Saved Model and Making Recommendations)

In the model.js script, we’ll load the saved model using TensorFlow.js, and use it to make recommendations for a specified user.

在model.js脚本中,我们将使用TensorFlow.js加载保存的模型,并使用它为指定用户提供建议。

Copy and paste the code below in the model.js script:

将以下代码复制并粘贴到model.js脚本中:

In the first two lines, we import TensorFlow.js and also load the book JSON data.

在前两行中,我们导入TensorFlow.js并加载书籍JSON数据。

Next, in line 8, we create an asynchronous function to load the model from the folder model. The model is loaded with the tf.loadLayersModel function. Notice we pass the full file path, prefixed with (file://), to the model. The (file://) is important, as it instructs TensorFlow to look for the model in the local system.

接下来,在第8行中,我们创建一个异步函数来从文件夹模型中加载模型。 该模型使用tf.loadLayersModel函数加载。 注意,我们将以(file://)为前缀的完整文件路径传递给模型。 (file://)很重要,因为它指示TensorFlow在本地系统中查找模型。

Next, in line 13 we create an array of all book_ids in the book dataset. Remember the book_id feature we added in the book JSON data—this is an integer of numbers running from 1, to the max number of books. The tf.range function helps us easily create a continuous set of numbers from the specified range. We also save the length of the book object.

接下来,在第13行中,我们在图书数据集中创建一个包含所有book_ids的数组。 请记住,我们在书籍JSON数据中添加的book_id功能-这是一个从1到最大书籍数的整数。 tf.range函数可帮助我们轻松地从指定范围创建一组连续的数字。 我们还保存book对象的长度。

In the recommend function (lines 17–33), we perform the following:

recommend功能(第17-33行)中,我们执行以下操作:

  • First, we create the user array just like we did in the Python version of this code when predicting. This is because our model expects two arrays (user and books).
    首先,我们像在预测时在此代码的Python版本中所做的那样创建用户数组。 这是因为我们的模型需要两个数组(用户和书本)。
  • Then, in line 20, we await model loading. This is done asynchronously so that we don’t end up trying to predict when the model has not been loaded.
    然后,在第20行中,我们等待模型加载。 这是异步完成的,因此我们不会最终尝试预测何时未加载模型。
  • After loading the model, in line 22, we make predictions by calling the .predict function and passing in the book and user arrays. We also reshape the result to a 1D array.

    加载模型后,在第22行中,我们通过调用.predict函数并传入book和user数组来进行预测。 我们还将结果整形为一维数组。

  • In line 23, we retrieve the JavaScript array from the model prediction. Note that the prediction function always returns a tensor, so to work with this in JS, we can use arraySync to convert the tensor into an array.

    在第23行中,我们从模型预测中检索JavaScript数组。 请注意,预测函数始终返回张量,因此要在JS中使用此函数,我们可以使用arraySync将张量转换为数组。

  • In the next code block (25–30), we’re basically performing NumPy’s argMax function. While NumPy’s argMax function can return multiple values, TensorFlow.js’s version of argMax can only return a single value at a time. To solve this, we run a for loop for the number of recommendations we need, get the argMax from the predictions, retrieve and save the corresponding book in the recommendations array, and then drop the current argMax from the array.

    在下一个代码块(25–30)中,我们基本上在执行NumPy的 argMax 函数 。 虽然NumPy的argMax函数可以返回多个值,但TensorFlow.js的argMax版本argMax只能返回一个值。 为了解决这个问题,我们为需要的建议数量运行一个for循环,从预测中获取argMax ,检索并保存对应的书到recommendations数组中,然后从数组中删除当前的argMax

And that’s it, we’ve successfully replicated the recommendation function, just like the one we did in Python in part 1. Next, we’ll design the UI and display our books and recommendations.

就是这样,我们已经成功地复制了推荐功能,就像我们在Python第1部分中所做的一样。接下来,我们将设计UI并显示我们的书和建议。

创建用户界面并显示建议 (Creating the UI and Displaying Recommendations)

Now comes the beautiful part of our application. In this section, we’ll create a simple UI using mainly Bootstrap. Navigate to the views folder and paste the code below in the index.hbs file:

现在是我们应用程序的美丽部分。 在本节中,我们将主要使用Bootstrap创建一个简单的UI。 导航到views文件夹,并将下面的代码粘贴到index.hbs文件中:

The app UI is simple—we’re using Bootstrap’s page columns and rows class. This lets us easily partition our page into rows and columns. Below is a wireframe of what we want to achieve:

应用程序用户界面很简单-我们正在使用Bootstrap的页面列和行类。 这使我们可以轻松地将页面分为行和列。 以下是我们想要实现的线框:

Wireframe of app UI
应用程序UI的线框
  • In line 8, we add the Bootstrap CDN to our HTML page.
    在第8行中,我们将Bootstrap CDN添加到我们HTML页面。
  • In the body section (line 16 to 37), we create navigation using Bootstrap’s navbar class. You can customize this to display your preferred app name and links.

    在正文部分(第16至37行)中,我们使用Bootstrap的navbar类创建导航。 您可以对其进行自定义以显示您首选的应用名称和链接。

  • In the container div, we create a row with two columns. The first columns will contain the books alongside the next and prev buttons. This will span 8 columns. The second column which will span 4 columns and will hold the input tag and also the recommend button.
    在容器div中,我们创建一个包含两列的行。 第一列将包含书籍,以及下一个和上一个按钮。 这将跨越8列。 第二列将跨越4列,并保留输入标签和“推荐”按钮。
  • In the first column (line 43), we check if the variable forUser was passed alongside the rendered page. If it was passed, then we know we’re making recommendations, and as such, we loop through the recommendations array and for each recommended book and create a simple book card. This card will display the book image, title, and author.

    在第一列(第43行)中,我们检查变量forUser是否与呈现的页面一起传递。 如果通过了,那么我们就知道我们正在提出建议,因此,我们遍历建议数组并为每本推荐的书创建一个简单的书卡。 此卡将显示图书图片,书名和作者。

Single book card
单书卡

Note: We’re able to check, loop through, and access variables like recommendations and forUser from the backend in the frontend because we’re using handlebars.

:我们能够检查,通过循环和访问变量,如建议forUser从后端的前端,因为我们使用的把手。

  • If we aren’t displaying recommendations, then we’re displaying a books from the book dataset to the user. In that case, we can loop over the book slice (12 books) passed from the backend. This is what we’re doing in lines 63 to 72.
    如果我们不显示推荐,那么我们是在向用户显示一本书。 在这种情况下,我们可以遍历从后端传递来的书籍切片(12本书)。 这就是我们在第63至72行中所做的。
  • Next, in lines 77 to 94, we create two forms with the next and prev buttons. These forms will keep track of the current page start and end, and on click will call the get-next or get-prev routes.

    接下来,在77至94行中,我们使用next和prev按钮创建两个表单。 这些表单将跟踪当前页面的开始和结束,并且在单击时将调用get-nextget-prev一条路线。

  • And finally, in lines 97 to 107, we create an input field and a button that accepts the userId and makes recommendations.

    最后,在第97至107行中,我们创建一个输入字段和一个接受userId并提出建议的按钮。

Whew! That was a bit of a marathon, right? But now we’re now ready to test our application.

ew! 那有点像马拉松比赛吧? 但是现在我们已经准备好测试我们的应用程序了。

测试应用 (Testing the Application)

In this final section, we’ll run our application and test it. In your terminal/command prompt, run this command:

在最后一部分中,我们将运行我们的应用程序并对其进行测试。 在终端/命令提示符下,运行以下命令:

npm start

This should display some information similar to what you see below:

这应该显示一些类似于您在下面看到的信息:

This means our app is up and running. Go to your browser and type in the address:

这意味着我们的应用已启动并正在运行。 转到浏览器并输入地址:

localhost:3000

This should open your application page, as shown below:

这将打开您的应用程序页面,如下所示:

Book Application Page
图书申请页面

If you see the page above, then your application is running properly. You can now interact with the pages. The next and prev button should display different books upon clicking them. For instance, this is the second page you see upon clicking next:

如果您看到上面的页面,则您的应用程序运行正常。 您现在可以与页面进行交互。 单击下一个和上一个按钮时,它们应显示不同的书。 例如,这是您单击下一步时看到的第二页:

Book Application Second Page
图书申请第二页

To make recommendations, enter a number in the userId input field and click recommend. This should make a recommendation for that specific user.

要提出建议,请在userId输入字段中输入数字,然后单击“推荐”。 这应该为该特定用户提供建议。

For instance, below are the recommended books for user 20:

例如,以下是用户20的推荐书籍:

Recommended books for user 20
给用户的推荐书籍20

Note: Recommendations made by your model may be different from the one displayed above. This is may be due to variations in the way your model was trained.

注意:您的模型提出的建议可能与上面显示的建议不同。 这可能是由于您训练模型的方式不同。

And that's it! You have successfully trained a recommender model in Python, converted it to JavaScript format, and embedded it in a web app. There are lots of other things you can do to improve this app, but I’ll leave that to you to experiment with.

就是这样! 您已成功使用Python训练了一个推荐器模型,并将其转换为JavaScript格式,并将其嵌入到Web应用程序中。 您还可以做很多其他事情来改进此应用程序,但我将留给您进行试验。

In the last and final part of this tutorial series, you’ll learn how to deploy your application using Google’s Firebase, an efficient platform for managing scalable mobile and web applications.

在本教程系列的最后一部分,您将学习如何使用Google的Firebase部署应用程序, Firebase是用于管理可扩展的移动和Web应用程序的高效平台。

Bye for now, and happy learning.

再见了,学习愉快。

Connect with me on Twitter.

Twitter上 与我联系

Connect with me on LinkedIn.

LinkedIn 上与我联系

Editor’s Note: Heartbeat is a contributor-driven online publication and community dedicated to exploring the emerging intersection of mobile app development and machine learning. We’re committed to supporting and inspiring developers and engineers from all walks of life.

编者注: 心跳 是由贡献者驱动的在线出版物和社区,致力于探索移动应用程序开发和机器学习的新兴交集。 我们致力于为各行各业的开发人员和工程师提供支持和启发。

Editorially independent, Heartbeat is sponsored and published by Fritz AI, the machine learning platform that helps developers teach devices to see, hear, sense, and think. We pay our contributors, and we don’t sell ads.

Heartbeat在编辑上是独立的,由以下机构赞助和发布 Fritz AI ,一种机器学习平台,可帮助开发人员教设备看,听,感知和思考。 我们向贡献者付款,并且不出售广告。

If you’d like to contribute, head on over to our call for contributors. You can also sign up to receive our weekly newsletters (Deep Learning Weekly and the Fritz AI Newsletter), join us on Slack, and follow Fritz AI on Twitter for all the latest in mobile machine learning.

如果您想做出贡献,请继续我们的 呼吁捐助者 您还可以注册以接收我们的每周新闻通讯(《 深度学习每周》 和《 Fritz AI新闻通讯》 ),并加入我们 Slack ,然后继续关注Fritz AI Twitter 提供了有关移动机器学习的所有最新信息。

翻译自: https://heartbeat.fritz.ai/build-train-and-deploy-a-book-recommender-system-using-keras-tensorflow-js-6e1fc9a17c9a

http://www.taodudu.cc/news/show-6592092.html

相关文章:

  • Ajax 解释Ajax的XML和JSON格式,操作Ajax的几种封装方法【案例+解释】(二)
  • 聊聊BIO,NIO和AIO
  • ZYNQ:MIO、EMIO、IO的区别和灵活使用
  • 基于Zynq的MIO与EMIO的区别和应用
  • cesium 根据经纬度与距离计算另一个经纬度
  • 根据经纬度计算地球距离-Numpy向量版
  • 两个经纬度点之间计算距离【经纬度距离计算】
  • PHP根据经纬度计算两地之间的距离
  • 根据经纬度计算两地距离——R
  • 根据起始点经纬度、方向、距离,计算目标点经纬度
  • IOS根据两个经纬度计算相距距离
  • 地理空间距离计算及优化(根据两个点经纬度计算距离)
  • 【开源访谈】腾讯贺嘉:从小程序谈起,开发者该如何跟进新技术?
  • 飞书“蒙冤”,还是舆论有噪声?
  • 工作十年以后,你们悟出了什么职场道理?
  • python每日一练(2021/11/10)字符串类型的cookie转化为字典类型
  • 笔记:XSS浅析
  • 如何使用谷歌浏览器修改cookie的值(黑客成长之路)
  • Cool Number
  • sessioncookie
  • Cool stuff
  • 创建新的cookie
  • Cool JavaScript Tricks
  • CookieLocaleResolver国际化(Springboot)
  • cookie、sessionStorage、localstorage作用范围
  • Cool Website
  • 使用Samba实现文件共享:Windows和Linux之间
  • 二、Vue2.0项目结构内容及配置解析
  • 【Vue前端开发学习】第2章,Vue项目目录结构
  • vue框架目录结构(全)

使用Keras,TensorFlow.js,Node.js和Firebase构建,训练和部署Book Recommender系统(第2部分)相关推荐

  1. 个人服务器搭建(轻便型) vue.js + node.js + mysql + centOs7

    个人服务器搭建(轻便型) vue.js + node.js + mysql + centOs7 此笔记有望帮助到他人也自己可回顾学习(如有误望指正) 完成以下四点即可开启web服务 一.创建 vue. ...

  2. Vue.js+Node.js开发实战:从入门到项目上线

    <Vue.js+Node.js开发实战:从入门到项目上线>以JavaScript语言为基础,以一个完整的网站开发过程为主线,介绍了一整套面向Web项目的开发技术,如使用Node.js搭建服 ...

  3. node.js(node.js+mongoose小案例)_实现简单的注册登录退出

    一.前言 通过node.js基本知识对node.js基本知识的一个简单应用 1.注册 2.登录 3.退出 二.基本内容 1.项目结构搭建如图所示 2.这个小案列中用到了art-template子模板以 ...

  4. java 推送数据给js,Node.js实现数据推送

    场景:后端更新数据推送到客户端(Java部分使用Tomcat服务器). 后端推送数据的解决方案有很多,比如轮询.Comet.WebSocket. 1. 轮询对于后端来说开发成本最低,就是按照传统的方式 ...

  5. [Node.js] node.js入门

    什么是nodejs 1.Node.js官网地址 中文 1.Node是一个构建于Chrome V8引擎之上的一个Javascript运行环境 Node是一个运行环境,作用是让js拥有开发服务端的功能 2 ...

  6. 一统江湖的大前端(2)—— Mock.js + Node.js 如何与后端潇洒分手

    <一统江湖的大前端>系列是自己的前端学习笔记,旨在介绍javascript在非网页开发领域的应用案例和发现各类好玩的js库,不定期更新.如果你对前端的理解还是写写页面绑绑事件,那你真的是有 ...

  7. 新晋小王子 doodoo.js Node.js开发框架

    2019独角兽企业重金招聘Python工程师标准>>> Doodoo.js Doodoo.js -- 中文最佳实践Node.js Web快速开发框架,支持Koa.js中间件. //b ...

  8. js node.js读取excel文件返回为json文本

    node-xlsx: 基于Node.js解析excel文件数据及生成excel文件:只支持xlsx xlsx: 基于Node.js解析excel文件数据及生成excel文件:只支持xlsx excel ...

  9. 从零到一的react.js+node.js+express.js+mysql产品开发全流程

    序言 组长说要使自己对产品在技术层面有一个清晰且足够的了解,最好自己动手开发一个迷你产品,例如todolist,因为公司有提供员工自学使用的服务器,所以我就来试试了,而且一步一步的记录自己的学习过程, ...

最新文章

  1. java excel开元_开元表格框架extremeTable
  2. java中array_Java 中的array数组总结之一
  3. strtus2改成springboot_jdk1.6环境下struts2改spring boot方案-阿里云开发者社区
  4. mac 无法ssh localhost,错误提示:bash: /usr/local/bin/ssh_session: Permission denied
  5. JavaScript中的事件循环
  6. 中国天然金红石市场趋势报告、技术动态创新及市场预测
  7. 微信视频不能连接到服务器,微信无法连接到服务器
  8. IOS开发中的几种设计模式介绍
  9. matlab 怎么保存,matlab怎么保存程序
  10. windows10 LTSC转换成pro
  11. 【学习】把自己的电脑创建成ftp服务器,用Cuteftp软件上传文件和下载文件。
  12. 加了尾注怎么添加新页_如何在毕业论文利用尾注添加参考文献之后再续正文
  13. php.ini maxfileuploads,细说PHP高洛峰文件上传类源文件
  14. XAMARIN.ANDROID的安装
  15. HEVC Cabac解码
  16. 微信公众号开发本地环境搭建
  17. 薄膜收放卷张力控制问题
  18. 2015美国大学计算机科学专业排名,USNews2015美国大学计算机科学专业研究生排名...
  19. 人生旅程需要自己去把握
  20. linux远程工具怎么设置网,xshell远程工具怎么设置?xshell设置为中文的教程

热门文章

  1. 虚拟试衣:使用VITON或CP-VTON模型在DeepFashion数据集上进行虚拟试衣任务
  2. 微信公众号语音信息自动回复语音信息
  3. Linux运维之(九)LNMP环境搭建
  4. java jdbc 删除不干净sa登录失败_JDBC连接数据库解决用户sa登录失败的问题
  5. 让你终身受益的5个定律
  6. 远程在线办公效率与业绩提升秘笈
  7. oracle服务器io,ORACLE数据库服务器IO高的分析方案和案例探讨
  8. 2021年中国装载机行业发展现状分析,行业集中度不断提升「图」
  9. android 7和苹果手机,现在iphone7p相当什么档次的安卓手机?今天知道,别被坑
  10. 大地坐标BLH转平面坐标xyh(高斯投影坐标正算) Java版