SoundAnalysis + Create MLで話者認識

追記1: 本スライドは2019年6月に開催された[イベント](https://wwdc-gorilla.connpass.com/event/132144/)向けに作成したものです。

---

追記2: 「[iOS 13の新機能をざっくり把握する本](https://shu223.booth.pm/items/1461791)」という電子書籍を

### 100円

で販売しています。本文84ページ。SoundAnalysisの解説も入っています。

https://shu223.booth.pm/items/1461791

---

### "SwiftUI"でGoogle検索 

<img width="310" alt="google_swiftui.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/264bdf01-0a2a-c4ef-18ad-dbc28bb07c2b.jpeg">

（日本語・直近1ヶ月）

---

### "SoundAnalysis"でGoogle検索

<img width="289" alt="Screen Shot 2019-06-17 at 15.24.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/98d4125a-948c-c2ae-6bb4-d8aec39ab5e8.png">

（日本語・直近1ヶ月）

---

## イマイチ注目されていない😇

---

### 音楽向け？

<img width="186" alt="IMG_E0171.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/6edc3647-02a5-58e0-934e-b630d6438927.jpeg">

---

### よくわからないユースケース？

<img width="211" alt="IMG_E0172.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/c198cdf8-4679-2737-ad89-1e6ee1a8b2fa.jpeg">

---

### ・・・と思われているのでは？

---

## 話者認識

---

### 話者認識とは

#### 「誰が話しているか？」を認識する

cf. 「何を話しているか」・・・音声認識

---

## 話者認識ができると・・・

- 議事録・翻訳・字幕
- 動画や音声の無音部分を自動でカット
- 動画や音声から特定話者の部分だけ抽出

etc.

---

今は静止画しか使用していないアプリでも、動画のサイズの問題が解決すれば、今後動画を利用する可能性も出てくるのでは？

---

## Sound Analysis

---

### Sound Analysisとは

- iOS 13で追加された**音声解析**のためのフレームワーク
- 今のところ音声の「分類」のみ可能
- "SoundAnalysis"（リファレンス） か "Sound Analysis"（WWDC）かはっきりしない...

---

### 何の音声を分類できるのか？

- 特定の種類の音声を分類するためのクラス等は何も用意されていない
- Core MLモデルを自作する必要がある

→ どんな音声でも大丈夫（できるとは言っていない）

---

## 音声分類用のCore MLモデルをつくる

---

### Create ML

- [［2019年度版］ドラッグ＆ドロップで機械学習のモデルがつくれる「Create ML」の使い方（macOS 10.15 Catalina） #WWDC19 - その後のその後](http://shu223.hatenablog.com/entry/2019/06/08/111957)

---

<img width="592" alt="IMG_E0174.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/c39896a9-57fd-68b4-5b86-f0a7ee956e0c.jpeg">

---

## Sound Analysisで音声分類を実行する

---

### 音声分類を実行する

```swift
// ファイル用のアナライザを初期化
let audioFileAnalyzer = try! SNAudioFileAnalyzer(url: url)

// MLModelオブジェクトを渡してリクエストを作成
let request = try! SNClassifySoundRequest(mlModel: HogeSoundClassifier().model)

// リクエストをアナライザに追加
try! audioFileAnalyzer.add(request, withObserver: self)

// 解析開始
audioFileAnalyzer.analyze()
```

---

### 分類結果

 `SNClassificationResult`

- `timeRange: CMTimeRange`
  - 処理区間の開始時間・終了時間
- `classifications: [SNClassification]`
  - 各分類クラスのラベル
  - 各分類クラスの信頼度

---

## （デモ） 動画内の話者を識別する

![000004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/8241e73d-e6fb-542f-e8f3-37853dc61876.jpeg)

---

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">SoundAnalysis + Create MLで話者認識（2019年6月に開催された勉強会向けにつくったデモ） <a href="https://twitter.com/hashtag/iOS13?src=hash&amp;ref_src=twsrc%5Etfw">#iOS13</a><a href="https://t.co/qpExce47Ss">https://t.co/qpExce47Ss</a> <a href="https://t.co/r2Dg27ueeH">pic.twitter.com/r2Dg27ueeH</a></p>&mdash; Shuichi Tsutsumi (@shu223) <a href="https://twitter.com/shu223/status/1233178367433699330?ref_src=twsrc%5Etfw">February 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

（会場での反応はこんな感じでした）

 <blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a> これめちゃくちゃ便利なのでは</p>&mdash; おもちメタル (@omochimetaru) <a href="https://twitter.com/omochimetaru/status/1140574050806161408?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Sound Analysis 使ってサザエさんの声を判定するデモすごい… <a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a></p>&mdash; たかしんぐ (@takashings) <a href="https://twitter.com/takashings/status/1140574188631019520?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">SoundAnalysis?Sound Analysis?のデモ、感動しました。<br>確かにこれは利用シーンが多そうですよね。。<br>トレーニングデータを増やせばもっと精度が上がるのでしょうか。<a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a></p>&mdash; haseken_dev (@haseken_dev) <a href="https://twitter.com/haseken_dev/status/1140574228254580739?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Sound Analysisすごい😱 <a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a></p>&mdash; 藤　治仁 (@From_F) <a href="https://twitter.com/From_F/status/1140574235976323072?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">サザエさん話者認識凄い！ <a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a></p>&mdash; izumi (@izm256) <a href="https://twitter.com/izm256/status/1140574242972454912?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">すげえ 字幕の色わけとかに使えそう <a href="https://twitter.com/hashtag/wwdc_rusuban?src=hash&amp;ref_src=twsrc%5Etfw">#wwdc_rusuban</a></p>&mdash; Sho Aoki (@shoaooki) <a href="https://twitter.com/shoaooki/status/1140574305727594502?ref_src=twsrc%5Etfw">June 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


---

## 実装概要 （学習側）

1. トレーニング用音声データを用意
2. CreateMLで学習 → `.mlmodel`ファイルを出力

---

## 実装概要 （アプリ側）

1. 動画から音声を抽出してファイル化
  - ファイルアナライザで処理するため。ストリーミング音声を解析することも可能
2. `timeRange`に応じて分類結果を表示する

---

## その他

---

### Sound Analysisを使わず、Core MLだけで実装することも可能

<img width="520" alt="IMG_E0177.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/951726d5-eb6a-53e3-d3cd-2434cb45ae19.jpeg">

---

### Sound Analysisを使うと・・・

<img width="539" alt="IMG_E0178.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/db2501eb-ec7c-b4ba-0b93-0e8bf3059e39.jpeg">


---

### `overlapFactor`

- 認識に渡されれるバッファの長さは約1.0秒
- 対象の音声波形が区間の真ん中に来るように、オーバーラップさせながら解析処理を行う
- オーバーラップするほど取りこぼしが減るが、処理時間はかかる
- デフォルトは0.5

---

## [PR] いろいろ本を出してます

https://shu223.booth.pm/items

- iOS 13の機能も追記予定です
- 電子版は無料でアップデートできます
- ページ数に応じて値上げするので、今買うと得かも？

<img width="794" alt="Screen Shot 2019-06-17 at 18.15.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3180/95bc51a6-fc95-f579-7082-135c0a184d72.png">


---

## 補足1

10分のLTなのでいろいろ割愛したことがある

- デモは `confidence` と結果の前後関係をみて出力をフィルタしている
  - `confidence < 0.7` の結果はカット
  - 前後の認識結果と `identifier` が違う（つまり孤立している）結果はカット
- デモでは `request.overlapFactor = 0.9`

---

## 補足2

- 学習データの録音環境を実行時の環境と合わせる必要がある
  - 学習データ／デモ用シーンともにBGMのないところを選んだ
  - ただ試してみてダメだったわけではない。BGMありも含めて大量のデータを食わせればロバストに認識できるかもしれない
 
---

## 補足3

- 学習用の音声データはAudacityという昔からあるmacOS用の波形編集ソフトを使ってチマチマ手作業でやった