>웹 프론트엔드 >JS 튜토리얼 >TensorFlow.js 기반 JavaScript 머신러닝

TensorFlow.js 기반 JavaScript 머신러닝

little bottle
little bottle앞으로
2019-04-29 09:44:232813검색

이 문서에서는 TensorFlow.js를 기반으로 한 JavaScript 기계 학습에 대해 설명합니다. 여기에는 관심 있는 친구가 배울 수 있는 특정 참고 가치가 있습니다.

TensorFlow.js 기반 JavaScript 머신러닝

Python이나 R 프로그래밍 언어는 상대적으로 학습 곡선이 쉬운 반면, 웹 개발자는 익숙한 JavaScript 영역 내에서 작업하는 것을 선호합니다. 현재 node.js는 JavaScript를 모든 분야에 적용하기 시작했습니다. 이러한 대세에 따라 우리는 기계 학습을 위해 JS를 이해하고 사용해야 합니다. Python은 사용 가능한 패키지 수로 인해 인기를 얻었지만 JS 커뮤니티도 이를 따랐습니다. 이 글은 초보자가 간단한 분류기를 구축하는 방법을 배우는 데 도움이 될 것입니다.

Create

tensorflow.js를 사용하여 브라우저에서 모델을 교육하는 웹페이지를 만들 수 있습니다. 모델은 집의 "avgareanumberofrows"를 고려하여 집의 "가격"을 예측하는 방법을 학습할 수 있습니다.

이를 위해 우리가 해야 할 일은:

데이터를 로드하고 훈련을 위해 준비하는 것입니다.

모델의 아키텍처를 정의합니다.

모델을 훈련하고 훈련하는 동안 성능을 모니터링하세요.

몇 가지 예측을 통해 훈련된 모델을 평가합니다.

1단계: 기본부터 시작하겠습니다

HTML 페이지를 만들고 JavaScript를 포함하세요. 다음 코드를 index.html이라는 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>

코드용 자바스크립트 파일 생성

위의 HTML 파일과 같은 폴더에 script.js라는 파일을 생성하고 다음 코드를 넣어주세요.

console.log(&#39;Hello TensorFlow&#39;);

Testing

이제 HTML 및 JavaScript 파일을 만들었으므로 테스트해 보세요. 브라우저에서 index.html 파일을 열고 devtools 콘솔을 엽니다.

모든 것이 괜찮다면 두 개의 전역 변수가 생성되어 devtools 콘솔에서 사용할 수 있어야 합니다.

  • tf는 tensorflow.js 라이브러리에 대한 참조입니다.
  • tfvis는 tfjs vis 라이브러리에 대한 참조입니다.

이제 "Hello TensorFlow"라는 메시지를 볼 수 있어야 합니다. 그렇다면 다음 단계로 넘어갈 수 있습니다.

TensorFlow.js 기반 JavaScript 머신러닝

참고: 재사용 가능한 JS 코드는 Bit를 사용하여 공유할 수 있습니다.

Bit(Bit on GitHub)는 프로젝트와 애플리케이션 전반에서 재사용 가능한 JavaScript 코드를 공유하는 가장 빠르고 확장성이 뛰어난 방법입니다. 무료로 사용해 보세요.

구성 요소 검색 및 협업·Bit

Bit은 개발자가 구성 요소를 공유하고 협업하여 놀라운 소프트웨어를 구축할 수 있는 장소입니다. 공유 구성요소 발견...
Bit.dev

예: 공유 구성요소로 사용되는 Ramda

Ramda by Ramda·Bit

JavaScript 프로그래머를 위한 실용적인 함수 라이브러리입니다. -256 자바스크립트 구성요소. 예: 등호, 곱하기…
Bit.dev

2단계: 데이터 로드, 데이터 형식화 및 입력 데이터 시각화

여기에서 찾을 수 있는 "집" 데이터세트를 로드합니다. 이는 특정 주택의 다양한 특징을 포함합니다. 이 튜토리얼에서는 평균 방 크기와 주택당 가격에 대한 데이터만 필요합니다.

script.js 파일에 다음 코드를 추가하세요.

async function getData() {
  Const houseDataReq=await
fetch(&#39;https://raw.githubusercontent.com/meetnandu05/ml1/master/house.json&#39;);  
  const houseData = await houseDataReq.json();  
  const cleaned = houseData.map(house => ({
    price: house.Price,
    rooms: house.AvgAreaNumberofRooms,
  }))
  .filter(house => (house.price != null && house.rooms != null));

  return cleaned;
}

이렇게 하면 가격이나 객실 수가 정의되지 않은 모든 항목이 제거됩니다. 이 데이터를 분산형 차트로 그려서 어떻게 보이는지 확인할 수 있습니다.

script.js 파일 하단에 다음 코드를 추가하세요.

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.rooms,
    y: d.price,
  }));
  tfvis.render.scatterplot(
    {name: &#39;No.of rooms v Price&#39;},
    {values}, 
    {
      xLabel: &#39;No. of rooms&#39;,
      yLabel: &#39;Price&#39;,
      height: 300
    }
  );
  // More code will be added below
}
document.addEventListener(&#39;DOMContentLoaded&#39;, run);

페이지를 새로고침하면 아래와 같이 데이터의 산점도가 포함된 패널이 페이지 왼쪽에 표시됩니다.

TensorFlow.js 기반 JavaScript 머신러닝

일반적으로 데이터 작업을 할 때는 데이터를 살펴보고 필요한 경우 정리하는 방법을 찾는 것이 가장 좋습니다. 데이터를 시각화하면 모델이 데이터의 구조를 학습할 수 있는지 여부를 이해할 수 있습니다.

위 그림에서 알 수 있듯이 방 수와 가격 사이에는 양의 상관관계가 있습니다. 즉, 일반적으로 방 수가 늘어날수록 주택 가격이 상승합니다.

3단계: 학습할 모델 구축

이 단계에서는 기계 학습 모델을 구축하는 코드를 작성하겠습니다. 모델은 주로 이 코드를 기반으로 구성되므로 이는 중요한 단계입니다. 기계 학습 모델은 입력을 받아 출력을 생성합니다. tensorflow.js의 경우 신경망을 구축해야 합니다.

모델을 정의하려면 script.js 파일에 다음 함수를 추가하세요.

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

  // Add a single hidden layer
  model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));

  // Add an output layer
  model.add(tf.layers.dense({units: 1, useBias: true}));
  return model;
}

