美文网首页一些需要知道的概念
用代码来模拟“神经元”和“条件反射”

用代码来模拟“神经元”和“条件反射”

作者: JiaYe | 来源:发表于2018-02-08 18:32 被阅读0次

参考巴甫洛夫的经典条件反射。
在给狗狗喂食时,狗狗嘴里产生唾液。如果在喂食的同时摇响铃铛,并经过多次训练,就会形成条件反射,不喂食摇响铃铛也会产生唾液。下面用一段简单的代码——“神经元”,来模拟一下条件反射过程。
神经元由树突、细胞、轴突组成,研究发现,相连接神经在同步放电后突触连接增强。我们通过修改树突的权重,来模拟连接增强:
狗吃东西流口水,属于先天非条件反射。狗听到铃铛流口水,属于后天训练的条件反射。假设有一个神经元,A树突连接到食物,B树突连接到铃铛。那么A树突的权重默认为1.0,代表非条件反射,树突有输入的时候就会激活唾液。B树突默认权重0.0,代表条件反射,树突有输入时不会激活唾液。我们就在两个树突同时有输入时,将其中较低的权重不断增加,来模拟训练过程。

struct Neuron<T:Axon>{
    dendrite_wieghts: Vec<f32>,
    dendrite_values: Vec<f32>,
    axon: T
}

以上代码是一个神经元的结构体,其中,dendrite_wieghts是神经元树突,dendrite_values是神经元的树突的输入值。axon是个接口,用来接收神经元输出。

impl <T:Axon> Neuron<T>{
    fn set_dendrites(&mut self, values: &[f32]){
        self.dendrite_values.copy_from_slice(values);
        self.execute();
    }

    fn execute(&mut self){
        let mut total = 0.0;
        let mut max_weight = 0.0;
        //加权求和
        for d in 0..self.dendrite_wieghts.len(){
            total += self.dendrite_values[d]*self.dendrite_wieghts[d];
            if self.dendrite_wieghts[d]>max_weight{
                max_weight = self.dendrite_wieghts[d];
            }
        }

        //调整权重: 如果有N个树突都有输入,那么调整他们的权重,直到同一水平
        for d in 0..self.dendrite_wieghts.len(){
            if self.dendrite_values[d]!=0.0 && self.dendrite_wieghts[d]<max_weight && self.dendrite_wieghts[d]<1.0{
                self.dendrite_wieghts[d] += 0.1;
            }
        }
        self.axon.output(total);
    }
}

神经元有两个方法,set_dendrites用来设置所有突触接收到的值。execute方法用来求所有突触的加权和,此方法会在set_dendrites调用之后自动触发,然后通知轴突(axon)回调,这相当于动物神经元树突受到刺激后激活轴突。

//轴突
trait Axon{
    fn output(&self, o:f32);
}
//实现一个监听是否有唾液的接口
struct SalivaAxon{}
impl Axon for SalivaAxon{
    fn output(&self, output:f32){
        //println!("output:{}", output);
        if output >= 1.0{
            println!("有唾液!");
        }else{
            println!("无唾液!!");
        }
    }
}

以上代码是接口回调。
下面的main函数开始模拟条件反射:

fn main() {
    let mut neuron = Neuron{
        //两个突触 连接到食物(舌头)的权重1.0 连接到铃铛(耳朵)的权重0.0
        dendrite_wieghts: vec![1.0, 0.0], 
        dendrite_values: vec![0.0, 0.0],
        axon: SalivaAxon{}
    };

    neuron.set_dendrites(&[1.0, 0.0]); //第一次: 吃+不响铃->有唾液
    neuron.set_dendrites(&[1.0, 1.0]); //第二次: 吃+响铃->有唾液
    neuron.set_dendrites(&[0.0, 1.0]); //第三次: 不吃+响铃->无唾液
    //再训练9次就学会条件反射
    for _ in 0..9{
        neuron.set_dendrites(&[1.0, 1.0]);
    }
    //测试训练好的条件反射
    neuron.set_dendrites(&[0.0, 1.0]);  // 不吃+响铃 ***有唾液***
}

运行结果输出如下:
有唾液!
有唾液!
无唾液!!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!
有唾液!

可以发现,经过训练以后,最后一次只输入铃铛,仍然会激发唾液。

当然大脑的思维和记忆是由千万亿的神经细胞呈现的,这里只是一段有趣的代码来模仿一下。如果将更多的神经元链接到一起,会有什么神奇的结果吗?
待续。。。

(原创文章)
2018年2月8日 上海
planet2@qq.com

相关文章

网友评论

    本文标题:用代码来模拟“神经元”和“条件反射”

    本文链接:https://www.haomeiwen.com/subject/pzgttftx.html