use candle_core::Device;
use candle_core::Tensor;
use super::*;
fn vocab(words: &[&str]) -> Vocab {
let entries: Vec<String> = words.iter().map(|w| format!("{w:?}")).collect();
let json = format!(
r#"{{"vocab": [{}], "stem_mapping": {{}}}}"#,
entries.join(", ")
);
Vocab::parse(&json).unwrap()
}
fn stopwords(words: &[&str]) -> Stopwords {
Stopwords::parse(&words.join("\n"))
}
fn token_text(tokens: &[&str]) -> Vec<String> {
tokens.iter().map(|t| t.to_string()).collect()
}
#[test]
fn a_single_recognized_word_end_to_end() {
let vocab = vocab(&["cat"]);
let stopwords = stopwords(&[]);
let tokens = token_text(&["cat"]);
let matrix = Tensor::from_vec(
vec![
0f32, 0., 0., 0., 0., 0., 0., 0., 1.0, -1.0, 0.5, 0.3, 0., 0., 0., 0.,
],
(2, 2, 4),
&Device::Cpu,
)
.unwrap();
let hidden_row = vec![vec![1.0f32, 0.0]];
let embedding = pooling::pool_row(
&hidden_row,
&[0],
&tokens,
&vocab,
&stopwords,
&matrix,
false,
)
.unwrap();
let t0 = 1.0f32.tanh();
let t1 = (-1.0f32).tanh();
let t2 = 0.5f32.tanh();
let t3 = 0.3f32.tanh();
let norm = (t0 * t0 + t1 * t1 + t2 * t2 + t3 * t3).sqrt();
let tf = 1.0 * (1.2 + 1.0) / (1.0 + 1.2 * (1.0 - 0.75 + 0.75 * 1.0 / 150.0));
assert_eq!(
embedding.indices,
vec![
index::dense_index(1, 0),
index::dense_index(1, 1),
index::dense_index(1, 2),
index::dense_index(1, 3),
]
);
let expected = [
t0 / norm * tf,
t1 / norm * tf,
t2 / norm * tf,
t3 / norm * tf,
];
for (got, want) in embedding.values.iter().zip(expected) {
assert!((got - want).abs() < 1e-5, "{got} vs {want}");
}
}
#[test]
fn two_occurrences_of_the_same_word_exercise_averaging_and_term_frequency() {
let vocab = vocab(&["cat"]);
let stopwords = stopwords(&[]);
let tokens = token_text(&["cat"]);
let matrix = Tensor::from_vec(
vec![
0f32, 0., 0., 0., 0., 0., 0., 0., 3.0, 1.0, -1.0, 2.0, 1.0, -1.0, 1.0, 0.0,
],
(2, 2, 4),
&Device::Cpu,
)
.unwrap();
let hidden_row = vec![vec![1.0f32, 0.0], vec![0.0, 1.0]];
let embedding = pooling::pool_row(
&hidden_row,
&[0, 0],
&tokens,
&vocab,
&stopwords,
&matrix,
false,
)
.unwrap();
let t0 = 2.0f32.tanh();
let t3 = 1.0f32.tanh();
let norm = (t0 * t0 + t3 * t3).sqrt();
let tf = 2.0 * (1.2 + 1.0) / (2.0 + 1.2 * (1.0 - 0.75 + 0.75 * 2.0 / 150.0));
assert_eq!(
embedding.indices,
vec![index::dense_index(1, 0), index::dense_index(1, 3)]
);
let expected = [t0 / norm * tf, t3 / norm * tf];
for (got, want) in embedding.values.iter().zip(expected) {
assert!((got - want).abs() < 1e-5, "{got} vs {want}");
}
}
mod query;
mod resplit;
mod rows;
mod shape;