テキストから音声の生成モデル「DiffSound」を動かす【#Text-to-Sound】【#音声AI】

今期はテキストから音声を生成するモデル"DiffSound"をpretraindeモデルで動作させる方法を記載します。
入力テキストには「Birds and insects make noise during the daytime」のような文章を使用し、その文章に適した音声が生成されるというモデルになります。このモデルはテキストから音声への生成結果が良いだけでなく、生成速度も早く、従来のARデコーダの5倍の生成速度であることが論文内で示されています。
DiffSound作成者が公開しているデモページがあるのでご確認ください。
Diffsound: Discrete Diffusion Model for Text-to-sound Generation | text-to-sound-synthesis-demo
本記事のテーマ
DiffSoundのgithubだけでなく、他のモデルも組み合わせて全体のシステムが作成されているためコードの配置やpretrainモデルを配置することが難しかった。
その方法を紹介する。
論文のAbstract
人間が求める効果音を生成することは、重要なテーマである。しかし、この分野の音生成の研究はほとんどない。本研究では、テキストプロンプトを条件とした音声生成について検討し、テキストエンコーダ、VQ-VAE(Vector Quantized Variational Autoencoder)、デコーダ、ボコーダからなる新しいテキスト-音声生成フレームワークを提案する。このフレームワークは、まずデコーダでテキストエンコーダから抽出したテキスト特徴をVQ-VAEの助けを借りてメルスペクトログラムに転送し、次にボコーダで生成されたメルスペクトログラムを波形に変換するものである。その結果、デコーダが生成性能に大きく影響することがわかった。そこで、本研究では、優れたデコーダの設計に焦点を当てる。まず、従来の音声生成で最先端であることが証明されている自己回帰型復号器について説明します。しかし、ARデコーダは常にメルスペクトログラムのトークンを1つずつ順番に予測するため、一方向の偏りや誤差の累積の問題が発生する。また、ARデコーダでは、音声の長さに比例して音声生成時間が増加する。このようなARデコーダの欠点を克服するために、我々は離散拡散モデルに基づく非自己回帰型デコーダDiffsoundを提案する。具体的には、Diffsoundは1つのステップでmel-spectrogramの全てのトークンを予測し、次のステップで予測されたトークンを洗練させるため、数ステップ後に最良の予測結果を得ることが可能である。実験の結果、提案するDiffsoundはARデコーダと比較して、テキストから音声への生成結果が良好であるだけでなく、生成速度も速く、例えば、MOS: 3.56 v.s 2.786 と、ARデコーダの5倍の生成速度であることが示された。さらに、生成されたサンプルの品質を自動的に評価するために、3つの異なる客観的評価指標(例えば、FID、KL、オーディオキャプションロス)を定義し、生成サンプルの関連性と忠実度を包括的に評価できるようにした。コード、事前学習済みモデル、および生成されたサンプルを公開します 1 。
Translated by DeepL
DiffSoundを動かす
1.コードをCloneする。
git clone https://github.com/yangdongchao/Text-to-sound-Synthesis.git
2.環境構築を行う
Text-to-sound-Synthesis/Diffsound/README.md内のEnviromentに記載されているライブラリをInstallする。
※その他実行中に足りないものが出てきた場合はInstallしてください。
pip install torch==1.9.0 torchvision --no-cache-dir -U | cat
pip install omegaconf pytorch-lightning --no-cache-dir -U | cat
pip install timm==0.3.4 --no-cache-dir -U | cat
pip install tensorboard==1.15.0 --no-cache-dir -U | cat
pip install lmdb tqdm --no-cache-dir -U | cat
pip install einops ftfy --no-cache-dir -U | cat
pip install git+https://github.com/openai/DALL-E.git --no-cache-dir -U | cat
3.pre-trained modelをダウンロードする
Text-to-sound-Synthesis/Diffsound/README.md内のAbout the pre-trained modelに記載されているURLからダウンロードを行う。
4.generate_samples_batch.pyの実行
今回はREADMEのSamplingに記載されているevaluate/generate_samples_batch.pyを実行してDiffSoundを動かす。
動かすためにはスクリプト内に記載されている。Pathを自身のPCと合わせないといけない。その手順を以下に示す。
■evaluate/generate_samples_batch.py
if __name__ == '__main__':
# Note that cap_text.yaml includes the config of vagan, we must choose the right path for it.
config_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/evaluation/caps_text.yaml'
#config_path = '/apdcephfs/share_1316500/donchaoyang/code3/VQ-Diffusion/OUTPUT/caps_train/2022-02-20T21-49-16/caps_text256.yaml'
pretrained_model_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/OUTPUT/pretrained_model/audioset_pretrain_diffsound.pth'
save_root_ = '/apdcephfs/share_1316500/donchaoyang/code3/DiffusionFast/OUTPUT/caps_train_vgg_pre/2022-05-18T01-00-38'
random_seconds_shift = datetime.timedelta(seconds=np.random.randint(60))
key_words = 'Real_vgg_pre_399'
now = (datetime.datetime.now() - random_seconds_shift).strftime('%Y-%m-%dT%H-%M-%S')
save_root = os.path.join(save_root_, key_words + '_samples_'+now, 'caps_validation')
# print(save_root)
# assert 1==2
os.makedirs(save_root, exist_ok=True)
# val_path = 'data_root/audiocaps/new_val.csv'
val_path = 'data_root/audiocaps/new_mytest.csv'
ckpt_vocoder = 'vocoder/logs/vggsound/'
Diffsound = Diffsound(config=config_path, path=pretrained_model_path, ckpt_vocoder=ckpt_vocoder)
Diffsound.generate_sample(val_path=val_path, truncation_rate=0.85, save_root=save_root, fast=False)
設定するPathは以下の4つ。
・config_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/evaluation/caps_text.yaml'
・pretrained_model_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/OUTPUT/pretrained_model/audioset_pretrain_diffsound.pth'
・save_root_ = '/apdcephfs/share_1316500/donchaoyang/code3/DiffusionFast/OUTPUT/caps_train_vgg_pre/2022-05-18T01-00-38'
・val_path = 'data_root/audiocaps/new_mytest.csv'
・ckpt_vocoder = 'vocoder/logs/vggsound/'
config_path
・config_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/evaluation/caps_text.yaml'
ここはText-to-sound-Synthesis/Diffsound/evaluationのフォルダ内に存在するcaps_text.yamlを指定すればよい。
pretrained_model_path
・pretrained_model_path = '/work/hiro877/Text-to-sound-Synthesis/Diffsound/OUTPUT/pretrained_model/audioset_pretrain_diffsound.pth'
ここは、Downloadしたフォルダ内に存在するaudioset_pretrain_diffsound.pthを配置してPathを設定する
save_root_
・save_root_ = '/apdcephfs/share_1316500/donchaoyang/code3/DiffusionFast/OUTPUT/caps_train_vgg_pre/2022-05-18T01-00-38'
ここは実行後の音声ファイルが保存されるPathであるため任意のPathを指定する。
val_path
・val_path = 'data_root/audiocaps/new_mytest.csv'
ここは元の設定のままで動作する。
このファイルが入力するテキストになるため、ここを編集することで好きな音声を生成することが出来る。
ckpt_vocoder
・ckpt_vocoder = 'vocoder/logs/vggsound/'
ここは元の設定のままで動作する。
ViT-B-32モデルのダウンロード
このまま実行すると"/apdcephfs/share_1316500/donchaoyang/code3/VQ-Diffusion/OUTPUT/pretrained_model/ViT-B-32.pt"が見つかりませんというエラーが発生する。
ViT-B-32.ptをダウンロードするにはDiffSound/sound_synthesis/modeling/modules/clip/clip.pyのload()関数内を少し変更する必要がある。
model_path = _download(_MODELS[name])のコメントアウトを外すことでモデルをダウンロードしてくれる。一度ダウンロードした後は必要ないので再度コメントアウトを行う。
ダウンロード先は_download()関数の中のdownload_targetを変更することで任意の場所に保存できる。また、load()関数内のmodel_pathの方も変更するように注意する。
def load(name: str, device: Union[str, torch.device] = "cuda" if torch.cuda.is_available() else "cpu", jit=True):
"""Load a CLIP model
Parameters
----------
name : str
A model name listed by `clip.available_models()`, or the path to a model checkpoint containing the state_dict
device : Union[str, torch.device]
The device to put the loaded model
jit : bool
Whether to load the optimized JIT model (default) or more hackable non-JIT model.
Returns
-------
model : torch.nn.Module
The CLIP model
preprocess : Callable[[PIL.Image], torch.Tensor]
A torchvision transform that converts a PIL image into a tensor that the returned model can take as its input
"""
if name in _MODELS:
model_path = _download(_MODELS[name]) ☆ここのコメントアウトを外す
# model_path = "/apdcephfs/share_1316500/donchaoyang/code3/VQ-Diffusion/OUTPUT/pretrained_model/ViT-B-32.pt"
※追記:私の使用感として下記リンクのコードからダウンロードしたモデルを使用したほうがテキストに近い音声が生成されることが分かった。
# Download ViT-B-32.pt
# aria2cのインストールが必要
aria2c https://facevcstandard.blob.core.windows.net/t-shuygu/release_model/VQ-Diffusion/pretrained_model/ViT-B-32.pt --auto-file-renaming=false -o OUTPUT/pretrained_model/ViT-B-32.pt
まとめ
これまでの設定を行うことでgenerate_samples_batch.pyが動作すると思う。
もし動かない場合は私の方の記載ミスの可能性もあるためコメント頂けますと幸いです。また、他にもご質問等あれば気軽にコメントください!
最後に、最近StableDiffutionでAIによる画像生成が注目を集めていますが今回のように音声の方の技術も発展してきています。
DiffSoundの他にもDannce Diffutionというモデルも注目を集めています。
私は博士課程として研究をする傍ら、インディーゲーム制作を行っているため、一人では大変な絵の作成や効果音、BGMの作成などをAIが行ってくれると大変助かります。
最近のAIによるクリエーターのサポートについて心配する声をよく聞きますが良い点を見てみると今まで大手企業でしか作れなかった大きなプロジェクトを個人または中小企業で作成できる可能性も広がるため、エンタメ界隈全体が賑わっていくのではないのかとポジティブに私は予想しています。
(もちろん学習データには著作権フリーのものを使うなどが必要ですが。)
引用
【Unity バグ修正】Scene移動先でUIフォーカスがFirstSelectedに設定したものと異なる
本記事のテーマ
「UIフォーカスがFirstSelectedに設定したものと異なる」問題の解決
制作環境
・Unity2021.3.0.f1
不具合解析
本ゲームはCheckPointScene→MazeSceneという流れになっています。
■現象
CheckPointからMazeSceneへ移動後、EventSystemのInspectorにあるFirstSelectedに設定されているButtonにフォーカスが当たっていなかった。

