ディープラーニングを使用した音声分類のエンドツーエンドの例と説明

ディープラーニングを使用した音声分類のエンドツーエンドの例と説明

サウンド分類は、オーディオのディープラーニングで最も広く使用されている方法の 1 つです。音を分類し、音のカテゴリーを予測することを学ぶことが含まれます。この種の問題は、音楽クリップを分類して音楽のジャンルを識別したり、話者のグループからの短い発話を分類して声に基づいて話者を識別するなど、多くの現実世界のシナリオに適用できます。

[[388733]]

この記事では、このようなオーディオ分類の問題を解決するために使用されるアプローチを理解するために、簡単なデモ アプリケーションを紹介します。私の目標は、何かがどのように機能するかだけでなく、なぜそのように機能するかを理解することです。

オーディオ分類

MNIST データセットを使用して手書きの数字を分類することがコンピューター ビジョンの「Hello World」型の問題であると考えられるのと同様に、このアプリケーションはオーディオにおけるディープラーニングの入門レベルの問題と考えることができます。

まずサウンド ファイルから始めて、それをスペクトログラムに変換し、CNN と線形分類モデルに入力して、サウンドが属するクラスに関する予測を生成します。

さまざまな種類のサウンドに適したデータセットが多数あります。これらのデータセットには、解決しようとしている問題に応じてサウンドの種類を識別する、各サンプルのクラス ラベルとともに、多数のオーディオ サンプルが含まれています。

これらのクラス ラベルは通常、オーディオ サンプル ファイル名の一部またはファイルが配置されているサブフォルダー名から取得できます。さらに、クラス ラベルは、通常は TXT、JSON、または CSV 形式の別のメタデータ ファイルで指定されます。

デモ - 一般的な都市の音の分類

デモンストレーションでは、都市の日常生活から録音された一般的な音のコーパスを含む Urban Sound 8K データセットを使用します。音は、工事騒音、犬の鳴き声、笛の音など 10 のカテゴリに分類されます。各サウンド サンプルには、それが属するクラスがラベル付けされます。

データセットをダウンロードすると、次の 2 つの部分で構成されていることがわかります。

「Audio」フォルダ内のオーディオ ファイル: 「fold1」から「fold10」までの名前が付いた 10 個のサブフォルダがあります。各サブフォルダーには多数のものが含まれます。 wav オーディオ サンプル。たとえば、「fold1/103074 - 7 - 1 - 0. - wav」

「Metadata」フォルダ内のメタデータ: 「UrbanSound8K」というファイルがあります。ファイル名、クラス ラベル、「fold」サブフォルダーの場所など、データセット内の各オーディオ サンプルに関する情報が含まれています。クラス ラベルは、10 個のクラスそれぞれに対する 0 から 9 までの数値クラス ID です。のように。数字の 0 はエアコンを表し、1 は車のクラクションを表します。

一般的なオーディオの長さは約 4 秒です。以下に一例を挙げます。

データセット作成者は、メトリックを計算し、モデルのパフォーマンスを評価するために、10 倍のクロス検証を使用することを推奨しています。 ただし、この記事の目的は最先端の指標を達成することではなく、主にオーディオにおけるディープラーニングの威力を実証することであるため、分析は無視し、すべてのサンプルを 1 つの大きなデータセットとして扱います。

トレーニングデータの準備

ほとんどのディープラーニングの問題では、次の手順に従います。

このデータセットのデータ構成はシンプルです。

プロパティ (X) はオーディオ ファイルへのパスです。

ターゲットラベル(y)はクラス名です

データセットにはすでにこの情報を含むメタデータ ファイルがあるため、それを直接使用できます。メタデータには各オーディオ ファイルに関する情報が含まれています。

