use rand::Rng;
use rustorch::nn::Linear;
use rustorch::prelude::*;
use rustorch::utils::mse_loss;
fn generate_data(n_samples: usize, n_features: usize) -> (Vec<f32>, Vec<f32>) {
let mut rng = rand::thread_rng();
let x_data: Vec<f32> = (0..n_samples * n_features)
.map(|_| rng.gen_range(-1.0..1.0))
.collect();
let true_weights: Vec<f32> = (0..n_features).map(|_| rng.gen_range(-1.0..1.0)).collect();
let mut y_data = Vec::with_capacity(n_samples);
for i in 0..n_samples {
let mut y = 0.0;
for j in 0..n_features {
y += x_data[i * n_features + j] * true_weights[j];
}
y += rng.gen_range(-0.1..0.1);
y_data.push(y);
}
(x_data, y_data)
}
fn main() {
let n_samples = 100;
let n_features = 3;
let (x_data, y_data) = generate_data(n_samples, n_features);
let x_tensor = Tensor::from_vec(x_data, vec![n_samples, n_features]);
let y_tensor = Tensor::from_vec(y_data, vec![n_samples, 1]);
let x_var = Variable::new(x_tensor, false);
let y_var = Variable::new(y_tensor, false);
let model = Linear::new(n_features, 1);
let n_epochs = 10;
println!("Starting training...");
for epoch in 0..n_epochs {
let output = model.forward(&x_var);
let output_binding = output.data();
let output_data = output_binding.read().unwrap();
let y_binding = y_var.data();
let y_data = y_binding.read().unwrap();
let loss = mse_loss(output_data.as_array(), y_data.as_array());
println!("Epoch {}: Loss = {:.6}", epoch, loss);
}
println!("Training completed!");
}