이것은 tensorflow.js에서 정의할 수 있는 가장 간단한 모델 중 하나입니다. 각 줄을 간단히 나누어 보겠습니다.

모델 인스턴스화

const model = tf.sequential();

이렇게 하면 tf.model 개체가 인스턴스화됩니다. 이 모델은 입력이 출력으로 직접 흐르기 때문에 연속적입니다. 다른 유형의 모델에는 분기가 있을 수 있고 여러 입력 및 출력이 있을 수도 있지만 대부분의 경우 모델은 연속적입니다.

레이어 추가

model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));

这为我们的网络添加了一个隐藏层。因为这是网络的第一层,所以我们需要定义我们的输入形状。输入形状是[1],因为我们有1这个数字作为输入(给定房间的房间数)。

单位(链接)设置权重矩阵在层中的大小。在这里将其设置为1,我们可以说每个数据输入特性都有一个权重。

model.add(tf.layers.dense({units: 1}));

上面的代码创建了我们的输出层。我们将单位设置为1,因为我们要输出1这个数字。

创建实例

将以下代码添加到前面定义的运行函数中。

// Create the model
const model = createModel();  
tfvis.show.modelSummary({name: &#39;Model Summary&#39;}, model);

这样可以创建实例模型,并且在网页上有显示层的摘要。

TensorFlow.js 기반 JavaScript 머신러닝

步骤4:为创建准备数据

为了获得TensorFlow.js的性能优势,使培训机器学习模型实用化,我们需要将数据转换为Tensors。

将以下代码添加到script.js文件中。

function convertToTensor(data) {

  return tf.tidy(() => {
    // Step 1\. Shuffle the data    
    tf.util.shuffle(data);
    // Step 2\. Convert data to Tensor
    const inputs = data.map(d => d.rooms)
    const labels = data.map(d => d.price);
    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).p(inputMax.sub(inputMin));
    const normalizedLabels = labelTensor.sub(labelMin).p(labelMax.sub(labelMin));
    return {
      inputs: normalizedInputs,
      labels: normalizedLabels,
      // Return the min/max bounds so we can use them later.
      inputMax,
      inputMin,
      labelMax,
      labelMin,
    }
  });  
}

接下来,我们可以分析一下将会出现什么情况。

随机播放数据

// Step 1\. Shuffle the data    
tf.util.shuffle(data);

在训练模型的过程中,数据集被分成更小的集合,每个集合称为一个批。然后将这些批次送入模型运行。整理数据很重要,因为模型不应该一次又一次地得到相同的数据。如果模型一次又一次地得到相同的数据,那么模型将无法归纳数据,并为运行期间收到的输入提供指定的输出。洗牌将有助于在每个批次中拥有各种数据。

转换为Tensor

// Step 2\. Convert data to Tensor
const inputs = data.map(d => d.rooms)
const labels = data.map(d => d.price);
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).p(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).p(labelMax.sub(labelMin));

接下来,我们规范化数据。在这里,我们使用最小-最大比例将数据规范化为数值范围0-1。规范化很重要,因为您将使用tensorflow.js构建的许多机器学习模型的内部设计都是为了使用不太大的数字。规范化数据以包括0到1或-1到1的公共范围。

返回数据和规范化界限

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

我们可以在运行期间保留用于标准化的值,这样我们就可以取消标准化输出,使其恢复到原始规模,我们就可以用同样的方式规范化未来的输入数据。

步骤5:运行模型

通过创建模型实例、将数据表示为张量,我们可以准备开始运行模型。

将以下函数复制到script.js文件中。