CSV ファイルなので、Pandas を使用して読み取ることができます。メタデータから特徴とラベルのデータを準備できます。

  1. # ----------------------------  
  2. #メタデータファイルからトレーニングデータを準備する
  3. # ----------------------------  
  4. pandasをpdとしてインポートする
  5. pathlibからPathをインポート
  6.  
  7. download_path = Path.cwd()/ 'UrbanSound8K'   
  8.  
  9. #メタデータファイルを読み取る
  10. metadata_file = ダウンロードパス/ 'メタデータ' / 'UrbanSound8K.csv'   
  11. df = pd.read_csv(メタデータファイル)
  12. df.head()
  13.  
  14. #折り返しファイルを連結しファイルパスを構築します  
  15. df[ '相対パス' ] = '/fold' + df[ 'fold' ].astype(str) + '/' + df[ 'スライスファイル名' ].astype(str)
  16.  
  17. # 関連する列を取得する
  18. df = df[[ '相対パス' , 'クラスID' ]]
  19. df.head()

トレーニングに必要な情報は次のとおりです。

メタデータが利用できない場合にディレクトリをスキャンしてオーディオファイルを探す

メタデータ ファイルを使用すると、物事ははるかに簡単になります。メタデータ ファイルが含まれていないデータセットのデータはどのように準備すればよいですか?

多くのデータセットは、フォルダー構造に配置されたオーディオ ファイルのみで構成されており、クラス ラベルはディレクトリから取得できます。この形式でトレーニング データを準備するには、次の操作を行います。

ディレクトリをスキャンし、すべてのオーディオ ファイル パスのリストを生成します。

各ファイル名または親子フォルダ名からクラスラベルを抽出します

各クラス名をテキストから数値クラスIDにマッピングする

メタデータの有無にかかわらず、結果は同じです。つまり、オーディオ ファイル名のリストで構成される機能と、クラス ID で構成されるターゲット ラベルになります。

オーディオの前処理: 変換の定義

オーディオ ファイル パスを含むこの種のトレーニング データは、モデルに直接取り込むことはできません。ファイルからオーディオ データを読み込み、モデルが想定する形式に適合するように処理する必要があります。

すべてのオーディオ前処理は、オーディオ ファイルを読み込んでロードするときに実行時に動的に実行されます。このアプローチは、画像ファイルで行う方法と似ています。オーディオ データ (または画像データ) は非常に大きく、メモリを大量に消費する可能性があるため、データセット全体を事前に一度にメモリに読み込むことは望ましくありません。したがって、トレーニング データにはオーディオ ファイル名 (または画像ファイル名) のみを保持します。 。

次に、実行時に、一度に 1 つのデータ バッチをトレーニングするときに、そのオーディオ データのバッチを読み込み、一連の変換をオーディオに適用して処理します。この方法では、一度に 1 つのオーディオ データ バッチのみがメモリに保持されます。

画像データの場合、最初に画像ファイルをピクセルとして読み取ってロードする変換パイプラインが必要になる場合があります。次に、いくつかの画像処理手順を適用して、データの形状を変更し、サイズを変更し、固定サイズにトリミングし、必要に応じて RGB からグレースケールに変換します。回転、反転などの画像拡張手順を適用する場合もあります。

オーディオデータの処理も非常に似ています。ここで、トレーニング中にモデルにデータを供給するときに後で実行される関数を定義します。

ファイルから音声を読み込む

最初に行う必要があるのは、「.wav」形式のオーディオ ファイルを読み込んでロードすることです。 この例では Pytorch を使用しているため、以下の実装ではオーディオ処理に torchaudio を使用していますが、librosa でも同様に動作します。

  1. インポート数式、ランダム
  2. 輸入トーチ
  3. torchaudio をインポート
  4. torchaudioから変換をインポート
  5. IPython.displayからオーディオをインポート
  6.  
  7. クラス AudioUtil():
  8. # ----------------------------  
  9. #オーディオファイルを読み込みます信号をテンソルとして返しサンプルレートを返します。
  10. # ----------------------------  
  11. @静的メソッド
  12. def open (オーディオファイル):
  13. sig、sr = torchaudio.load (オーディオファイル)
  14. リターン(sig、sr)

ステレオに変換

