简体   繁体   English

如何提高前馈神经网络的准确性?

[英]How to improve accuracy of a FeedForward Neural Network?

I want to draw StackOverflow's logo with this Neural Network:我想用这个神经网络绘制 StackOverflow 的标志:

在此处输入图像描述

The NN should ideally become [r, g, b] = f([x, y]) . NN 理想情况下应变为[r, g, b] = f([x, y]) In other words, it should return RGB colors for a given pair of coordinates.换句话说,对于给定的一对坐标,它应该返回 RGB colors。 The FFNN works pretty well for simple shapes like a circle or a box. FFNN 非常适合简单的形状,例如圆形或盒子。 For example after several thousands epochs a circle looks like this:例如,在几千个时代之后,一个圆圈看起来像这样:

在此处输入图像描述

Try it yourself: https://codepen.io/adelriosantiago/pen/PoNGeLw自己试试: https://codepen.io/adelriosantiago/pen/PoNGeLw


However since StackOverflow's logo is far more complex even after several thousands of iterations the FFNN's results are somewhat poor:然而,由于 StackOverflow 的徽标即使经过数千次迭代也要复杂得多,因此 FFNN 的结果有些差:

在此处输入图像描述

From left to right:从左到右:

  1. StackOverflow's logo at 256 colors. StackOverflow 的徽标位于 256 colors。
  2. With 15 hidden neurons: The left handle never appears.有 15 个隐藏神经元:左手柄永远不会出现。
  3. 50 hidden neurons: Pretty poor result in general. 50 个隐藏神经元:总的来说结果很差。
  4. 0.03 as learning rate: Shows blue in the results (blue is not in the orignal image) 0.03 作为学习率:在结果中显示蓝色(蓝色不在原始图像中)
  5. A time-decreasing learning rate: The left handle appears but other details are now lost.随时间递减的学习率:左手柄出现,但其他细节现在丢失了。

Try it yourself: https://codepen.io/adelriosantiago/pen/xxVEjeJ自己尝试一下: https://codepen.io/adelriosantiago/pen/xxVEjeJ

Some parameters of interest are synaptic.Architect.Perceptron definition and learningRate value.一些感兴趣的参数是synaptic.Architect.Perceptron定义和learningRate值。


How can I improve the accuracy of this NN?我怎样才能提高这个神经网络的准确性?

Could you improve the snippet?你能改进这个片段吗? If so, please explain what you did.如果是这样,请解释你做了什么。 If there is a better NN architecture to tackle this type of job could you please provide an example?如果有更好的神经网络架构来处理这类工作,您能举个例子吗?

Additional info:附加信息:

By adding another layer, you get better results:通过添加另一层,您可以获得更好的结果:

let perceptron = new synaptic.Architect.Perceptron(2, 15, 10, 3)

1000 次迭代 2000 次迭代

There are small improvements that you can do to improve efficiency (marginally): Here is my optimized code:您可以做一些小的改进来提高效率(略微):这是我优化的代码:

const width = 125
const height = 125
const outputCtx = document.getElementById("output").getContext("2d")
const iterationLabel = document.getElementById("iteration")
const stopAtIteration = 3000
let perceptron = new synaptic.Architect.Perceptron(2, 15, 10, 3)
let iteration = 0

let inputData = (() => {
  const tempCtx = document.createElement("canvas").getContext("2d")
  tempCtx.drawImage(document.getElementById("input"), 0, 0)
  return tempCtx.getImageData(0, 0, width, height)
})()

const getRGB = (img, x, y) => {
  var k = (height * y + x) * 4;
  return [
    img.data[k] / 255, // R
    img.data[k + 1] / 255, // G
    img.data[k + 2] / 255, // B
    //img.data[(height * y + x) * 4 + 3], // Alpha not used
  ]
}
const paint = () => {
  var imageData = outputCtx.getImageData(0, 0, width, height)
  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      var rgb = perceptron.activate([x / width, y / height])
      var k = (height * y + x) * 4;
      imageData.data[k] = rgb[0] * 255
      imageData.data[k + 1] = rgb[1] * 255
      imageData.data[k + 2] = rgb[2] * 255
      imageData.data[k + 3] = 255 // Alpha not used
    }
  }
  outputCtx.putImageData(imageData, 0, 0)

  setTimeout(train, 0)
}

const train = () => {
  iterationLabel.innerHTML = ++iteration

  if (iteration > stopAtIteration) return

  let learningRate = 0.01 / (1 + 0.0005 * iteration) // Attempt with dynamic learning rate
  //let learningRate = 0.01 // Attempt with non-dynamic learning rate
      
  for (let x = 0; x < width; x += 1) {
    for (let y = 0; y < height; y += 1) {
      perceptron.activate([x / width, y / height])
      perceptron.propagate(learningRate, getRGB(inputData, x, y))
    }
  }
  paint()
}

const startTraining = (btn) => {
  btn.disabled = true
  train()
}

EDIT: I made another CodePen with even better results:编辑:我制作了另一个 CodePen,结果更好:

在此处输入图像描述

https://codepen.io/xurei/pen/KKzWLxg https://codepen.io/xurei/pen/KKzWLxg

It is likely to be over-fitted BTW.顺便说一句,它很可能是过度拟合的。 The perceptron definition:感知器定义:

let perceptron = new synaptic.Architect.Perceptron(2, 8, 15, 7, 3)

Taking some insights from the lecture/ slides of Bhiksha Raj (from slides 62 onwards), and summarizing as below:从 Bhiksha Raj 的讲座/ 幻灯片(从幻灯片 62 开始)中获取一些见解,并总结如下:

Each node can be assumed like a linear classifier, and combination of several nodes in a single layer of neural.networks can approximate any basic shapes.每个节点都可以假设为线性分类器,单层神经网络中多个节点的组合可以近似任何基本形状。 For example, a rectangle can be formed by 4 nodes for each lines, assuming each nodes contributes to one line, and the shape can be approximated by the final output layer.例如,一个矩形可以由每条线的 4 个节点组成,假设每个节点都贡献一条线,并且形状可以由最终的 output 层近似。

Falling back to the summary of complex shapes such as circle, it may require infinite nodes in a layer.回溯到圆形等复杂形状的总结,可能需要一层有无限个节点。 Or this would likely hold true for a single layer with two disjoint shapes (A non-overlapping triangle and rectangle).或者这可能适用于具有两个不相交形状(不重叠的三角形和矩形)的单层。 However, this can still be learnt using more than 1 hidden layers.然而,这仍然可以通过使用多于 1 个隐藏层来学习。 Where, the 1st layer learns the basic shapes, followed by 2nd layer approximating their disjoint combinations.其中,第一层学习基本形状,然后第二层学习它们的不相交组合。

Thus, you can assume that this logo is combination of disjoint rectangles (5 rectangles for orange and 3 rectangles for grey).因此,您可以假设此徽标是不相交矩形的组合(橙色为 5 个矩形,灰色为 3 个矩形)。 We can use atleast 32 nodes in 1st hidden layer and few nodes in the 2nd hidden layer.我们可以在第一个隐藏层中使用至少 32 个节点,在第二个隐藏层中使用少量节点。 However, we don't have control over what each node learns.但是,我们无法控制每个节点学习的内容。 Hence, a few more number of neurons than required neurons should be helpful.因此,比所需神经元多一些的神经元应该是有帮助的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM