首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >随机学习神经元作为信号计数器

随机学习神经元作为信号计数器
EN

Code Review用户
提问于 2015-07-30 14:47:48
回答 1查看 131关注 0票数 2

我有一个学习人工神经元作为一个简单信号计数器的小程序:我的细胞有四根输入线(也称为树突)和一条输出线(也称为轴突)。如果至少有两个输入信号足够强,轴突就被激活。我认为神经元一旦连续“猜测”出了足够多的输出,就会被学习。

Neuron.java

代码语言:javascript
复制
package net.coderodde.ai.neural;

import java.util.Objects;

/**
 * This class models artificial neurons.
 * 
 * @author Rodion "rodde" Efremov
 */
public class Neuron {

    private final float[] dendriteWeightArray;
    private TransitionFunction transitionFunction;

    public Neuron(int dendriteAmount) {
        this.dendriteWeightArray = new float[dendriteAmount];
    }

    public float getDendriteWeight(int dendriteIndex) {
        checkDendriteIndex(dendriteIndex);
        return dendriteWeightArray[dendriteIndex];
    }

    public void setDendriteWeight(int dendriteIndex, float weight) {
        checkDendriteIndex(dendriteIndex);
        checkIsFinite(weight);
        dendriteWeightArray[dendriteIndex] = weight;
    }

    public void setTransitionFunction(TransitionFunction transitionFunction) {
        Objects.requireNonNull(transitionFunction, 
                               "The input transition function is null.");
        this.transitionFunction = transitionFunction;
    }

    public float process(float... input) {
        float sum = 0.0f;

        for (int i = 0; i < Math.min(input.length,
                                     dendriteWeightArray.length); ++i) {
            sum += input[i] * dendriteWeightArray[i];
        }

        return transitionFunction.process(sum);
    }

    public int getDendriteCount() {
        return dendriteWeightArray.length;
    }

    private void checkDendriteIndex(int index) {
        if (index < 0) {
            throw new IndexOutOfBoundsException(
                    "The dendrite index is negative: " + index);
        }

        if (index >= dendriteWeightArray.length) {
            throw new IndexOutOfBoundsException(
                    "The dendrite index is too large: " + index + ", the " +
                    "amount of dendrites: " + dendriteWeightArray.length);
        }
    }

    private static void checkIsFinite(float f) {
        if (Float.isNaN(f)) {
            throw new IllegalArgumentException("The value is NaN.");
        }

        if (Float.isInfinite(f)) {
            throw new IllegalArgumentException(
                    "The value is infinite in absolute value: " + f);
        }
    }
}

TransitionFunction.java

代码语言:javascript
复制
package net.coderodde.ai.neural;

/**
 * This interface defines the API for a transition function in artificial 
 * neurons.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6
 */
@FunctionalInterface
public interface TransitionFunction {

    /**
     * Maps the input signal to output.
     * 
     * @param input the input signal.
     * @return the output signal. 
     */
    public float process(float input);
}

NeuronLearner.java

代码语言:javascript
复制
package net.coderodde.ai.neural;

/**
 * This class defines the API for neuron learning routines.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6
 */
public interface NeuronLearner {

    /**
     * The actual learning method.
     * 
     * @param neuron the neuron to learn.
     */
    public void learn(Neuron neuron);
}

RandomNeuronLearner.java

代码语言:javascript
复制
package net.coderodde.ai.neural;

import java.util.Random;

/**
 * This class implements fully random neuron learner routine.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6
 */
public class RandomNeuronLearner implements NeuronLearner {

    private final Random random;

    public RandomNeuronLearner(Random random) {
        this.random = random;
    }

    @Override
    public void learn(Neuron neuron) {
        int dendriteCount = neuron.getDendriteCount();

        for (int i = 0; i < dendriteCount; ++i) {
            neuron.setDendriteWeight(i, 2.0f * random.nextFloat() - 1.0f);
        }

        float min = random.nextFloat();

        neuron.setTransitionFunction((f) -> {
            return f > min ? 1.0f : 0.f;
        });
    }
}

Demo.java

代码语言:javascript
复制
package net.coderodde.ai.neural;

import java.util.Random;

public class Demo {

    private static final int MINIMUM_MATCHES = 50;

    public static void main(String[] args) {
        // This demonstration learns a neuron with four dendrites to act as a
        // "counter": if at least two dendrites receive a signal strong 
        // enough, the axon must be activated.
        Neuron neuron = new Neuron(4);
        Random random = new Random();
        NeuronLearner learner = new RandomNeuronLearner(new Random());

        long ta = System.currentTimeMillis();

        outer:
        for (;;) {
            learner.learn(neuron);

            for (int i = 0; i < MINIMUM_MATCHES; ++i) {
                float[] signal = getRandomSignal(neuron.getDendriteCount(), 
                                                 random);

                if (signalShouldPass(signal) != signalPasses(neuron.process(signal))) {
                    continue outer;
                }
            }

            break;
        }

        long tb = System.currentTimeMillis();

        System.out.println("The neuron learned in " + (tb - ta) + 
                           " milliseconds.");
    }

    /**
     * Generates a random signal.
     * 
     * @param size   the amount of dendrites of a neuron receiving the signal.
     * @param random the random number generator.
     * @return a random signal.
     */
    private static float[] getRandomSignal(int size, Random random) {
        float[] ret = new float[size];

        for (int i = 0; i < size; ++i) {
            ret[i] = random.nextFloat();
        }

        return ret;
    }

    /**
     * Checks whether the input signal should activate the axon.
     * 
     * @param signal the signal to check.
     * @return {@code true} if the input signal should activate the axon.
     */
    private static boolean signalShouldPass(float[] signal) {
        int count = 0;

        for (float f : signal) {
            if (f > 0.5) {
                count++;
            }
        }

        return count >= 2;
    }

    /**
     * Check whether the axon was activated.
     * 
     * @param output the output of the axon.
     * @return {@code true} if the axon was activated.
     */
    private static boolean signalPasses(float output) {
        return output > 0.7f;
    }
}

我得到了这样的东西:

神经元在307毫秒内学习。

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-07-31 06:49:05

并没有真正的工作

我不喜欢这个程序的概念,因为从数学上讲,你的神经网络实际上不能产生你想要达到的正确结果。

目前的神经网络太原始,无法计算所需的函数。它简单地总结了四个加权输入,并与一个截止值进行了比较,这意味着它所能做的最好的就是做一个相当于:

代码语言:javascript
复制
return (a+b+c+d > X) ? 1.0f : 0.0f;

因此,如果您尝试了这样的测试用例(通过排列):

代码语言:javascript
复制
(0,0,0.5,0.5)       <-- Tests minimum succeeding case
(1,0.49,0.49,0.49)  <-- Tests maximum failing case

你会发现没有一个神经网络能够通过每一个边缘的案例测试。实际上,你的程序所做的就是找到一个可以通过50个随机测试用例的神经网络,这意味着随机测试用例不一定是一个很好的成功判断。

从理论的角度来看,我认为你的神经网络至少需要两层。如果神经网络真的“学习”,而不是在失败时随机分配新的权重,那就更有趣了。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/98592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档