一部のサウンド ファイルはモノラル (つまり、1 つのオーディオ チャネル) ですが、ほとんどのサウンド ファイルはステレオ (つまり、2 つのオーディオ チャネル) です。 私たちのモデルではすべてのアイテムが同じ寸法を持つことが想定されているため、最初のチャネルを 2 番目のチャネルに複製してモノラル ファイルをステレオに変換します。

  1. # ----------------------------  
  2. #指定されたオーディオを必要なチャンネル変換します
  3. # ----------------------------  
  4. @静的メソッド
  5. def rechannel(aud, new_channel):
  6. sig、sr = aud
  7.  
  8. sig.shape[0] == new_channelの場合:
  9. # 何もすることがない
  10. オーストラリアドルを返す
  11.  
  12. (new_channel == 1 の場合):
  13. 変換する 最初チャンネルのみを選択しステレオからモノラルに変更
  14. レジスタ = sig[:1, :]
  15. それ以外
  16. 変換する 最初のチャンネルを複製しモノラルからステレオ
  17. resig = torch.cat([sig, sig])
  18.  
  19. 戻り値((resig, sr))

正規化されたサンプリングレート

一部のサウンド ファイルは 48000Hz でサンプリングされますが、ほとんどのサウンド ファイルは 44100Hz でサンプリングされます。 つまり、一部のサウンド ファイルでは 1 秒のオーディオの配列サイズが 48000 であり、他のサウンド ファイルでは 44100 であるということです。すべての配列が同じ次元を持つように、すべてのオーディオを正規化し、同じサンプリング レートに変換する必要があります。

  1. # ----------------------------  
  2. # リサンプルは単一のチャネル適用されるため、一度1つのチャネルをリサンプルします  
  3. # ----------------------------  
  4. @静的メソッド
  5. def resample(aud, newsr):
  6. sig、sr = aud
  7.  
  8. (sr == newsr)の場合:
  9. # 何もすることがない
  10. オーストラリアドルを返す
  11.  
  12. num_channels = sig.shape[0]
  13. #最初のチャンネルを再サンプリングする
  14. resig = torchaudio.transforms.Resample(sr, newsr)(sig[:1,:])
  15. num_channels > 1の場合:
  16. # 2番目のチャンネルを再サンプリングし両方のチャンネルを結合します
  17. retwo = torchaudio.transforms.Resample(sr, newsr)(sig[1:,:])
  18. resig = torch.cat([resig, retwo])
  19.  
  20. 戻り値((resig, newsr))

同じ長さに調整する

次に、無音部分を埋め込むか、長さを切り捨てて継続時間を延長するかのいずれかの方法で、すべてのオーディオ サンプルのサイズを同じ長さに変更します。 このメソッドを AudioUtil クラスに追加します。

  1. # ----------------------------  
  2. # パッド(または 信号固定長'max_ms'切り捨てる ミリ秒単位
  3. # ----------------------------  
  4. @静的メソッド
  5. pad_trunc(aud, max_ms)を定義します。
  6. sig、sr = aud
  7. num_rows、sig_len = sig.shape
  8. 最大長さ = sr//1000 * 最大ミリ秒
  9.  
  10. (sig_len > max_len)の場合:
  11. #信号を指定された長さ切り捨てる
  12. sig = sig[:,:max_len]
  13.  
  14. elif (sig_len < max_len):
  15. #パディング 追加 初め 終わり 信号
  16. pad_begin_len = random.randint(0, max_len - sig_len)
  17. pad_end_len = max_len - sig_len - pad_begin_len
  18.  
  19. # 0埋め込む
  20. pad_begin = torch.zeros((num_rows, pad_begin_len))
  21. pad_end = torch.zeros((num_rows, pad_end_len))
  22.  
  23. sig = torch.cat((pad_begin, sig, pad_end), 1)
  24.  
  25. リターン(sig、sr)

データ拡張: タイムシフト

次に、タイムシフトを適用してオーディオをランダムな量だけ左または右にシフトすることにより、元のオーディオ信号にデータ拡張を実行できます。 この記事では、このデータ拡張手法とその他のデータ拡張手法について詳しく説明します。

  1. # ----------------------------  
  2. # 信号を左シフトします または  による パーセント。 最後  
  3. # は「ラップアラウンド」  変換された信号開始まで
  4. # ----------------------------  
  5. @静的メソッド
  6. def time_shift(aud, shift_limit):
  7. sig、sr = aud
  8. _, sig_len = sig.shape
  9. shift_amt = int (random.random() * shift_limit * sig_len)
  10. 戻り値(sig.roll(shift_amt), sr)

