class Diarize::Speaker
Attributes
gender[R]
model[RW]
model_uri[RW]
normalized[W]
Public Class Methods
detection_threshold()
click to toggle source
# File lib/diarize/speaker.rb, line 33 def detection_threshold @@detection_threshold end
detection_threshold=(threshold)
click to toggle source
# File lib/diarize/speaker.rb, line 29 def detection_threshold=(threshold) @@detection_threshold = threshold end
divergence(speaker1, speaker2)
click to toggle source
# File lib/diarize/speaker.rb, line 46 def divergence(speaker1, speaker2) # TODO bundle in mean_log_likelihood to weight down unlikely models? return unless speaker1.model and speaker2.model # MAP Gaussian divergence # See "A model space framework for efficient speaker detection", Interspeech'05 divergence_lium(speaker1, speaker2) end
divergence_lium(speaker1, speaker2)
click to toggle source
# File lib/diarize/speaker.rb, line 54 def divergence_lium(speaker1, speaker2) Rjb::import('fr.lium.spkDiarization.libModel.Distance').GDMAP(speaker1.model, speaker2.model) end
divergence_ruby(speaker1, speaker2)
click to toggle source
# File lib/diarize/speaker.rb, line 58 def divergence_ruby(speaker1, speaker2) SuperVector.divergence(speaker1.supervector, speaker2.supervector) end
find_or_create(uri, gender)
click to toggle source
# File lib/diarize/speaker.rb, line 41 def find_or_create(uri, gender) return @@speakers[uri] if @@speakers[uri] @@speakers[uri] = Speaker.new(uri, gender) end
load_model(filename)
click to toggle source
# File lib/diarize/speaker.rb, line 37 def load_model(filename) read_gmm(filename) end
match(speakers)
click to toggle source
# File lib/diarize/speaker.rb, line 72 def match(speakers) speakers.combination(2).select { |s1, s2| s1.same_speaker_as(s2) } end
match_sets(speakers1, speakers2)
click to toggle source
# File lib/diarize/speaker.rb, line 62 def match_sets(speakers1, speakers2) matches = [] speakers1.each do |s1| speakers2.each do |s2| matches << [ s1, s2 ] if s1.same_speaker_as(s2) end end matches end
new(uri = nil, gender = nil, model_file = nil)
click to toggle source
# File lib/diarize/speaker.rb, line 13 def initialize(uri = nil, gender = nil, model_file = nil) @model = Speaker.load_model(model_file) if model_file @uri = uri @gender = gender @normalized = false end
ubm()
click to toggle source
# File lib/diarize/speaker.rb, line 22 def ubm speaker = Speaker.new speaker.normalized = true speaker.model = Speaker.load_model(File.join(File.expand_path(File.dirname(__FILE__)), 'ubm.gmm')) speaker end
Protected Class Methods
read_gmm(filename)
click to toggle source
# File lib/diarize/speaker.rb, line 78 def read_gmm(filename) gmmlist = Rjb::JavaObjectWrapper.new("java.util.ArrayList") input = Rjb::import('fr.lium.spkDiarization.lib.IOFile').new(filename, 'rb') input.open Rjb::import('fr.lium.spkDiarization.libModel.ModelIO').readerGMMContainer(input, gmmlist.java_object) input.close gmmlist.to_a.first.java_object end
Public Instance Methods
as_json()
click to toggle source
# File lib/diarize/speaker.rb, line 166 def as_json { 'gender' => gender, 'model' => model_uri, 'mean_log_likelihood' => mean_log_likelihood, 'supervector_hash' => supervector.hash.to_s } end
Also aliased as: _as_json
mean_log_likelihood()
click to toggle source
# File lib/diarize/speaker.rb, line 89 def mean_log_likelihood @mean_log_likelihood ? @mean_log_likelihood : model.mean_log_likelihood # Will be NaN if model was loaded from somewhere end
mean_log_likelihood=(mll)
click to toggle source
# File lib/diarize/speaker.rb, line 93 def mean_log_likelihood=(mll) @mean_log_likelihood = mll end
namespaces()
click to toggle source
Calls superclass method
# File lib/diarize/speaker.rb, line 145 def namespaces super.merge 'ws' => 'http://wsarchive.prototype0.net/ontology/' end
normalize!()
click to toggle source
# File lib/diarize/speaker.rb, line 106 def normalize! unless normalized? # Applies M-Norm from "D-MAP: a Distance-Normalized MAP Estimation of Speaker Models for Automatic Speaker Verification" # to the associated GMM, placing it on a unit hyper-sphere with a UBM centre (model will be at distance one from the UBM # according to GDMAP) # Using supervectors: vector = (1.0 / distance_to_ubm) * vector + (1.0 - 1.0 / distance_to_ubm) * ubm_vector speaker_ubm = Speaker.ubm distance_to_ubm = Math.sqrt(Speaker.divergence(self, speaker_ubm)) model.nb_of_components.times do |k| gaussian = model.components.get(k) gaussian.dim.times do |i| normalized_mean = (1.0 / distance_to_ubm) * gaussian.mean(i) + (1.0 - 1.0 / distance_to_ubm) * speaker_ubm.model.components.get(k).mean(i) gaussian.set_mean(i, normalized_mean) end end @normalized = true end @normalized end
normalized?()
click to toggle source
# File lib/diarize/speaker.rb, line 102 def normalized? !!@normalized end
rdf_mapping()
click to toggle source
# File lib/diarize/speaker.rb, line 157 def rdf_mapping { 'ws:gender' => gender, 'ws:model' => model_uri, 'ws:mean_log_likelihood' => mean_log_likelihood, 'ws:supervector_hash' => supervector.hash.to_s } end
same_speaker_as(other)
click to toggle source
# File lib/diarize/speaker.rb, line 126 def same_speaker_as(other) # Detection score defined in Ben2005 return unless [ self.mean_log_likelihood, other.mean_log_likelihood ].min > @@log_likelihood_threshold self.normalize! other.normalize! detection_score = 1.0 - Speaker.divergence(other, self) detection_score > @@detection_threshold end
save_model(filename, force = false)
click to toggle source
# File lib/diarize/speaker.rb, line 97 def save_model(filename, force = false) raise RuntimeError, "normalized model must be saved with force=true" if !force && normalized? write_gmm(filename, @model) end
supervector()
click to toggle source
# File lib/diarize/speaker.rb, line 135 def supervector if normalized? @supervector ||= begin SuperVector.generate_from_model(model) end else SuperVector.generate_from_model(model) end end
to_json()
click to toggle source
# File lib/diarize/speaker.rb, line 176 def to_json as_json.to_json end
Also aliased as: _to_json
type_uri()
click to toggle source
# File lib/diarize/speaker.rb, line 153 def type_uri 'ws:Speaker' end
uri()
click to toggle source
# File lib/diarize/speaker.rb, line 149 def uri @uri end
Protected Instance Methods
write_gmm(filename, model)
click to toggle source
# File lib/diarize/speaker.rb, line 183 def write_gmm(filename, model) gmmlist = Rjb::JavaObjectWrapper.new("java.util.ArrayList") gmmlist.java_object.add(model) output = Rjb::import('fr.lium.spkDiarization.lib.IOFile').new(filename, 'wb') output.open Rjb::import('fr.lium.spkDiarization.libModel.ModelIO').writerGMMContainer(output, gmmlist.java_object) output.close end