Java へのオーディオ埋め込み
現在のプロジェクトは、純粋な Java または Android プログラムで使用できる純粋な Java オーディオ エンコーダの開発を試みています。このようなオーディオ エンコーダは、音楽ジャンルの分類、音楽検索、または音楽の推奨に使用できます。
現在のプロジェクトには、現在以下から採用された 2 つの深層学習ネットワークが含まれています。
これら 2 つのモデルのトレーニングと検証を以下に示します。
Java の機械学習パッケージは tensorflow であり、事前トレーニングされた音声分類子モデル (.pb 形式) を読み込みます。オーディオ分類子モデルは元々、Python の Keras を使用して実装およびトレーニングされました。このトレーニングされた分類子モデル (.h5 形式) は、Java の tensorflow によって直接ロードできる .pb モデル ファイルに変換されました。
オーディオ分類子モデルの keras トレーニングは README_Training.md にあります。
以下のサンプル コードは、cifar オーディオ分類子を使用して音楽のジャンルを予測する方法を示しています。
import com . github . chen0040 . tensorflow . classifiers . models . cifar10 . Cifar10AudioClassifier ;
import com . github . chen0040 . tensorflow . classifiers . utils . ResourceUtils ;
import org . slf4j . Logger ;
import org . slf4j . LoggerFactory ;
import java . io . File ;
import java . io . IOException ;
import java . io . InputStream ;
import java . util . ArrayList ;
import java . util . Collections ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ) {
InputStream inputStream = ResourceUtils . getInputStream ( "tf_models/cifar10.pb" );
Cifar10AudioClassifier classifier = new Cifar10AudioClassifier ();
classifier . load_model ( inputStream );
List < String > paths = getAudioFiles ();
Collections . shuffle ( paths );
for ( String path : paths ) {
System . out . println ( "Predicting " + path + " ..." );
File f = new File ( path );
String label = classifier . predict_audio ( f );
System . out . println ( "Predicted: " + label );
}
}
}
以下のサンプル コードは、resnet v2 オーディオ分類子を使用して音楽のジャンルを予測する方法を示しています。
import com . github . chen0040 . tensorflow . classifiers . resnet_v2 . ResNetV2AudioClassifier ;
import com . github . chen0040 . tensorflow . classifiers . utils . ResourceUtils ;
import org . slf4j . Logger ;
import org . slf4j . LoggerFactory ;
import java . io . File ;
import java . io . IOException ;
import java . io . InputStream ;
import java . util . ArrayList ;
import java . util . Collections ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ) {
InputStream inputStream = ResourceUtils . getInputStream ( "tf_models/resnet-v2.pb" );
ResNetV2AudioClassifier classifier = new ResNetV2AudioClassifier ();
classifier . load_model ( inputStream );
List < String > paths = getAudioFiles ();
Collections . shuffle ( paths );
for ( String path : paths ) {
System . out . println ( "Predicting " + path + " ..." );
File f = new File ( path );
String label = classifier . predict_audio ( f );
System . out . println ( "Predicted: " + label );
}
}
}
以下のサンプル コードは、cifar オーディオ分類子を使用してオーディオ ファイルを float 配列にエンコードする方法を示しています。
import com . github . chen0040 . tensorflow . classifiers . models . cifar10 . Cifar10AudioClassifier ;
import com . github . chen0040 . tensorflow . classifiers . utils . ResourceUtils ;
import org . slf4j . Logger ;
import org . slf4j . LoggerFactory ;
import java . io . File ;
import java . io . IOException ;
import java . io . InputStream ;
import java . util . ArrayList ;
import java . util . Collections ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ){
InputStream inputStream = ResourceUtils . getInputStream ( "tf_models/cifar10.pb" );
Cifar10AudioClassifier classifier = new Cifar10AudioClassifier ();
classifier . load_model ( inputStream );
List < String > paths = getAudioFiles ();
Collections . shuffle ( paths );
for ( String path : paths ) {
System . out . println ( "Encoding " + path + " ..." );
File f = new File ( path );
float [] encoded_audio = classifier . encode_audio ( f );
System . out . println ( "Encoded: " + Arrays . toString ( encoded_audio ));
}
}
}
以下のサンプル コードは、resnet v2 オーディオ分類子がオーディオ ファイルを float 配列にエンコードする方法を示しています。
import com . github . chen0040 . tensorflow . classifiers . resnet_v2 . ResNetV2AudioClassifier ;
import com . github . chen0040 . tensorflow . classifiers . utils . ResourceUtils ;
import org . slf4j . Logger ;
import org . slf4j . LoggerFactory ;
import java . io . File ;
import java . io . IOException ;
import java . io . InputStream ;
import java . util . ArrayList ;
import java . util . Collections ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ) {
InputStream inputStream = ResourceUtils . getInputStream ( "tf_models/resnet-v2.pb" );
ResNetV2AudioClassifier classifier = new ResNetV2AudioClassifier ();
classifier . load_model ( inputStream );
List < String > paths = getAudioFiles ();
Collections . shuffle ( paths );
for ( String path : paths ) {
System . out . println ( "Encoding " + path + " ..." );
File f = new File ( path );
float [] encoded_audio = classifier . encode_audio ( f );
System . out . println ( "Encoded: " + Arrays . toString ( encoded_audio ));
}
}
}
以下のサンプル コードは、AudioSearchEngine クラスを使用してオーディオ ファイルのインデックスを作成し、検索する方法を示しています。
import com . github . chen0040 . tensorflow . search . models . AudioSearchEngine ;
import com . github . chen0040 . tensorflow . search . models . AudioSearchEntry ;
import java . io . File ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ){
AudioSearchEngine searchEngine = new AudioSearchEngine ();
if (! searchEngine . loadIndexDbIfExists ()) {
searchEngine . indexAll ( FileUtils . getAudioFiles ());
searchEngine . saveIndexDb ();
}
int pageIndex = 0 ;
int pageSize = 20 ;
boolean skipPerfectMatch = true ;
File f = new File ( "mp3_samples/example.mp3" );
System . out . println ( "querying similar music to " + f . getName ());
List < AudioSearchEntry > result = searchEngine . query ( f , pageIndex , pageSize , skipPerfectMatch );
for ( int i = 0 ; i < result . size (); ++ i ){
System . out . println ( "# " + i + ": " + result . get ( i ). getPath () + " (distSq: " + result . get ( i ). getDistance () + ")" );
}
}
}
以下のサンプル コードは、KnnAudioRecommender クラスを使用してユーザーの音楽履歴に基づいて音楽を推奨する方法を示しています。
import com . github . chen0040 . tensorflow . classifiers . utils . FileUtils ;
import com . github . chen0040 . tensorflow . recommenders . models . AudioUserHistory ;
import com . github . chen0040 . tensorflow . recommenders . models . KnnAudioRecommender ;
import com . github . chen0040 . tensorflow . search . models . AudioSearchEntry ;
import java . io . File ;
import java . util . Collections ;
import java . util . List ;
public class Demo {
public static void main ( String [] args ){
AudioUserHistory userHistory = new AudioUserHistory ();
List < String > audioFiles = FileUtils . getAudioFilePaths ();
Collections . shuffle ( audioFiles );
for ( int i = 0 ; i < 40 ; ++ i ){
String filePath = audioFiles . get ( i );
userHistory . logAudio ( filePath );
try {
Thread . sleep ( 100L );
} catch ( InterruptedException e ) {
e . printStackTrace ();
}
}
KnnAudioRecommender recommender = new KnnAudioRecommender ();
if (! recommender . loadIndexDbIfExists ()) {
recommender . indexAll ( new File ( "music_samples" ). listFiles ( a -> a . getAbsolutePath (). toLowerCase (). endsWith ( ".au" )));
recommender . saveIndexDb ();
}
System . out . println ( userHistory . head ( 10 ));
int k = 10 ;
List < AudioSearchEntry > result = recommender . recommends ( userHistory . getHistory (), k );
for ( int i = 0 ; i < result . size (); ++ i ){
AudioSearchEntry entry = result . get ( i );
System . out . println ( "Search Result #" + ( i + 1 ) + ": " + entry . getPath ());
}
}
}