transfer_learning/
transfer_learning.rs1#![allow(
2 clippy::pedantic,
3 clippy::unnecessary_wraps,
4 clippy::needless_range_loop,
5 clippy::useless_vec,
6 clippy::needless_collect,
7 clippy::too_many_arguments
8)]
9use quantrs2_ml::autodiff::optimizers::Adam;
15use quantrs2_ml::prelude::*;
16use quantrs2_ml::qnn::QNNLayerType;
17use scirs2_core::ndarray::{Array1, Array2};
18
19fn main() -> Result<()> {
20 println!("=== Quantum Transfer Learning Demo ===\n");
21
22 println!("1. Loading pre-trained image classifier...");
24 let pretrained = QuantumModelZoo::get_image_classifier()?;
25
26 println!(" Pre-trained model info:");
27 println!(" - Task: {}", pretrained.task_description);
28 println!(
29 " - Original accuracy: {:.2}%",
30 pretrained
31 .performance_metrics
32 .get("accuracy")
33 .unwrap_or(&0.0)
34 * 100.0
35 );
36 println!(" - Number of qubits: {}", pretrained.qnn.num_qubits);
37
38 println!("\n2. Creating new layers for text classification task...");
40 let new_layers = vec![
41 QNNLayerType::VariationalLayer { num_params: 6 },
42 QNNLayerType::MeasurementLayer {
43 measurement_basis: "Pauli-Z".to_string(),
44 },
45 ];
46
47 println!("\n3. Testing different transfer learning strategies:");
49
50 println!("\n a) Fine-tuning strategy (train last 2 layers only)");
52 let mut transfer_finetune = QuantumTransferLearning::new(
53 pretrained.clone(),
54 new_layers.clone(),
55 TransferStrategy::FineTuning {
56 num_trainable_layers: 2,
57 },
58 )?;
59
60 println!(" b) Feature extraction strategy (freeze all pre-trained layers)");
62 let transfer_feature = QuantumTransferLearning::new(
63 pretrained.clone(),
64 new_layers.clone(),
65 TransferStrategy::FeatureExtraction,
66 )?;
67
68 println!(" c) Progressive unfreezing (unfreeze one layer every 5 epochs)");
70 let transfer_progressive = QuantumTransferLearning::new(
71 pretrained,
72 new_layers,
73 TransferStrategy::ProgressiveUnfreezing { unfreeze_rate: 5 },
74 )?;
75
76 println!("\n4. Generating synthetic training data...");
78 let num_samples = 50;
79 let num_features = 4;
80 let training_data = Array2::from_shape_fn((num_samples, num_features), |(i, j)| {
81 (i as f64).mul_add(0.1, j as f64 * 0.2).sin()
82 });
83 let labels = Array1::from_shape_fn(num_samples, |i| if i % 2 == 0 { 0.0 } else { 1.0 });
84
85 println!("\n5. Training with fine-tuning strategy...");
87 let mut optimizer = Adam::new(0.01);
88
89 let result = transfer_finetune.train(
90 &training_data,
91 &labels,
92 &mut optimizer,
93 20, 10, )?;
96
97 println!(" Training complete!");
98 println!(" - Final loss: {:.4}", result.final_loss);
99 println!(" - Accuracy: {:.2}%", result.accuracy * 100.0);
100
101 println!("\n6. Extracting features from pre-trained layers...");
103 let features = transfer_feature.extract_features(&training_data)?;
104 println!(" Extracted feature dimensions: {:?}", features.dim());
105
106 println!("\n7. Available pre-trained models in the zoo:");
108 println!(" - Image classifier (4 qubits, MNIST subset)");
109 println!(" - Chemistry model (6 qubits, molecular energy)");
110
111 let chemistry_model = QuantumModelZoo::get_chemistry_model()?;
113 println!("\n Chemistry model info:");
114 println!(" - Task: {}", chemistry_model.task_description);
115 println!(
116 " - MAE: {:.4}",
117 chemistry_model
118 .performance_metrics
119 .get("mae")
120 .unwrap_or(&0.0)
121 );
122 println!(
123 " - R² score: {:.4}",
124 chemistry_model
125 .performance_metrics
126 .get("r2_score")
127 .unwrap_or(&0.0)
128 );
129
130 println!("\n=== Transfer Learning Demo Complete ===");
131
132 Ok(())
133}
134
135fn print_layer_configs(configs: &[LayerConfig]) {
137 for (i, config) in configs.iter().enumerate() {
138 println!(
139 " Layer {}: frozen={}, lr_multiplier={:.2}",
140 i, config.frozen, config.learning_rate_multiplier
141 );
142 }
143}