如何提高前馈神经网络的准确性?
Posted
技术标签:
【中文标题】如何提高前馈神经网络的准确性?【英文标题】:How to improve accuracy of a FeedForward Neural Network? 【发布时间】:2020-12-09 04:40:36 【问题描述】:我想用这个神经网络绘制 *** 的标志:
NN 应该理想地变为 [r, g, b] = f([x, y])。换句话说,它应该返回给定坐标对的 RGB 颜色。 FFNN 非常适用于圆形或盒子等简单形状。例如,在几千个 epoch 之后,一个圆看起来像这样:
自己试试吧:https://codepen.io/adelriosantiago/pen/PoNGeLw
但是,由于 *** 的徽标要复杂得多,即使经过数千次迭代,FFNN 的结果也有些差:
从左到右:
-
*** 的 256 色徽标。
有 15 个隐藏神经元:左手柄永远不会出现。
50 个隐藏神经元:总体上效果很差。
0.03 作为学习率:在结果中显示为蓝色(原始图像中没有蓝色)
学习率随时间递减:左侧手柄出现,但其他细节现在丢失。
自己试试吧:https://codepen.io/adelriosantiago/pen/xxVEjeJ
一些感兴趣的参数是synaptic.Architect.Perceptron
定义和learningRate
值。
如何提高此 NN 的准确性?
你能改进sn-p吗?如果是这样,请解释你做了什么。如果有更好的神经网络架构来解决这类工作,您能否提供一个示例?
附加信息:
使用的人工神经网络库:Synaptic.js 要在本地主机中运行此示例:See repository【问题讨论】:
【参考方案1】:通过添加另一层,您可以获得更好的结果:
let perceptron = new synaptic.Architect.Perceptron(2, 15, 10, 3)
您可以做一些小的改进来提高效率(略微): 这是我的优化代码:
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()
编辑:我制作了另一个 CodePen,效果更好:
https://codepen.io/xurei/pen/KKzWLxg
顺便说一句,它很可能是过度拟合的。 感知器定义:
let perceptron = new synaptic.Architect.Perceptron(2, 8, 15, 7, 3)
【讨论】:
您可以尝试的另一件事是使用 RGB 以外的其他东西。我相信 Lab* 或 HSV 颜色空间可能效果更好。 另外,您的误差函数目前是线性的。我的直觉是,均方误差也可能会更好。 谢谢!结果看起来还不错。赏金时间已过,我决定将其奖励给你。我唯一真正想知道的是新价值观背后的原因。基本上如何选择合适的?运气?谢谢! 感谢您的奖励,非常感谢 :-) 回答您的问题:运气和经验的组合。基本上,只有一层的感知器就像一个线性聚类算法(即它可以定义一个分隔空间的平面)。每个额外的层都允许 NN 将输入转换为另一种更容易线性分割的形式。基于此,我的想法是“图像太复杂而无法线性分离,让我们尝试额外的层”。检查内核技巧以获取更多理论:en.wikipedia.org/wiki/Kernel_method.【参考方案2】:从 Bhiksha Raj 的讲座/slides(从幻灯片 62 开始)中获得一些见解,总结如下:
可以假设每个节点都像一个线性分类器,在单层神经网络中多个节点的组合可以逼近任何基本形状。例如,一个矩形可以由每条线的4个节点组成,假设每个节点对一条线有贡献,并且形状可以由最终的输出层来近似。
回到圆形等复杂形状的总结,它可能需要一层中的无限节点。或者这可能适用于具有两个不相交形状(非重叠三角形和矩形)的单层。但是,这仍然可以使用超过 1 个隐藏层来学习。其中,第 1 层学习基本形状,然后第 2 层近似它们的不相交组合。
因此,您可以假设此徽标是不相交的矩形组合(5 个橙色矩形和 3 个灰色矩形)。我们可以在第一个隐藏层中使用至少 32 个节点,在第二个隐藏层中使用几个节点。但是,我们无法控制每个节点学习的内容。因此,比所需神经元多一些神经元应该是有帮助的。
【讨论】:
以上是关于如何提高前馈神经网络的准确性?的主要内容,如果未能解决你的问题,请参考以下文章
如何评估/提高来自具有不平衡数据集的神经网络的预测的准确性?
使用Python,Keras和TensorFlow训练第一个CNN