メルスペクトログラム

拡張オーディオをメルスペクトログラムに変換します。 これらはオーディオの本質的な特性を捉えており、多くの場合、オーディオ データをディープラーニング モデルに入力する最も適切な方法です。

  1. # ----------------------------  
  2. # スペクトログラムを生成する
  3. # ----------------------------  
  4. @静的メソッド
  5. def spectro_gram(aud, n_mels=64, n_fft=1024, hop_len=なし):
  6. sig、sr = aud
  7. トップ_db = 80
  8.  
  9. # 仕様は [channel, n_mels, time ] の形をしており、 channelモノラル、ステレオなどです。
  10. spec = transforms.MelSpectrogram(sr, n_fft=n_fft, hop_length=hop_len, n_mels=n_mels)(sig)
  11.  
  12. 変換する デシベル
  13. spec = transforms.AmplitudeToDB(top_db=top_db)(spec)
  14. 戻り値(仕様)

データ拡張: 時間と周波数のマスキング

ここで、元のオーディオではなくメル スペクトログラムに対して、もう一度拡張を実行できます。 ここでは、次の 2 つの方法を使用する SpecAugment という手法を使用します。

周波数マスキング - スペクトログラムに水平バーを追加して、連続する周波数の範囲をランダムにマスクします。

時間マスク - 周波数マスクに似ていますが、垂直線を使用してスペクトログラムから時間範囲をランダムにマスクする点が異なります。

  1. # ----------------------------  
  2. # スペクトログラムをマスクして拡張する 周波数いくつセクション
  3. # 次元(水平バー)時間次元(垂直バー)を区別し
  4. # 過剰適合 モデルの一般化を向上させるためにマスクされたセクションは
  5. #平均値置き換えられました。
  6. # ----------------------------  
  7. @静的メソッド
  8. 定義 spectro_augment(spec、max_mask_pct=0.1、n_freq_masks=1、n_time_masks=1):
  9. _、n_mels、n_steps = スペックシェイプ
  10. マスク値 = spec.mean()
  11. aug_spec = スペック
  12.  
  13. freq_mask_param = 最大マスク率 * n_mels
  14. _が範囲(n_freq_masks)の場合:
  15. aug_spec = transforms.FrequencyMasking(freq_mask_param)(aug_spec, mask_value)
  16.  
  17. time_mask_param = max_mask_pct * n_steps
  18. _が範囲(n_time_masks)の場合:
  19. aug_spec = transforms.TimeMasking(time_mask_param)(aug_spec、mask_value)
  20.  
  21. aug_specを返す

カスタムデータローダー

前処理変換関数をすべて定義したので、カスタム Pytorch Dataset オブジェクトを定義します。

Pytorch を使用してモデルにデータを供給するには、次の 2 つのオブジェクトが必要です。

すべてのオーディオ変換を使用してオーディオ ファイルを前処理し、一度に 1 つのデータ項目を準備するカスタム Dataset オブジェクト。