■原因
CheckPointからMazeSceneへ↑矢印キーで移動しながら扉の中に入ってシーンが移動します。その際、Scene移動後すぐに↑矢印キーの入力が入っており、FirstSelectedの上にあるButtonにフォーカスが移動していた。
修正方法
■修正方法1
First Selectedに割り当てたButtonのInspector内になるButtonComponentのNavigation項目をNoneにしてキー入力によるフォーカスを移動しないようにする。

■修正方法2
ScriptからEventSystemComponetを使用して制御する。
(例)
GameObject firstSelect;
EventSystem.current.SetSelectedGameObject(firstSelect);
感想
パッと見では分かりにくいバグであるが、知っていればどうといったことのないバグだったので気づいた時は閃いた感があって嬉しかった。
UIフォーカスという単語自体、はじめは知らなかったので独学の欠点が出てしまった。
また一つ成長できました。
カメラを用いた指認識コントローラーの作り方②指認識【Unity, Mediapipe, Websocket】

本記事のテーマ
指に連動してキャラクターが動くアプリを制作する。
制作環境
・Unity2020.3.26.f1
・Mediapipe Python
・NodeJs
本記事ではPythonで指認識を行い、Websocketサーバーへキャラクターの移動量を送信する機能の作り方を説明します。
■前記事
カメラを用いた指認識コントローラーの作り方①リアルタイム同期通信【Unity, Mediapipe, Websocket】 - 人工知性を作りたい
仕様書(指認識コントローラー)
■機能
1. 指の形を認識する
”1”、”2”、”3”、”4”、”5”、”OK”、キツネ”、”いいね”
※上記以外は”1”とする
2. Pythonスクリプトを起動したときに指認識で動かすオブジェクトを生成
画像の黒い球
3. 手を”1”にしたときの人差し指先端を基準位置として、指の移動量を計算する
4. 3で計算した移動量を随時Websocketサーバーへ送信する。

