1pub mod tensor;
2pub mod neural_networks;
3
4use crate::tensor::Tensor2D;
5use crate::neural_networks::NeuralNetwork;
6
7use std::fs;
8
9pub fn current_millis() -> u128 {
10 std::time::SystemTime::now()
11 .duration_since(std::time::SystemTime::UNIX_EPOCH)
12 .unwrap()
13 .as_millis()
14}
15
16pub fn read_csv(
17 filename: &str,
18 input_size: usize,
19 output_size: usize,
20) -> (Vec<Tensor2D>, Vec<Tensor2D>) {
21 let mut inputs = Vec::new();
22 let mut labels = Vec::new();
23 let content = fs::read_to_string(filename).expect("Error opening file");
24 let lines: Vec<&str> = content.lines().collect();
25 for idx in 0..lines.len() {
26 let line = lines[idx];
27 let values: Vec<&str> = line.split(",").collect();
28 let mut input = Tensor2D::new(input_size, 1);
29 let mut label = Tensor2D::new(output_size, 1);
30 for value_index in 0..values.len() {
31 if value_index < input_size {
32 input[value_index][0] = values[value_index].parse::<f32>().unwrap();
33 } else {
34 label[value_index - input_size][0] =
35 values[value_index].parse::<f32>().unwrap();
36 }
37 }
38 inputs.push(input);
39 labels.push(label);
40 }
41 (inputs, labels)
42}
43
44pub fn get_accuracy(nn: &NeuralNetwork, filename: &str) -> f32 {
45 let (inputs, labels) = read_csv(filename, nn.input_nodes, nn.output_nodes);
46 let mut count: usize = 0;
47 for i in 0..inputs.len() {
48 if nn.predict(&inputs[i]).index_of_max() == labels[i].index_of_max() {
49 count += 1;
50 }
51 }
52 count as f32 / inputs.len() as f32
53}
54
55pub fn train(nn: &mut NeuralNetwork, filename: &str, num_epochs: u32) {
56 let (inputs, labels) = read_csv(filename, nn.input_nodes, nn.output_nodes);
57 let ts = current_millis();
58 println!("Training started ...");
59 for i in 0..num_epochs {
60 for j in 0..inputs.len() {
61 nn.train_one_epoch(&inputs[j], &labels[j]);
62 }
63 println!("Epoch [{} / {}] completed.", i + 1, num_epochs);
64 }
65 let tt = (current_millis() - ts) as f32 / 1000 as f32;
66 println!("Training time: {}s", tt);
67}