我想使用此神经网络绘制StackOverflow的徽标:
理想情况下,NN应该变为 [r,g,b] = f([x,y])。换句话说,它应该为给定的一对坐标返回RGB颜色。 FFNN非常适合简单的形状,例如圆形或盒子。例如,在数千个纪元之后,一个圆圈看起来像这样:
自己尝试:https://codepen.io/adelriosantiago/pen/PoNGeLw
但是,由于即使经过数千次迭代,StackOverflow的徽标也要复杂得多,所以FFNN的结果有些差:
从左到右:
自己尝试:https://codepen.io/adelriosantiago/pen/xxVEjeJ
一些令人感兴趣的参数是synaptic.Architect.Perceptron
的定义和learningRate
的值。
您可以改善摘要吗?如果是这样,请说明您做了什么。如果有更好的NN体系结构来解决此类工作,您可以举个例子吗?
其他信息:
答案 0 :(得分:7)
通过添加另一层,您可以获得更好的结果:
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
BTW可能过拟合。 感知器定义:
let perceptron = new synaptic.Architect.Perceptron(2, 8, 15, 7, 3)
答案 1 :(得分:1)
从比克莎·拉吉(Bhiksha Raj)的演讲/ slides中获得一些见解(从幻灯片62开始),并总结如下:
可以像线性分类器那样假设每个节点,并且在神经网络的单层中多个节点的组合可以近似任何基本形状。例如,假设每个节点对一条线有贡献,则矩形可以由每条线的4个节点组成,并且形状可以由最终输出层近似。回到复杂形状(例如圆形)的摘要,它可能需要一层中的无限个节点。否则,对于具有两个不相交形状(非重叠三角形和矩形)的单层来说,这可能适用。但是,仍然可以使用多个隐藏层来学习。在那里,第一层学习基本形状,第二层学习它们的不相交组合。
因此,您可以假定此徽标是不相交的矩形的组合(橙色为5个矩形,灰色为3个矩形)。我们可以在第一个隐藏层中使用至少32个节点,在第二个隐藏层中使用几个节点。但是,我们无法控制每个节点的学习内容。因此,比所需神经元多一些的神经元应该会有所帮助。