作成したコード
・JavaScriptsフォルダ:Websocketサーバー用
・Pythonフォルダ:指認識(Mediapipe)、Websocketクライアント用
・Unityフォルダ:リアルタイム同期通信アプリ、Websocketクライアント用
GitHub - hiro877/FingerController-Unity-Mediapipe
実行方法
GitHub - hiro877/FingerController-Unity-Mediapipe
上記のコードをダウンロードする。
1. mediapipe Pythonの環境を構築する(手順は下記サイト参照)
MediaPipe in Python - mediapipe
2. JavaScriptsフォルダ内のws.jsを起動する
$ node we.js
3. UnityHub→リストに追加でUnityProjectsフォルダを選択し起動する。
4. 1で作成した環境からPythonフォルダ内のclient.pyを実行する。
※Pythonなどで必要な求められたパッケージをインストールしてください。
作り方
指認識にはMediapipeのhand trackingを使用します。
コードはKazuhito00さんが作成しているサンプルを編集しています。
■元コード
・sample_hand.py
https://github.com/Kazuhito00/mediapipe-python-sample
■完成コード
・Python/client.py
実装手順
0. sample_hand.pyをダウンロード
1. 指の形認識の処理を追加
2. 指の移動量の計算処理を追加
3. Websocketへの送信
1. 指の形認識の処理を追加
下記記事で説明されているJavaScriptのコードをPythonに置き換えました。
すみませんが、内容については把握していません。
ご存知の方はコメント欄で教えください!
MediaPipe 入門 (6) - 指ポーズの検出|npaka|note
■実装部分
Python/client.py
・calcDistance()
・calcAngle()
・cancFingerAngle()
・detectFingerPose()
2. 指の移動量の計算処理を追加
detectFingerPoseで指の形を認識します。
基準値となるx, y座標を記録するorigin_posを定義しておきます。(初期値は空リスト)
最初のみ、認識した指の形が”1”のときorigin_posに基準値となるx, y座標を記録します。
2回目以降は現在の人差し指の位置と基準値との距離を計算して、基準値で割ることで正規化(-1 ~ 1の間に収める)をしています。
■実装コード
finger_pose = detectFingerPose(landmark_point)
if finger_pose == "1":
if origin_pos:
cv.circle(debug_image, origin_pos, 5, (0, 0, 255), 2)
cv.circle(debug_image, index_finger_pos, 5, (0, 0, 255), 2)
finger_x, finger_y = (origin_pos[0]-index_finger_pos[0])/origin_pos[0], (origin_pos[1]-index_finger_pos[1])/origin_pos[1]
data["pos_x"] = -1*finger_x
data["pos_y"] = finger_y
ws.send(json.dumps(data))
result = ws.recv()
else:
origin_pos = index_finger_pos
cv.circle(debug_image, origin_pos, 5, (0, 0, 255), 2)
else:
origin_pos = []
3. Websocketへの送信
まず、起動後にWebsocketサーバーとのコネクションを確立します。
次に、指認識で移動させるオブジェクトを生成するJsonデータを生成します。
その後は、カメラが指を認識している間Websocketサーバーへ移動量を送信します。
最後に、生成したオブジェクトを退出させる処理をスクリプトが終了する直前に行います。
以上、ご参考になると幸いです!
質問などは下のコメント欄でお待ちしております!
分かりにくいなどのクレームもお待ちしております!
カメラを用いた指認識コントローラーの作り方①リアルタイム同期通信【Unity, Mediapipe, Websocket】