Dataset オブジェクトを使用して個々のデータ項目を取得し、それらをデータのバッチにパッケージ化する組み込みの DataLoader オブジェクト。

  1. torch.utils.dataからDataLoader、Dataset、random_split をインポートします
  2. torchaudio をインポート
  3.  
  4. # ----------------------------  
  5. # サウンドデータセット
  6. # ----------------------------  
  7. クラスSoundDS(データセット):
  8. def __init__(self, df, data_path):
  9. 自己.df = df
  10. 自己.data_path = str(データパス)
  11. 自己持続時間 = 4000
  12. 自己.sr = 44100
  13. 自己チャンネル = 2
  14. 自己シフト率 = 0.4
  15.  
  16. # ----------------------------  
  17. #データセット内のアイテム
  18. # ----------------------------  
  19. __len__(自分)を定義します:
  20. len(self.df)を返す
  21.  
  22. # ----------------------------  
  23. #データセット内のi 番目の項目を取得する
  24. # ----------------------------  
  25. __getitem__(self, idx)を定義します。
  26. # オーディオファイル絶対ファイルパス- オーディオディレクトリ  
  27. #相対パス
  28. audio_file = self.data_path + self.df.loc[idx, 'relative_path' ]
  29. # クラスIDを取得する
  30. class_id = self.df.loc[idx, 'classID' ]
  31.  
  32. aud = AudioUtil.open (オーディオファイル)
  33. #一部のサウンドは、サンプルレートが高く、チャンネルが少ないため
  34. # 多数派。すべてのサウンドに同じ数チャンネル同じ数
  35. # サンプルレート。サンプルレート同じでない限り、pad_truncは
  36. #サウンドの長さが同じであっても、異なる長さ配列生成されます。   
  37. # 同じ。
  38. reaud = AudioUtil.resample(aud, self.sr)
  39. rechan = AudioUtil.rechannel(reaud, self.channel)
  40.  
  41. dur_aud = AudioUtil.pad_trunc(rechan, self.duration)
  42. shift_aud = AudioUtil.time_shift(dur_aud、self.shift_pct) です。
  43. sgram = AudioUtil.spectro_gram(shift_aud、n_mels=64、n_fft=1024、hop_len=なし)
  44. aug_sgram = AudioUtil.spectro_augment(sgram、max_mask_pct=0.1、n_freq_masks=2、n_time_masks=2)
  45.  
  46. aug_sgram、class_idを返す

データローダーを使用してデータのバッチを準備する

これで、モデルにデータを入力するために必要なすべての関数が定義されました。

カスタム データセットを使用して Pandas から機能とラベルを読み込み、データを 80:20 の比率でトレーニング セットと検証セットにランダムに分割します。 次に、これらを使用してトレーニングおよび検証データ ローダーを作成します。

  1. torch.utils.dataからrandom_split をインポートします
  2.  
  3. myds = SoundDS(df, データパス)
  4.  
  5. #トレーニング検証80:20ランダム分割
  6. num_items = len(myds)
  7. num_train = round(num_items * 0.8)
  8. num_val = num_items - num_train
  9. train_ds, val_ds = random_split(myds, [num_train, num_val])
  10.  
  11. #トレーニングおよび検証データローダーを作成する
  12. train_dl = torch.utils.data.DataLoader(train_ds、batch_size=16、shuffle= True )
  13. val_dl = torch.utils.data.DataLoader(val_ds、batch_size=16、shuffle= False )

トレーニングを開始すると、オーディオ ファイル名のリストを含む入力のランダム バッチを取得し、各オーディオ ファイルに対して前処理オーディオ変換を実行します。 また、クラス ID を含む対応するターゲット ラベルのバッチも取得します。 したがって、一度にトレーニング データのバッチが出力され、それをディープラーニング モデルへの入力として直接渡すことができます。

まずオーディオ ファイルから始めて、データ変換の手順を実行してみましょう。

ファイルからのオーディオは Numpy 配列 (numchannels、numsamples) に読み込まれます。オーディオのほとんどは 44.1kHz でサンプリングされ、約 4 秒間続くため、サンプル数は 44,100 * 4 = 176,400 になります。オーディオに 1 つのチャンネルがある場合、配列の形状は (1, 176, 400) になります。同様に、2 チャンネルで 4 秒間持続し、48kHz でサンプリングされたオーディオには、(2, 192,000) の形状を持つ 192,000 個のサンプルが含まれます。

各オーディオのチャンネルとサンプリング レートは異なるため、次の 2 つの変換では、オーディオが標準の 44.1kHz と標準の 2 チャンネルに再サンプリングされます。

一部のオーディオ クリップは 4 秒より長いか短い場合があるため、オーディオの長さも 4 秒の固定長さに正規化します。これで、すべてのアイテムの配列は同じ形状になります (2, 176, 400)

タイムシフト データ拡張は、各オーディオ サンプルをランダムに前方または後方にシフトします。形状は変わりません。

拡張オーディオは、(numchannels, Mel freqbands, time_steps) = (2, 64, 344) の形状を持つメルスペクトログラムに変換されます。

SpecAugment データ拡張関数は、時間と周波数のマスクをメルスペクトログラムにランダムに適用します。形状は変わりません。

