1use crate::value::Value;
2
3use rand::{thread_rng, Rng};
4
5#[derive(Clone)]
6pub struct Neuron {
7 weights: Vec<Value>,
8 bias: Value,
9}
10
11impl Neuron {
12 pub fn new(input_count: usize) -> Neuron {
13 let mut rng = thread_rng();
14 let mut rand_value_fn = || {
15 let data = rng.gen_range(-1.0..1.0);
16 Value::from(data)
17 };
18
19 let mut weights = Vec::new();
20 for _ in 0..input_count {
21 weights.push(rand_value_fn());
22 }
23
24 Neuron {
25 weights,
26 bias: rand_value_fn().with_label("b"),
27 }
28 }
29
30 pub fn forward(&self, xs: &Vec<Value>) -> Value {
31 let products = std::iter::zip(&self.weights, xs)
32 .map(|(a, b)| a * b)
33 .collect::<Vec<Value>>();
34
35 let sum = self.bias.clone() + products.into_iter().reduce(|acc, prd| acc + prd).unwrap();
36 sum.tanh()
37 }
38
39 pub fn parameters(&self) -> Vec<Value> {
40 [self.bias.clone()]
41 .into_iter()
42 .chain(self.weights.clone())
43 .collect()
44 }
45}