本記事のテーマ
指に連動してキャラクターが動くアプリを制作する。
制作環境
・Unity2020.3.26.f1
・Mediapipe Python
・NodeJs
概要(設計)
カメラで人差し指の位置を認識し、指の動きに連動してアプリ上のキャラクターを動かす。
使用技術
指認識:Mediapipe
データ送信:Websocket
キャラクターを動かすアプリ:Unity

作り方
今回つくるWebsocket通信と複数アプリ間のキャラクターの位置の同期は以下のサイトを元に作成しました。
ですので基本的には下記サイトを参考に作ってください。
本記事では追加説明を記載いたします。
また、参考サイトには誤字や脱字があったので修正しています。
完成したコードをGithubにおいていますので動かない際はお手数ですが私のGithubのコードと比較しながら作成してください。
■誤字脱字、説明不足パターン
※細かい差分などを覚えていないのでコメント欄でご質問いただけますと幸いです。
・オブジェクトの名前がコードないと異なる。
・オブジェクトの配置位置が記載されていない
・UserLoginDataクラスを作成していない状態で使用するためErrorが発生。
Unity初心者がawsサーバーとWebSocketを使ってのリアルタイム同期通信について学ぶ①
Unity初心者がawsサーバーとWebSocketを使ってのリアルタイム同期通信について学ぶ②
Unity初心者がawsサーバーとWebSocketを使ってのリアルタイム同期通信について学ぶ③
完成コード
追加説明
③追加するプラグインの配置
参考記事①のWebsocketに関するプラグインの配置です。
・Network.Json.dll
Unity2020からはNetwork.Json.dllと同等の機能のパッケージが入っており、新しく追加しなくても↓のパッケージが使用できます。
・websocket-sharp.dll
Ubuntuでwebsocket-sharp.dllを作成するためにMonodevelopを使用しました。
手順:
1. websocket-sharpのgit repogitoryをダウンロードする。
GitHub - sta/websocket-sharp: A C# implementation of the WebSocket protocol client and server
2. monodevelopをインストールする
下記サイトのUbuntu18.04の手順でUbuntu20.04にダウンロードできました。
3. monodevelopをアクティビティから開き,websocket-sharpをBuildする。
手順は下記サイトを参考。ファイル→開く→1でダウウンロードしたファイル内のwebsokcet-sharp.slnを選択する。
Exampleファイルを削除後、Releaseを選択してBuildする。
Nodejsのインストールと設定
インストールは参考サイトから転載
git clone https://github.com/creationix/nvm.git ~/.nvm
source ~/.nvm/nvm.sh
vi .bashrc(下記を追加)
--------------
# nvm
if -s ~/.nvm/nvm.sh ; then
source ~/.nvm/nvm.sh ;
fi
-------------
nvm ls-remote
nvm install v16.13.2
nvm use v16.13.2
node -v
npm install ws
この後node ws.jsを実行するとMODULE_NOT_FOUNDとなったので下記サイトを通りにPATHを通してあげると動いた。
Node.jsで、存在するはずのmoduleがrequireでエラーになることについて - Qiita
websocketのIPアドレスを指定する
nodejsで立てるサーバーのIPアドレスを確認する。
UbuntuだとIfconfigコマンドで確認できる。
残りの手順は次の記事にて記載いたします。
「Mediapipeによる指認識〜Nodejsを通してアプリに位置情報を送信する」
以上、ご参考になると幸いです!
質問などは下のコメント欄でお待ちしております!
分かりにくいなどのクレームもお待ちしております!
Raspberry PiでMediapipeをPythonで使用する【pipでインストール】

