The text/ZhenZi

After imgCook.com was released, we posted a lot of articles on Nuggets, Zhihu, wechat moments and our official account. The most common feedback we got was that the front end was going to lose its job. According to the current trend, the demand for P5 front-end engineers will be significantly reduced. Imgcook has replaced P5 front-end engineers for 80% of the intelligent generation of UI and logic code from data analysis, according to statistics at the bottom of imgCook.com. Both trends and data show the demise of low-tech, repetitive work on the traditional front end.

As Jack Ma said when he taught young people entrepreneurship in Hong Kong, the steam engine and electricity have liberated human physical strength, while artificial intelligence and machine learning have liberated human brain. When evaluating the unemployment caused by steam engine and electricity, Mr. Ma said that with the progress of science and technology, human beings have been liberated from heavy manual labor and gradually transferred to mental labor, which is the progress of human society. Today, the front end is liberated from the repetitive work of the construction team, and gradually to the transition of intelligent high-tech work, which is the progress of the front end technology.

To sum up, today it is impossible to bypass the intelligent proposition, just like today’s society can not go back to the slash-and-burn era. So come to foresee the future that we introduced a github.com/alibaba/pipcook project, trying to help the front zero cost into intelligent, joint Google Tensorflow. Js team, use this framework to easily get through intelligent as overseers second pulse: Connect the front-end technology ecosystem and reuse Python technology ecosystem.

Therefore, the following article will share with you the ways from concept to method, method to practice, tool to application based on the Pipcook framework: which front-end jobs will be replaced by intelligence? How to apply this intelligent method in work? How do front end engineers work with AI using pipcook? Finally, the detailed design implementation of IMGCook is used as a case to explain the practice systematically.

Instead of going to imgcook.com for an experience, here’s an official example from Tensorflow.js to see how far intelligence has come. The first is the definition problem: many people are confused about the relationship between engine horsepower and mileage. Is it possible to predict how fuel-efficient a future car will be based on engine horsepower? The traditional method of statistical analysis is to define the pattern and use the model to calculate and analyze, and the man and the computer are the master-servant relationship of instruction and execution. The method of machine learning is to use the data learning model to analyze. People and computers are in a cooperative relationship of providing data and understanding data. The following code shows how this collaboration can be implemented in Javascript:

Environment Preparation:

index.html


      
<html>
<head>
  <title>TensorFlow.js Tutorial</title>

  <! -- Import TensorFlow.js -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
  <! -- Import tfjs-vis -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tfjs-vis.umd.min.js"></script>

  <! -- Import the main script file -->
  <script src="script.js"></script>

</head>

<body>
</body>
</html>
Copy the code

Here tensorflow. js is Google’s official front-end machine learning base library, TFJS-VIS is a visualization tool used to display data, models and other information, and script.js is the example code.

script.js

The sample code consists of four main parts: supplying the data, defining the model, training the model, predicting the model, and the run function that executes the logic. The following is a detailed introduction of these four parts.

Provide data:

The data provided can be divided into three stages: data acquisition, data analysis and data processing. Obtaining data can be interpreted as obtaining raw data from existing data sources such as logs and cloud object storage. Analyzing data is a question of looking at data, looking for data: is it average? Ordinary? Is it realistic? Is the description sufficient for the problem we are defining? Data processing is to calibrate the data according to the results of analysis and then format it for the training requirements of the model.

Get data:

async function getData() {
  const carsDataReq = await fetch(
    "https://storage.googleapis.com/tfjs-tutorials/carsData.json"
  );
  const carsData = await carsDataReq.json();
  return carsData;
}
Copy the code

Analysis data:

async function run() {
  // Load and plot the original input data that we are going to train on.
  const data = await getData();
  const values = data.map((d) = > ({
    x: d.horsepower,
    y: d.mpg,
  }));

  tfvis.render.scatterplot(
    { name: "Horsepower v MPG" },
    { values },
    {
      xLabel: "Horsepower".yLabel: "MPG".height: 300}); }document.addEventListener("DOMContentLoaded", run);
Copy the code


Processing data:

Washing vegetables: Do some cleaning of the raw data first:

function cleaned(data){
  const cleaned = carsData
      .map((car) = > ({
        mpg: car.Miles_per_Gallon,
        horsepower: car.Horsepower,
      }))
      .filter((car) = >car.mpg ! =null&& car.horsepower ! =null);

  return cleaned;
}
Copy the code

4. To process the data into a model that can be eaten:

function convertToTensor(data) {
  // Wrapping these calculations in a tidy will dispose any
  // intermediate tensors.

  return tf.tidy((a)= > {
    // Step 1. Shuffle the data
    tf.util.shuffle(data);

    // Step 2. Convert data to Tensor
    const inputs = data.map((d) = > d.horsepower);
    const labels = data.map((d) = > d.mpg);

    const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
    const labelTensor = tf.tensor2d(labels, [labels.length, 1]);

    //Step 3. Normalize the data to the range 0 - 1 using min-max scaling
    const inputMax = inputTensor.max();
    const inputMin = inputTensor.min();
    const labelMax = labelTensor.max();
    const labelMin = labelTensor.min();

    const normalizedInputs = inputTensor
      .sub(inputMin)
      .div(inputMax.sub(inputMin));
    const normalizedLabels = labelTensor
      .sub(labelMin)
      .div(labelMax.sub(labelMin));

    return {
      inputs: normalizedInputs,
      labels: normalizedLabels,
      // Return the min/max bounds so we can use them later.
      inputMax,
      inputMin,
      labelMax,
      labelMin,
    };
  });
}
Copy the code