最終的にはバッチごとに 2 つのテンソルが作成されます。1 つはメル スペクトログラムを含む X 特徴データ用で、もう 1 つは数値クラス ID を含む y ターゲット ラベル用です。 バッチは、各トレーニング エポックのトレーニング データからランダムに選択されます。

各バッチの形状は (batchsz、numchannels、Mel freqbands、timesteps) です。

バッチ内の 1 つの項目を視覚化できます。 垂直方向と水平方向の縞模様のメル スペクトログラムには、周波数と時間マスクされたデータの拡張が表示されていることがわかります。

モデルの構築

今実行したデータ処理手順は、オーディオ分類の問題の最もユニークな側面です。 ここからのモデルとトレーニング プロセスは、標準的な画像分類問題で一般的に使用されるものと非常に似ており、オーディオ ディープラーニングに固有のものではありません。

データはスペクトログラム画像で構成されているため、それを処理するために CNN 分類アーキテクチャを構築します。 特徴マップを生成する 4 つの畳み込みブロックがあります。 次に、データは必要な形式に再構成され、線形分類レイヤーに入力され、最終的に 10 個のクラスごとに予測が出力されます。

モデル情報:

カラー画像は、(バッチ数、チャネル数、メル周波数バンド、タイムステップ) の形でモデルに入力されます。 (16、2、64、344)。

各 CNN レイヤーはフィルターを適用して、画像の深度、つまりチャネルの数を増やします。 (16、64、4、22)。

これらは結合され、(16, 64) の形状に平坦化されてから、線形レイヤーに送られます。