本記事のテーマ
Raspberry PiでMediapipeをpipでインストールする
下記問題の解決
・RasbianOSではpipでMediapipeをインストールできない
・python-opencv-contribをインストールすると強制終了する
概要
今回はラズパイでpip installするためのwheelというものを作ってくださっている方がいるという情報を得ましたのでその方法を使用します。
主な流れは下記記事を参考にしました。
Raspberry Piで手軽にMediaPipeを楽しむ方法
RasbianOS(64bit)のインストール
Raspberry Pi Imagerを使ってSDカードに焼いているのですが、64ビットのRasbianがありませんでした。
記事によると以下からダウンロードできるということでお借りしました。
(こういう情報をどこから知るんでしょうか...?)
Index of /raspios_arm64/images

※今回は2021-10-30-raspios-bullseye-arm64.zipを使用
(raspios_arm64-2021-11-08/)
ダウンロードしたZipファイルをRaspberry Pi ImagerのCHOOSE OS→USE CUSTOMから選択します。
起動後、とりあえずお作法として
sudo apt-get update && sudo apt-get upgradeしています。
スワップファイルの拡張
pipでpython-opencv-contribをインストールするためにスワップファイルの拡張を行います。(これをしないと私は強制終了されてインストールできませんでした。。)
方法は下記を参考にしました。
ラズパイ(Raspbian Jessie)とスワップメモリ容量の変更(環境設定の続き) - 今日も微速転進
☆引用
エディタで/etc/dphys-swapfileを開き、CONF_SWAPSIZE という行の値を変更。例えば2048MB(2GB)なら以下のように変更。
CONF_SWAPSIZE=2048
設定したいSwapのサイズをMB単位で指定。
$ sudo systemctl stop dphys-swapfile $ sudo systemctl start dphys-swapfile
systemctl経由でstop/start する。実際に呼び出されるのは/etc/init.d/dphys-swapfile。 なお、swapの容量を変更した直後は内部でddコマンドが呼び出されるので非常に時間がかかります。
最後にfree -hで意図した容量に設定されているか確認。
$ free -h
total used free shared buffers cached
Mem: 862M 833M 28M 6.3M 36M 656M
-/+ buffers/cache: 140M 721M
Swap: 2.0G 0B 2.0G
-hは人間が読みやすい単位で出力するというオプション。
mediapipeのwheelを取得
今回の1. Binary typeはDebian/Bullseyeです。
v0.8.4/numpy120x/mediapipe-0.8-cp39-none-linux_aarch64_numpy120x_debian11_download.sh