Don’t worry about Tensor, just think of it as a form of organizing data like Json. The only thing you need to understand here is “normalization,” because data can have a variety of values, how do you unify the data into one value range? This code scales the data from 0 to 1, using the constraints of maxima and minima to ensure that the nature of the data has not changed but that the expression has changed.

Another concept is the Label, which is easy to understand. Each horsepower is a Label, and the data is the miles per gallon. The example loaded data is the miles per gallon and the corresponding engine horsepower Label.

. {"mpg":15, // Data: miles per gallon"horsepower":165, // tag: engine horsepower}, {"mpg":18, // Data: miles per gallon"horsepower":150, // tag: engine horsepower}, {"mpg"// Data: miles per gallon"horsepower":150, // tag: engine horsepower},...Copy the code

With the labeled sample data: vegetables, washed vegetables, fried vegetables and then fed to the model, the model can digest and understand the patterns and rules behind the data.

Define the model

In fact, in addition to research institutions and senior scholars, few people can really define the model. Algorithm engineers are still far away from defining the model after experiencing adjustment engineers and data engineers, and most of the time even algorithm engineers are just applying. Therefore, just go ahead and define the model by following the most popular and effective model copy in the industry.

/** * Define Model */
function createModel() {
  // Create a sequential model
  const model = tf.sequential();

  // Add a single input layer
  model.add(tf.layers.dense({ inputShape: [1].units: 1.useBias: true }));
  model.add(tf.layers.dense({ units: 50.activation: "sigmoid" }));
  // Add an output layer
  model.add(tf.layers.dense({ units: 1.useBias: true }));

  return model;
}
Copy the code

If you use github.com/alibaba/pipcook even saved copy, because we commonly used model and community ecological good copy (migration) in advance. If you need a copy of the tensorFlow model, it is easy to copy it from the tensorFlow model. If you need a copy of the tensorFlow model, it is easy to copy the tensorFlow model.

Training model

Unlike human-human collaboration, machine learning models are useless until they are trained. They learn the patterns and patterns behind the data only after they have eaten the cooked food:

async function trainModel(model, inputs, labels) {
  // Prepare the model for training.
  model.compile({
    optimizer: tf.train.adam(),
    loss: tf.losses.meanSquaredError,
    metrics: ["mse"]});const batchSize = 32;
  const epochs = 50;

  return await model.fit(inputs, labels, {
    batchSize,
    epochs,
    shuffle: true.callbacks: tfvis.show.fitCallbacks(
      { name: "Training Performance"},"loss"."mse"] and {height: 200.callbacks: ["onEpochEnd"]})}); }Copy the code

The batchSize and Epochs of model.fit are hyperparameters, and the algorithm engineers are tuning engineers because of this. They spend most of their time tuning these two parameters. What these two parameters mean is very simple, batchSize tells the model how many bites to eat? How many bites does Epochs tell the model to take at a time? Old models are usually afraid of choking if they eat too much, or improper eating methods under different tasks. For example, they may eat one dish at a time to have a meal, or they may eat several mouthfuls in order to remember a delicious food.

Model to predict

After eating the labeled data, as long as it is eaten correctly, the model can remember the patterns and laws behind the data, and the next natural step is to pull the model to cooperate with us:

function testModel(model, inputData, normalizationData) {
  const { inputMax, inputMin, labelMin, labelMax } = normalizationData;

  // Generate predictions for a uniform range of numbers between 0 and 1;
  // We un-normalize the data by doing the inverse of the min-max scaling
  // that we did earlier.
  const [xs, preds] = tf.tidy((a)= > {
    const xs = tf.linspace(0.1.100);
    const preds = model.predict(xs.reshape([100.1]));

    const unNormXs = xs.mul(inputMax.sub(inputMin)).add(inputMin);

    const unNormPreds = preds.mul(labelMax.sub(labelMin)).add(labelMin);

    // Un-normalize the data
    return [unNormXs.dataSync(), unNormPreds.dataSync()];
  });
Copy the code

The model. Predict is used to predict the random data generated by Tf.linspace, and the output is: what horsepower engine is this data? So, tell the model miles per gallon, and the model tells us roughly how much horsepower the engine is, and bam! Collaboration.

The complete code

/** * Get the car data reduced to just the variables we are interested * and cleaned of missing data. */
async function getData() {
  const carsDataReq = await fetch(
    "https://storage.googleapis.com/tfjs-tutorials/carsData.json"
  );
  const carsData = await carsDataReq.json();
  const cleaned = carsData
    .map((car) = > ({
      mpg: car.Miles_per_Gallon,
      horsepower: car.Horsepower,
    }))
    .filter((car) = >car.mpg ! =null&& car.horsepower ! =null);

  return cleaned;
}

/** * Define Model */
function createModel() {
  // Create a sequential model
  const model = tf.sequential();

  // Add a single input layer
  model.add(tf.layers.dense({ inputShape: [1].units: 1.useBias: true }));
  model.add(tf.layers.dense({ units: 50.activation: "sigmoid" }));
  // Add an output layer
  model.add(tf.layers.dense({ units: 1.useBias: true }));

  return model;
}

/** * Convert the input data to tensors that we can use for machine * learning. We will also do the important best practices of _shuffling_ * the data and _normalizing_ the data * MPG on the y-axis. */
function convertToTensor(data) {
  // Wrapping these calculations in a tidy will dispose any
  // intermediate tensors.

  return tf.tidy((a)= > {
    // Step 1. Shuffle the data
    tf.util.shuffle(data);

    // Step 2. Convert data to Tensor
    const inputs = data.map((d) = > d.horsepower);
    const labels = data.map((d) = > d.mpg);

    const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
    const labelTensor = tf.tensor2d(labels, [labels.length, 1]);

    //Step 3. Normalize the data to the range 0 - 1 using min-max scaling
    const inputMax = inputTensor.max();
    const inputMin = inputTensor.min();
    const labelMax = labelTensor.max();
    const labelMin = labelTensor.min();

    const normalizedInputs = inputTensor
      .sub(inputMin)
      .div(inputMax.sub(inputMin));
    const normalizedLabels = labelTensor
      .sub(labelMin)
      .div(labelMax.sub(labelMin));

    return {
      inputs: normalizedInputs,
      labels: normalizedLabels,
      // Return the min/max bounds so we can use them later.
      inputMax,
      inputMin,
      labelMax,
      labelMin,
    };
  });
}

async function trainModel(model, inputs, labels) {
  // Prepare the model for training.
  model.compile({
    optimizer: tf.train.adam(),
    loss: tf.losses.meanSquaredError,
    metrics: ["mse"]});const batchSize = 32;
  const epochs = 50;

  return await model.fit(inputs, labels, {
    batchSize,
    epochs,
    shuffle: true.callbacks: tfvis.show.fitCallbacks(
      { name: "Training Performance"},"loss"."mse"] and {height: 200.callbacks: ["onEpochEnd"]})}); }function testModel(model, inputData, normalizationData) {
  const { inputMax, inputMin, labelMin, labelMax } = normalizationData;

  // Generate predictions for a uniform range of numbers between 0 and 1;
  // We un-normalize the data by doing the inverse of the min-max scaling
  // that we did earlier.
  const [xs, preds] = tf.tidy((a)= > {
    const xs = tf.linspace(0.1.100);
    const preds = model.predict(xs.reshape([100.1]));

    const unNormXs = xs.mul(inputMax.sub(inputMin)).add(inputMin);

    const unNormPreds = preds.mul(labelMax.sub(labelMin)).add(labelMin);

    // Un-normalize the data
    return [unNormXs.dataSync(), unNormPreds.dataSync()];
  });

  const predictedPoints = Array.from(xs).map((val, i) = > {
    return { x: val, y: preds[i] };
  });

  const originalPoints = inputData.map((d) = > ({
    x: d.horsepower,
    y: d.mpg,
  }));

  tfvis.render.scatterplot(
    { name: "Model Predictions vs Original Data" },
    {
      values: [originalPoints, predictedPoints],
      series: ["original"."predicted"],}, {xLabel: "Horsepower".yLabel: "MPG".height: 300}); }async function run() {
  // Load and plot the original input data that we are going to train on.
  const data = await getData();
  const values = data.map((d) = > ({
    x: d.horsepower,
    y: d.mpg,
  }));

  tfvis.render.scatterplot(
    { name: "Horsepower v MPG" },
    { values },
    {
      xLabel: "Horsepower".yLabel: "MPG".height: 300});// More code will be added below
  // Create the model
  const model = createModel();
  tfvis.show.modelSummary({ name: "Model Summary" }, model);

  // Convert the data to a form we can use for training.
  const tensorData = convertToTensor(data);
  const { inputs, labels } = tensorData;

  // Train the model
  await trainModel(model, inputs, labels);
  console.log("Done Training");

  // Make some predictions using the model and compare them to the
  // original data
  testModel(model, data, tensorData);
}

document.addEventListener("DOMContentLoaded", run);
Copy the code

This completes the whole process of buying food (fetch data), washing food (process data), frying food (process data), headhunting (find/copy/define model), feeding (training model), and collaborating (model prediction), all within the browser (Tensorflow.js has added WASM acceleration capabilities, WebNN acceleration capabilities will be supported in the future), all front-end technology, do you think front-end intelligence has arrived?

What`s next

  • Still staring at the metrics during launch? Organize the logs and metrics into the miles per gallon and engine horsepower format shown in the example, use the code above to train a model, and write a Chrome plugin to look at the screen.
  • Finish the follow-up, the system to learn intelligent, in the front field of human-computer collaborative programming.
  • Introduce the principle of the method in this series, go to www.tensorflow.org/resources/m… Copy more models.