線形層は各カテゴリの予測スコアを出力する。すなわち、(16, 10)

  1. torch.nn.function をFとしてインポートします。
  2. torch.nnからinitをインポート
  3.  
  4. # ----------------------------  
  5. # オーディオ分類モデル
  6. # ----------------------------  
  7. クラス AudioClassifier (nn.Module):
  8. # ----------------------------  
  9. # モデルアーキテクチャを構築する
  10. # ----------------------------  
  11. __init__(self)を定義します。
  12. スーパー().__init__()
  13. 変換レイヤー = []
  14.  
  15. # Reluバッチノルムを使用した最初の畳み込みブロック。Kaiming初期化を使用する
  16. self.conv1 = nn.Conv2d(2, 8, カーネルサイズ=(5, 5), ストライド=(2, 2), パディング=(2, 2))
  17. 自己.relu1 = nn.ReLU()
  18. 自己.bn1 = nn.BatchNorm2d(8)
  19. init.kaiming_normal_(self.conv1.weight、a=0.1) を使います。
  20. 自己.conv1.バイアス.データ.ゼロ_()
  21. conv_layers += [self.conv1, self.relu1, self.bn1]
  22.  
  23. # 2 番目の畳み込みブロック
  24. self.conv2 = nn.Conv2d(8, 16, カーネルサイズ=(3, 3), ストライド=(2, 2), パディング=(1, 1))
  25. 自己.relu2 = nn.ReLU()
  26. 自己.bn2 = nn.BatchNorm2d(16)
  27. init.kaiming_normal_(self.conv2.weight、a=0.1) を使います。
  28. 自己.conv2.バイアス.データ.ゼロ_()
  29. conv_layers += [self.conv2、self.relu2、self.bn2]
  30.  
  31. # 2 番目の畳み込みブロック
  32. self.conv3 = nn.Conv2d(16, 32, カーネルサイズ=(3, 3), ストライド=(2, 2), パディング=(1, 1))
  33. 自己.relu3 = nn.ReLU()
  34. 自己.bn3 = nn.BatchNorm2d(32)
  35. init.kaiming_normal_(self.conv3.weight、a=0.1) を使います。
  36. 自己.conv3.バイアス.データ.ゼロ_()
  37. conv_layers += [self.conv3、self.relu3、self.bn3]
  38.  
  39. # 2 番目の畳み込みブロック
  40. self.conv4 = nn.Conv2d(32, 64, カーネルサイズ=(3, 3), ストライド=(2, 2), パディング=(1, 1))
  41. 自己.relu4 = nn.ReLU()
  42. 自己.bn4 = nn.BatchNorm2d(64)
  43. init.kaiming_normal_(self.conv4.weight、a=0.1) を使います。
  44. 自己.conv4.バイアス.データ.ゼロ_()
  45. conv_layers += [self.conv4、self.relu4、self.bn4]
  46.  
  47. # 線形分類器
  48. 自己.ap = nn.AdaptiveAvgPool2d(出力サイズ=1)
  49. self.lin = nn.Linear(in_features=64、out_features=10) です。
  50.  
  51. # 畳み込みブロックをラップする
  52. self.conv = nn.Sequential(*conv_layers)
  53.  
  54. # ----------------------------  
  55. #フォワードパス計算
  56. # ----------------------------  
  57. def forward (self, x):
  58. # 畳み込みブロックを実行する
  59. x = 自己変換(x)
  60.  
  61. #線形レイヤーへの入力ための適応プールフラット化
  62. x = 自己.ap(x)
  63. x = x.view (x.shape[0], -1)
  64.  
  65. # 線形レイヤー
  66. x = 自己.lin(x)
  67.  
  68. # 最終出力  
  69. xを返す
  70.  
  71. #モデルを作成し可能であれば GPU配置します
  72. myModel = オーディオ分類器()
  73. デバイス = torch.device( "cuda:0" torch.cuda.is_available() の場合、そうでない場合  "CPU"
  74. myModel = myModel.to (デバイス)
  75. #確認しください  Cudaについて
  76. 次の(myModel.parameters()).device

電車

これで、モデルをトレーニングするためのトレーニング ループを作成する準備が整いました。

トレーニングの進行に合わせて学習率を動的に変更するオプティマイザー、損失関数、学習率スケジュール関数を定義し、モデルの収束を早めます。

各トレーニングラウンドが完了した後。 私たちは、正しい予測の割合を測定する単純な精度メトリックを追跡します。

# ----------------------------

# トレーニングループ

# ----------------------------

def トレーニング(モデル、train_dl、num_epochs):

# 損失関数、オプティマイザー、スケジューラー

基準 = nn.CrossEntropyLoss()

オプティマイザー = torch.optim.Adam(model.parameters(),lr=0.001)

スケジューラ = torch.optim.lr_scheduler.OneCycleLR(オプティマイザ、max_lr=0.001、

ステップ数/エポック = int(len(train_dl))、

エポック=num_epochs、

anneal_strategy = '線形')

# 各エポックごとに繰り返します

範囲(num_epochs)内のエポックの場合:

ランニングロス = 0.0

正しい予測 = 0

合計予測 = 0

# トレーニングセット内の各バッチについて繰り返します

iの場合、enumerate(train_dl)内のデータ:

# 入力特徴とターゲットラベルを取得し、GPUに配置する

入力、ラベル = data[0].to(デバイス)、data[1].to(デバイス)

# 入力を正規化する

inputs_m、inputs_s = inputs.mean()、inputs.std()

入力 = (入力 - inputs_m) / inputs_s

# パラメータの勾配をゼロにする

オプティマイザ.zero_grad()

# 前進 + 後退 + 最適化

出力 = モデル(入力)

損失 = 基準(出力、ラベル)

損失.後方()

オプティマイザ.ステップ()

スケジューラ.ステップ()

# 損失と精度の統計を保存する

実行中の損失 += 損失.item()

# 最高スコアの予測クラスを取得する

_, 予測 = torch.max(出力,1)

# ターゲットラベルに一致した予測の数

正しい予測 += (予測 == ラベル).sum().item()

合計予測 += 予測形状[0]

#if i % 10 == 0: # 10 個のミニバッチごとに印刷

# print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 10))

# エポック終了時に統計情報を出力します

バッチ数 = len(train_dl)

平均損失 = 実行損失 / バッチ数

acc = 正しい予測/合計予測

print(f'エポック: {epoch}, 損失: {avg_loss:.2f}, 精度: {acc:.2f}')

print('トレーニング終了')

num_epochs=2 # デモ用なので、これを高く調整します。

トレーニング(myModel、train_dl、num_epochs)

推論

通常、トレーニング ループの一部として、検証データのメトリックも評価します。 そこで、元のデータから保持されたテスト データセット (トレーニング中に未知のデータとして扱われる) に対して推論を実行します。 このデモでは、検証データを使用します。

勾配更新を無効にして推論ループを実行します。 予測を得るためにモデルでフォワードパスを実行しますが、バックプロパゲーションと最適化は必要ありません。

  1. # ----------------------------  
  2. # 推論
  3. # ----------------------------  
  4. def推論(モデル、val_dl):
  5. 正しい予測 = 0
  6. 合計予測 = 0
  7.  
  8. # グラデーションの更新を無効にする
  9. torch.no_grad()の場合:
  10. val_dlデータの場合:
  11. # 入力特徴ターゲットラベルを取得し、 GPU配置する
  12. 入力、ラベル = data[0] .to (デバイス)、data[1] .to (デバイス)
  13.  
  14. # 入力を正規化する
  15. inputs_m、inputs_s = inputs.mean()、inputs.std()
  16. 入力 = (入力 - inputs_m) / inputs_s
  17.  
  18. # 予測を取得する
  19. 出力 = モデル(入力)
  20.  
  21. #最高スコア予測クラスを取得する
  22. _, 予測 = torch.max (出力,1)
  23. #カウント ターゲットラベルに一致する予測
  24. 正しい予測 += (予測 == ラベル) .sum ().item()
  25. 合計予測 += 予測形状[0]
  26.  
  27. acc = 正しい予測/合計予測
  28. print(f '精度: {acc:.2f}, 合計項目: {total_prediction}' )
  29.  
  30. #検証セットを使用してトレーニング済みモデル推論を実行する  
  31. 推論(myModel、val_dl)

結論は

ここまで、オーディオのディープラーニングにおける最も基本的な問題の 1 つであるサウンド分類のエンドツーエンドの例を見てきました。 これは幅広いアプリケーションで使用できるだけでなく、ここで紹介する概念やテクニックの多くは、人間の音声から始めて、人が言っていることを理解し、それをテキストに変換する自動音声認識などの、より複雑なオーディオの問題にも関連します。

<<:  人間は機械化され、機械は人間化されるのです!起こっていることはさらに恐ろしいことだ。

>>:  ペイ・ジアンのチームの44ページの新作:ディープラーニングモデルの複雑さを理解するには、これを読んでください

ブログ    

推薦する

超人工知能を巡る究極の議論 ― 人間とどう共存するか?それとも人類に対する完全な脅威でしょうか?

[[386332]] 1950 年代に、SF 作家のフレドリック・ブラウンは超知能機械についての物...

Baidu Brainのインテリジェント会話エンジンが9つのコア機能のリリースで「警笛を鳴らす」

言語は思考と知識を伝達し、人類の文明を推進します。そして会話によって機械はより賢くなり、人間にとって...

...

...

...

...

テクスチャコントラスト検出を使用してAI生成画像を検出する

この記事では、AI によって生成された画像を検出するためのディープラーニング モデルを開発する方法に...

オープンモデルの重みはAIを制御不能にすると言われ、Metaはプラカードで抗議され、LeCun:オープンソースAIコミュニティは活発化している

AIの分野では、オープンソースとクローズドソースの選択については、常に意見が分かれてきました。しかし...

...

「思考スタンプ」が実現!中国とアメリカの科学者33人の最新の成果:光を使って脳の認知を変える

[[404075]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

...

役に立つヒント | 複数の事前トレーニング済みビジョンモデルの転移学習

この記事では、Keras Tensorflow 抽象ライブラリに基づく転移学習アルゴリズム モデルを...

ドローンと農業は互いに補完し合い、数千億ドルの価値がある広大なブルーオーシャンを共同で生み出す

かつて、農業と言えば、人々はいつも「真昼に畑を耕し、汗を地面に垂らす」という苦労を思い浮かべていまし...

人工知能と機械学習がスタートアップに与える影響

人工知能 (AI) と機械学習 (ML) は、スタートアップを含む複数の業界に革命をもたらしました。...

Kingsoft WPS Office 2019 正式リリース: Word、Excel、PPT を 1 つのソフトウェアで操作

7月3日、キングソフトは北京オリンピックタワーで「シンプル・クリエイティブ・シンプルではない」をテー...