下記コマンドを実行してインストールします。
$ sudo apt update && \
sudo apt install -y python3-dev protobuf-compiler python3-pip git make libssl-dev
$ sudo pip3 install pip --upgrade
$ cd && git clone https://github.com/PINTO0309/mediapipe-bin && cd mediapipe-bin
$ ./v0.8.4/numpy120x/mediapipe-0.8-cp39-none-linux_aarch64_numpy120x_debian11_download.sh
$ sudo pip3 install *.whl
$ sudo pip3 install opencv-python
この時、libcblas.so.3が見つからないというErrorが出たので下記を追加しました。
$ sudo apt-get install libatlas-base-dev
下記サイトを参考にしましたので他に足らないものがあればインストールしてみたら改善するかもしれません。
【Raspberry Pi】Raspberry Pi Zero WにOpenCVの環境を構築する - ソースに絡まるエスカルゴ
Sampleを動かす
以下コマンドで実行できます。
$ cd && git clone https://github.com/Kazuhito00/mediapipe-python-sample
$ cd mediapipe-python-sample
$ python3 sample_hand.py
この時model_complexityが見当たらないと言われたので#でコメントアウトすれば動くようになりました。
hands = mp_hands.Hands(
# model_complexity=model_complexity,
max_num_hands=max_num_hands,
min_detection_confidence=min_detection_confidence,
min_tracking_confidence=min_tracking_confidence,
)

以上、ご参考になると幸いです!
質問などは下のコメント欄でお待ちしております!
Raspberry PiでMediapipeの環境構築とBuild、Run【フリーズ問題解決】