async function trainModel(model, inputs, labels) {
  // Prepare the model for training.  
  model.compile({
    optimizer: tf.train.adam(),
    loss: tf.losses.meanSquaredError,
    metrics: [&#39;mse&#39;],
  });

  const batchSize = 28;
  const epochs = 50;

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

我们把它分解一下。

准备运行

// Prepare the model for training.  
model.compile({
  optimizer: tf.train.adam(),
  loss: tf.losses.meanSquaredError,
  metrics: [&#39;mse&#39;],
});

我们必须在训练前“编译”模型。要做到这一点,我们必须明确一些非常重要的事情:

优化器:这是一个算法,它可以控制模型的更新,就像上面看到的例子一样。TensorFlow.js中有许多可用的优化器。这里我们选择了Adam优化器,因为它在实践中非常有效,不需要进行额外配置。

损失函数:这是一个函数,它用于检测模型所显示的每个批(数据子集)方面完成的情况如何。在这里,我们可以使用meansquaredrror将模型所做的预测与真实值进行比较。

度量:这是我们要在每个区块结束时用来计算的度量数组。我们可以用它计算整个训练集的准确度,这样我们就可以检查自己的运行结果了。这里我们使用mse,它是meansquaredrror的简写。这是我们用于损失函数的相同函数,也是回归任务中常用的函数。

const batchSize = 28;
const epochs = 50;

接下来,我们选择一个批量大小和一些时间段:

batchSize指的是模型在每次运行迭代时将看到的数据子集的大小。常见的批量大小通常在32-512之间。对于所有问题来说,并没有一个真正理想的批量大小,描述各种批量大小的精确方式这一知识点本教程没有相关讲解,对这些有兴趣可以通过别的渠道进行了解学习。

epochs指的是模型将查看你提供的整个数据集的次数。在这里,我们通过数据集进行50次迭代。

启动列车环路

return model.fit(inputs, labels, {
  batchSize,
  epochs,
  callbacks: tfvis.show.fitCallbacks(
    { name: &#39;Training Performance&#39; },
    [&#39;loss&#39;, &#39;mse&#39;], 
    { 
      height: 200, 
      callbacks: [&#39;onEpochEnd&#39;]
    }
  )
});

model.fit是我们调用的启动循环的函数。它是一个异步函数,因此我们返回它给我们的特定值,以便调用者可以确定运行结束时间。

为了监控运行进度,我们将一些回调传递给model.fit。我们使用tfvis.show.fitcallbacks生成函数,这些函数可以为前面指定的“损失”和“毫秒”度量绘制图表。

把它们放在一起

现在我们必须调用从运行函数定义的函数。

将以下代码添加到运行函数的底部。

// 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(&#39;Done Training&#39;);

刷新页面时,几秒钟后,你应该会看到图形正在更新。

这些是由我们之前创建的回调创建的。它们在每个时代结束时显示丢失(在最近的批处理上)和毫秒(在整个数据集上)。

当训练一个模型时,我们希望看到损失减少。在这种情况下,因为我们的度量是一个误差度量,所以我们希望看到它也下降。

第6步:做出预测

既然我们的模型经过了训练,我们想做一些预测。让我们通过观察它预测的低到高数量房间的统一范围来评估模型。

将以下函数添加到script.js文件中

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.rooms, y: d.price,
  }));

  tfvis.render.scatterplot(
    {name: &#39;Model Predictions vs Original Data&#39;}, 
    {values: [originalPoints, predictedPoints], series: [&#39;original&#39;, &#39;predicted&#39;]}, 
    {
      xLabel: &#39;No. of rooms&#39;,
      yLabel: &#39;Price&#39;,
      height: 300
    }
  );
}

在上面的函数中需要注意的一些事情。

const xs = tf.linspace(0, 1, 100);      
const preds = model.predict(xs.reshape([100, 1]));

我们生成100个新的“示例”以提供给模型。model.predict是我们如何将这些示例输入到模型中的。注意,他们需要有一个类似的形状([num_的例子,num_的特点每个_的例子])当我们做培训时。

// Un-normalize the data
const unNormXs = xs
  .mul(inputMax.sub(inputMin))
  .add(inputMin);

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

为了将数据恢复到原始范围(而不是0–1),我们使用规范化时计算的值,但只需反转操作。

return [unNormXs.dataSync(), unNormPreds.dataSync()];

.datasync()是一种方法,我们可以使用它来获取存储在张量中的值的typedarray。这允许我们在常规的javascript中处理这些值。这是通常首选的.data()方法的同步版本。

最后,我们使用tfjs-vis来绘制原始数据和模型中的预测。

将以下代码添加到运行函数中。

testModel(model, data, tensorData);

刷新页面,现在已经完成啦!

现在你已经学会使用tensorflow.js创建一个简单的机器学习模型了。

相关教程:JavaScript视频教程

위 내용은 TensorFlow.js 기반 JavaScript 머신러닝의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
이전 기사:Vuex가 뭐야?다음 기사:Vuex가 뭐야?