Текст / Донни Йен
После выпуска imgcook.com мы опубликовали много статей о Nuggets, Zhihu, WeChat Moments и официальном аккаунте, и больше всего отзывов, которые мы получили, заключались в том, что интерфейс будет безработным. В соответствии с текущей тенденцией спрос на фронтенд-инженеров в районе уровня P5 значительно сократится. Внизу официального сайта imgcook.com есть статистика.В случае интеллектуальной генерации UI и логического кода из анализа данных imgcook уже может заменить 80% работы, проделанной фронтенд-инженерами P5. Независимо от тенденций или данных, мы видим, что традиционная передовая низкотехнологичная работа с высоким дублированием умирает.
Как сказал г-н Джек Ма, когда он обучал молодых людей своему предпринимательскому опыту в Гонконге, паровые двигатели и электричество высвободили человеческие физические силы, а искусственный интеллект и машинное обучение высвободили возможности человеческого мозга. Оценивая проблему безработицы, вызванную паровыми двигателями и электричеством, г-н Ма сказал, что люди освобождаются от тяжелого ручного труда благодаря развитию науки и техники и постепенно переходят к умственному труду, что является прогрессом человеческого общества. Сегодня front-end освобождается от монотонной работы строительной бригады и постепенно переходит к интеллектуальной высокотехнологичной работе, что является прогрессом front-end технологий.
Подводя итог, можно сказать, что предложение интеллекта сегодня невозможно обойти, так же как сегодняшнее общество не может вернуться к эпохе подсечно-огневого земледелия. В преддверии наступления будущего мы запустили проект github.com/alibaba/pipcook, пытаясь помочь интерфейсу стать интеллектуальным без каких-либо затрат.Совместно с командой Google Tensorflow.js этот фреймворк может легко открыть два импульса интеллекта: подключение внешней технологии экологии, повторное использование экологии технологии Python.
Поэтому следующая статья, основанная на фреймворке Pipcook, расскажет вам о пути от концепции к методу, от метода к практике, от инструмента к приложению: Заменит ли фронтенд интеллект? Как этот интеллектуальный подход можно применить на работе? Как фронтенд-инженеры могут работать вместе с pipcook и AI? Наконец, подробный дизайн и реализация imgcook используются в качестве примера для систематического объяснения практики.
В дополнение к imgcook.com, чтобы испытать, вот официальный пример tensorflow.js, чтобы увидеть, насколько далеко от нас интеллект. Во-первых, это вопрос определения: многие люди не понимают, как мощность двигателя связана с пробегом? Можно ли предсказать, будет ли будущий автомобиль экономичным, исходя из мощности двигателя? Традиционный метод статистического анализа заключается в определении модели, использовании модели для расчетов и анализа, а человек и компьютер являются отношениями хозяин-слуга в инструкции и выполнении. Метод машинного обучения заключается в изучении модели с помощью данных и использовании модели, изученной моделью, для анализа.Человек и компьютер представляют собой совместные отношения между предоставлением данных и их пониманием. Следующий код показывает, как это сотрудничество реализовано в Javascript:
Подготовка среды:
index.html
<!DOCTYPE html>
<html>
<head>
<title>TensorFlow.js Tutorial</title>
<!-- Import TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
<!-- Import tfjs-vis -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
<!-- Import the main script file -->
<script src="script.js"></script>
</head>
<body>
</body>
</html>
Здесь Tensorflow.js — официальная базовая библиотека машинного обучения Google, tfjs-vis — инструмент визуализации, используемый для отображения данных, моделей и другой информации, а script.js — код примера.
script.js
Код примера в основном состоит из четырех частей: предоставление данных, определение модели, обучение модели, прогнозирование модели и функция запуска, которая выполняет логику. Эти четыре части подробно описаны ниже.
предоставить данные:
Предоставление данных делится на три этапа: сбор данных, анализ данных и обработка данных. Получение данных можно понимать как получение необработанных данных из существующих источников данных, таких как журналы и облачное хранилище объектов. Анализ данных — это наблюдение за данными и поиск проблемы данных: среднее? Обычный? Соответствует ли это реальной сцене? Достаточно ли описания для проблемы, которую мы определяем? Обработка данных — это калибровка данных на основе результатов анализа, а затем их форматирование в соответствии с требованиями обучения модели.
получить данные:
async function getData() {
const carsDataReq = await fetch(
"https://storage.googleapis.com/tfjs-tutorials/carsData.json"
);
const carsData = await carsDataReq.json();
return carsData;
}
анализировать данные:
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);
Обработка данных:
Мойка овощей: сначала почистите исходные данные:
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;
}
Приготовление: обработайте данные во что-то, что модель может съесть:
function convertToTensor(data) {
// Wrapping these calculations in a tidy will dispose any
// intermediate tensors.
return tf.tidy(() => {
// 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,
};
});
}
Плевать на слово Tensor (тензор), просто понимать его как формат организации данных вроде Json. Единственное, что нужно понять здесь, это «нормализация», потому что данные могут иметь разные диапазоны значений, как объединить данные в один диапазон значений? Приведенный выше код помещает данные в диапазон 0 — 1 и масштабирует данные с ограничениями максимального и минимального значений, чтобы гарантировать, что суть данных не изменилась, но изменилось выражение.
Другим понятием является метка, которая хорошо понятна. Каждая лошадиная сила — это метка, а данные — это пробег на галлон. Данные, загруженные в примере, — это данные о пробеге на галлон и мощность двигателя, соответствующая этим данным.
...
{
"mpg":15, //数据:每加仑行驶的里程
"horsepower":165, //标签:发动机马力
},
{
"mpg":18, //数据:每加仑行驶的里程
"horsepower":150, //标签:发动机马力
},
{
"mpg":16, //数据:每加仑行驶的里程
"horsepower":150, //标签:发动机马力
},
...
Используйте образцы данных, помеченные таким образом: овощи, мойте овощи и жареные овощи, и скормите их модели.После еды модель может переварить и понять закономерности и законы, лежащие в основе данных.
Определить модель
На самом деле, за исключением исследовательских институтов и старших ученых, очень немногие люди могут действительно определить модель.Инженеры-алгоритмы все еще далеки от определения моделей после того, как у них есть опыт инженеров по настройке параметров и инженеров по данным.Большую часть времени даже инженеры-алгоритмы просто применяют их. Поэтому просто используйте его.Чтобы определить модель, вам нужно всего лишь скопировать домашнее задание по самой популярной и эффективной модели в отрасли.
/**
* 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;
}
Если вы используете github.com/alibaba/pipcook, вы можете даже сохранить копию, потому что мы и сообщество экологии заранее скопируем (пересадим) часто используемые модели. Если вам нужно скопировать его, это очень просто. Здесь tf — официальное имя библиотеки tensorflow. Определения функций и определений параметров такие же, как в Python (различия в написании, вызванные языковыми особенностями, должны быть изменены в деталях). Просто скопируйте определение.
Обучите модель
В отличие от сотрудничества между людьми, модель машинного обучения является новичком перед обучением и ест наши жареные блюда: после маркировки данных модель может изучить закономерности и законы, лежащие в основе данных:
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"],
{ height: 200, callbacks: ["onEpochEnd"] }
),
});
}
Вы правильно прочитали.Model.fit действительно питает ta, здесь batchSize и epochs являются гиперпараметрами, а вышеупомянутый инженер алгоритмов является инженером по настройке параметров, поэтому они действительно настраивают эти два параметра большую часть времени. Смысл этих двух параметров очень прост, batchSize сообщает модели, сколько съедать за один укус? эпохи сообщают модели, сколько кусочков нужно съесть за раз? Старая модель, как правило, боится подавиться, съев слишком много, или неправильно поесть под разными задачами, точно так же, как съесть один кусочек риса и одно блюдо, чтобы запомнить вкусную еду.
Предсказание модели
После того, как вы съели блюдо с маркировкой данных, если оно съедено правильно, модель может запомнить закономерности и законы, лежащие в основе данных.Следующий шаг — заставить модель сотрудничать с нами:
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(() => {
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()];
});
Здесь model.predict позволяет модели предсказывать случайные данные, сгенерированные tf.linspace, а на выходе получается, сколько лошадиных сил у двигателя? Итак, сообщите модели количество миль на галлон, и модель может приблизительно сказать нам, сколько лошадиных сил это от двигателя, да-да! Сотрудничество завершено.
полный код
/**
* 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(() => {
// 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"],
{ 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(() => {
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);
На этом завершается весь процесс покупки продуктов (получение данных), мытья овощей (обработка данных), приготовления пищи (обработка данных), подбора персонала (поиск/копирование/определение моделей), кормление (обучение моделей) и сотрудничество (прогнозирование моделей). выполняются в браузере (в Tensorflow.js добавлена возможность ускорения WASM, а в будущем будет поддерживаться возможность ускорения WebNN), все из которых являются интерфейсными технологиями. Как вы думаете, появился интерфейсный интеллект?
What`s next
- Все еще смотрите на экран, чтобы увидеть различные индикаторы, когда он выпущен и запущен? Организуйте журналы и показатели в формате пробега на галлон и мощности двигателя в примере, обучите модель с помощью приведенного выше кода и напишите подключаемый модуль Chrome для просмотра экрана.
- После прочтения продолжения система учится быть интеллектуальной и выполняет совместное программирование человека и машины в области внешнего интерфейса.
- Используя принципы и методы, представленные в этой серии, перейдите кwoohoo.tensorflow.org/resources/no…Скопируйте больше моделей.