本記事の特徴
・OpenCVのセットアップでフリーズ
・ハローワールドのビルドでフリーズ
上記の問題を解決します。
本記事のテーマ
【Raspberry PiでMediapipeのビルドが止まる問題の解決!】
・exampleにあるHallo Worldを動かす
環境構築からHalloWorldの手順
主に公式のInstallationの通りに行うのが良いと思います。
他の日本の方がまとめているサイトで参考にしたのは下記のサイトです。
※追記:問題1と問題2を同時に解決する方法
スワップファイルを拡張することで解決できました!
ラズパイ(Raspbian Jessie)とスワップメモリ容量の変更(環境設定の続き) - 今日も微速転進
☆引用
エディタで/etc/dphys-swapfileを開き、CONF_SWAPSIZE という行の値を変更。例えば2048MB(2GB)なら以下のように変更。
CONF_SWAPSIZE=2048
設定したいSwapのサイズをMB単位で指定。
$ sudo systemctl stop dphys-swapfile $ sudo systemctl start dphys-swapfile
systemctl経由でstop/start する。実際に呼び出されるのは/etc/init.d/dphys-swapfile。 なお、swapの容量を変更した直後は内部でddコマンドが呼び出されるので非常に時間がかかります。
最後にfree -hで意図した容量に設定されているか確認。
$ free -h
total used free shared buffers cached
Mem: 862M 833M 28M 6.3M 36M 656M
-/+ buffers/cache: 140M 721M
Swap: 2.0G 0B 2.0G
問題1:OpenCVビルドでフリーズ
Installationの3Install OpenCV and FFmpeg.のOption2であるsetup_opencv.shを実行すると途中でフリーズするという現象に会いました。
試行錯誤した結果、viなどでsetup_opencv.shを以下のように変更するとフリーズせずにビルドが通るようになりました。
77行めのmake -j 16を -j4に変更する。(使用する並列処理の数を減らす)
77 make -j 16 → make -j 4
78 sudo make install
79 rm -rf /tmp/build_opencv
80 echo "OpenCV has been built. You can find the header files and libraries in /usr/local/include/opencv2/ and /usr/local/lib"
問題2:bazel runでフリーズ
問題1と同様にjobsを下げてみたがそれでもフリーズした。
調査した結果、bazelには--jobsだけでなく,--local_ram_resourcesでCPUのリソースの調整もできるらしい。
少しずつCPUの使用率を減らしていった結果、次のパラメータでビルドが通るようになった。(しかし2回失敗した後、3回めで成功。)
# cd ~/mediapipe
export GLOG_logtostderr=1
bazel run --copt -DMESA_EGL_NO_X11_HEADERS --copt -DEGL_NO_X11 \
mediapipe/examples/desktop/hello_world:hello_world --jobs 4\
--local_ram_resources 280
ramのリソースは使用するラズパイのCPUによって変わるため、コマンド(free -h)を用いて最大使用できるCPUリソースを確認してから減らすと良いと思います。
・freeコマンドの使い方(サイト内のメモリ容量参照)
Linux のメモリ容量・CPUコア数・ディスク容量を確認する - 猫でもわかるWebプログラミングと副業
参考文献
・bazelのjobsリファレンス
Command-Line Reference - Bazel main
・bazelのlocal_ram_resources
Command-Line Reference - Bazel 0.23.0
以上、ご参考になると幸いです!
質問などは下のコメント欄でお待ちしております!
ホログラムディスプレイを作ってみた(Unity、100均材料、IPad、ペッパーズ・ゴースト)
本記事のテーマ
「ホログラムディスプレイを作ってみた」
よめ子さんというYoutuberの方の動画に感化されて作ってみました。
普段プログラミングという目に見えないものづくりしかしていないので久々に段ボールを切ったりしたりするのが新鮮で楽しかったです。
・よめ子さんの動画
作り方
下記の動画を参考に作りました。
私が使用したもの
・透明な下敷き(ダイソー)※CDケースの代わり
・黒の厚紙(ダイソー)
・段ボール(スーパーから無料でもらう)
・グルーガン(ダイソーにもある)
完成品画像
・正面


・横(段ボール3枚)

・裏面

関連記事
Unityで3D映像を表示するアプリを作る際にいくつか課題にぶつかりましてその解決方法を別の記事にまとめています。
【Unity】背景の色が開発環境(黒、Linux)と実機(白、IPad[IOS])で異なる問題解決
背景の色を黒に設定したのですがIPad (IOS)で実行すると白になってなんでだろう〜と考えて半日ぐらいかかったので解決方法を共有します!
本記事のテーマ
「背景の色が開発環境(黒、Linux)と実機(白、IPad[IOS])で異なる問題解決」
動作環境
- 開発:Ubuntu20.04
- 実機:IPad
不具合解析
解析結果
下記画像のUbuntuの背景設定(メインカメラのBackground)でアルファ値(A)を0にして透明にしてしまっていた。

IPadとの比較のためにAndroidでもアプリをビルドして確認していたのですがAndroidでは背景が黒になっていました。
ですので、どうやら背景を透明にした場合Linux、Androidでは黒、IPadでは白になるようです。
この結果は個人的にとても興味深かく、Linux, AndroidとIPadではViewレイヤーなどの作り方が違っていて背景を透明化することでデフォルトの色が出てきているのかなぁーと想像しました。
最後に
Linuxの上にAndriodが作られているのでViewの構造などは同じになっている確率が高く感じます。そういった観点でも上記の考察を捉えることができるので個人的に面白い発見となる課題解決になりました!
皆さんの興味深かった不具合などありましたらコメント欄で共有いただけますと嬉しいです。
【Unity】外部コントローラの入力キーが異なる問題解決「開発環境(Linux)と実機(IPad, IOS)」
外部コントローラのキー入力を使う際、開発環境(Linux)では上手くいくのに実機(IPad, IOS)では上手くいかなかったのでその時の解決方法をもとに説明していきます!
本記事のテーマ
「外部コントローラの入力キーが異なる問題解決「開発環境(Linux)と実機(IPad, IOS)」」
動作環境
・開発環境
Ubuntu20.04
Unity
・実機
IPad
・使用コントローラ
dualshock 4(PS4のコントローラ)
解決方法
結論から申し上げますと、無料Assets「Controller Tester」を使うだけです。
使い方は簡単で新しいUnityプロジェクトにControllerTesterをImportしてビルドするだけです。
手順
まず、IPadでController Testerアプリを使うためにIOS用にビルド後、MacBookなどのXcodeが使える環境に作成したフォルダをコピーします。
その後、フォルダ内にある「Unity-iPhone.xcodeproj」ファイルをダブルクリックしてXcodeで開きます。
開いたら、Signing情報を設定した後ビルドして実機でアプリを立ち上げます。
Dualshock 4とIPadの繋ぎ方は真ん中下にあるPlayStationマークとSHAREボタンの長押しでコントローラが点滅するまで待ってください。
すると、IPadのBlueTooth設定画面にDualshockが出てきますのでタップするだけでつながります。
IPad内でのDualshock 4のキーコード対応表
実際にボタンとキーコードの対応関係をまとめましたのでよければお使いください。

最後に
IPadとコントローラをつなぐという経験は初めてだったので開発環境で動いていたものが実機で動かないという問題に気づくのが遅れました。
同じ問題で困っている人の助けになれば良いなと思います。
(自分もまた同じ問題にぶつかるかもしれないのでその時はこの記事を見返します笑)
ご質問等あれば下のコメント欄でおまちしております!
Controller Testerの画面
丸ボタンのキーコード
・UbuntuのUnityエミュレータ
キーコード:1

・IPadアプリ
キーコード:13

Tensor.kthvalueの動作概要

Tensor.kthvalueの使い方について公式のDocumentではよく分からなかったので自分で動作確認した結果をまとめる。
・公式ドキュメント
本記事のテーマ
「Tensor.kthvalueの動作概要」
について実動作確認した結果をまとめる。
関数の説明
x.kthvalue(n, dim=1, keepdim=True)で動作確認をおこなった。
kthvalueはn番目に小さな値を抽出する関数です。
dimで選択した次元を探索します。
動作確認
動作確認した結果を紙にまとめました。
例として作ったTensorは
x: Tensor
x.shape: (2, 3, 6)
x[0]:
[[ 1, 2, 3, 1000, 5, 6]
[ 7, 8, 9, 10, 11, 12]
[13, 14, 15, 16, 17, 1000]]
x[1]:
[[ 19, 20, 21, 22, 23, 24]
[ 25, 26, 27, 28, 29, 30]
[ 31, 32, 33, 34, 1000, 36]]

x.kthvalue(3, dim=1, keepdim=True)を実行すると、写真の左の図に記載されているように1次元目を縦に探索して3番めに小さい数字、1次元目のサイズは3なため、最も大きい数字を探索していることになる。(x[0次元目][1次元目][2次元目])
結果は3番めに小さい数字とその数字が格納されているIndexの配列をTupleとして出力してくれる。
torch.return_types.kthvalue(
values=tensor([ 13., 14., 15., 1000., 17., 1000.,
31., 32., 33., 34., 1000., 36.]),
indices=tensor([2, 2, 2, 0, 2, 2,
2, 2, 2, 2, 2, 2]))、
■indecesの見方
dimで1次元目を探索するようにしているため、x[1次元目]に当たるIndexの数字が出力される。
つまり、唯一0になっている箇所を確認すると、x[0][0][3]=1000で1次元目のIndexは0なので出力結果のindecesも0になる。他も同様に確認すると全て2になることが分かる。