VolumioでSambaサーバーをマウントするときError when adding network drive (95): Operation not supported Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)のエラーが出る

タイトルの通り、VolumioでSambaサーバーをマウントするときに「Error when adding network drive (95): Operation not supported Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)」が出て困っている人のために。

Volumioを使って音楽を聞いているが、最近自宅サーバーを新しくしそこに音楽を入れSambaを使って共有している。
raspberry pi 3 Model Bに入れたVolumioからは普通にマウントできるのだが、Intel NUCに入れたVolumioからはエラーが出てマウントがうまくできなかった。raspberry piと全く同じ設定なのになぜマウントできないのかわからなかった。
もしかしたらx86のVolumioはcifs-utilsとかのパッケージが足りないのではと思ったがそんなことはなかった。
調べてマウントオプションに「vers=1.0」を入れると良いとあったのでつけたけど駄目。

よく考えるとSambaプロトコルのバージョンを確認してなかったので確認した。Sambaのプロトコルバージョンは以下のコマンドで確認できる。

sudo smbstatus -b

確認するとSMB3_00であることがわかった。なのでオプションを「vers=3.0」にしたら無事マウントできた。

同じエラーで困っている人がいたらSambaサーバーでプロトコルのバージョンを確認し、オプションで適切なバージョンを指定してマウントしましょう。

HAP-S1のUSBデジタル出力でTopping D90に出力したかった話

現在、自宅のメインのオーディオシステムはraspberry pi(Volumio) -> Topping D90 -> アンプという流れなのだが、Volumioがどうにも繋がりにくい。
VolumioはIPを固定して使用時に電源を入れ使用後は電源を毎回落としている。
起動して少ししてもブラウザからなかなかVolumioに繋がらなくて地味にイライラする。

今回機会がありSony HAP-S1というHDDプレイヤーを手に入れた。

これは500GBのHDDが搭載されたHDDオーディオプレイヤーで、NASのような働きもできるし、スピーカー出力もあるしと結構1台で手軽に色々楽しめるオーディオ機器だ。以前に使用していたこともあり結構お気に入り。上位機種にHAP-Z1ESというのもあるけど、当時はスピーカー出力がほしかったのであえてS1の方を購入した。

このHAP-S1、中ではLinux OSで動いていて利用しているライブラリを公開している。
oss.sony.net
今度色々試してみたいところ。
実際LinuxならなにかいじれないかとSSHとか色々試したけどだめだった。
nmapでポートを調べたら、
139/tcp open netbios-ssn
445/tcp open microsoft-ds
60100/tcp open unknown
60200/tcp open unknown
60300/tcp open unknown
60400/tcp open unknown
137/udp open netbios-ns
1900/udp open upnp
が開放されていた。139、445、137はsamba関係。1900はSSDP用。60000番台はプライベートで、60100~60400を使って専用アプリと通信している様子。
ssdpでの応答を調べる。wiresharkでパケットを調べるとhttp://{IPアドレス}/hap.xmlに通信の仕様が書かれたxmlがあるらしく確認するとリソース等が見えた。
http://{IPアドレス}:60100/HAP.htmlに一応ブラウザからの操作用htmlファイルがあるのがわかる。
バージョンが3つあり最新は2.0の用でHAP-S1をブラウザからコントロールできる。
60200ポートでコントロール用のリクエストを受け取る感じ?基本POSTだけで、一部GETもあった。


関係ない話が長くなったが、今回VolumioをやめてHAP-S1に移行を考えた。
HAP-S1はソフトウェアアップデートでUSBデジタル出力に対応したのでこれをTopping D90に入力すれば特に問題ないかなと思っていたがそんなことはなかった。出力されるのはノイズだけで、かすかに音楽が聞こえるぐらい。明らかにおかしい。
まあ、HAP-S1のデジタル出力はSony製の一部に対応としていたのでこれは仕方のないこと。
調べてみると同じ症状の人が少し見つかる。
どうやらDDコンバーターを噛ませるとよいとのこと。
そこで同じくToppingの安価で評判の良いD10sを購入した。

構成は HAP-S1 -> D10s -> D90 -> アンプ という感じ。半信半疑だったが無事に音楽が再生された。音質に関してはVolumioのときとは雰囲気が違うが劣化している感じはない。できればDDコンバーターを挟まずに構成したかったがそれは難しそうだ。

HAP-S1とTopping D90を使った構成を考えている人の役に立てば幸いである。

めでたしめでたし


それにしてもなぜだめなのか。HAP-S1のUSBデジタル出力をTopping D90に入力するとUSB入力というのは検出できるがサンプリングレートが明らかにおかしくなっている。送信するデータの形式が違ってDSDやPCMのフォーマットを誤認識している?それでもかすかに音楽が聞こえたのでそれは違う?
このあたりに詳しい人に是非お聞きしたいところである。

Volumioをディスプレイに出力してマウス操作する

自分は音楽を聞くときにメインでVolumioを利用している。
メインで1台、テレワーク用のデスク用に1台、それぞれraspberry pi 3で運用している。
Volumioにはプラグインでタッチディスプレイに出力しタッチ操作できるようにすることができる。デスクではネットワークの関係上、ブラウザ操作ではなくディスプレイでの操作がしたかったのでこのプラグインを利用した。プラグインのインストール方法等は別の人の記事を参考にして欲しい。

自分は安く以下のディスプレイを入手できたので使ってみた。Volumioを入れたraspberry piで表示とタッチ操作の確認ができたのを報告しておく。

電源供給もraspberry piからできるのでケーブルがraspberry piへの電源ケーブルのみでスッキリして便利だった。

上記ディスプレイはスピーカーも搭載しているようだがそれは試していない。スピーカーは別途安いやつを使っている。

これをraspberry piに直差しして簡易的なデスク用音楽環境を構築している。

いざこれをデスクで利用するとタッチ操作は悪くなかったが、別にタッチで操作する必要がないことに気がつく。
いちいちディスプレイに手をのばす必要があるし、正確にタッチできないこともある。別にマウス操作でいいのでは?

試しにVolumioを入れたraspberry piにUSBマウスを接続してみたがカーソルは出ない。やっぱりだめかと思ったがマウスを動かしてみると反応はある。どうやらカーソルが見えないだけでマウス操作はできる様子。カーソルが見えなくても操作はできるが少々やりにくい。どうにかしてカーソルを表示できないかと調べたら無事にカーソル表示ができた。

sudo nano /lib/systemd/system/volumio-kiosk.service

を実行してファイルを確認する。すると下の方に

ExecStart=/usr/bin/startx /etc/X11/Xsession /opt/volumiokiosk.sh -- -nocursor

という部分があり、これの -- -nocursorがカーソルを消す設定のようだった。この部分を削除して再起動(プラグインのリロードでもいいのかも?)したらカーソルが表示される。

めでたしめでたし。

MacBook Pro 13inch late2018で3台の外部ディスプレイを使用する

MacBook Pro 13inch late2018から外部ディスプレイ3台を接続するために試したこと・解決策について、同じことをしようとしている人たちのために。

自宅の環境を整えウルトラワイドの大きめのディスプレイを2台購入した結果、MacBook Pro本体が邪魔になりクラムシェルでの使用を余儀なくされた。

今までは外部ディスプレイ2台とMacBook Proの画面1枚でのトリプルディスプレイを構築していたが、それをクラムシェルで外部ディスプレイ3台にしようと思ったわけだ。

色々調べるとMacBook Pro 13inchでは基本的に外部ディスプレイは2台までのようだ(15inchはそうではないらしい)。なので何かしらのエクストラなデバイスなりを使って拡張する必要がある。

MacBook Proでの外部ディスプレイ3台を使用する方法についてググるのは意外と難しかった。「外部ディスプレイ 3台 トリプルディスプレイ 」などのワードではどうもMacBook Pro本体のディスプレイ + 外部ディスプレイ2台といった当たり前の記事しかヒットしない。違う、MacBook Pro本体のディスプレイを使わないトリプルディスプレイを構築したいんだ。

調べるとUSBディスプレイアダプタとやらが必要らしい(ディスプレイを拡張するためのデバイスの名前をそもそもよく知らなかった)。ただ、この「USBディスプレイアダプタ」という言葉も微妙に厄介だった。特にMacBook Proの場合、USBはtype-c(Thunderbolt3)というものになり、ディスプレイを別途拡張するデバイスを探しているのに、「type-c USBディスプレイアダプタ」と検索をするとtype-cからHDMIなどへの変換ケーブルがヒットする。当然これらは今回の目的には合わず、2台の外部ディスプレイしか得られない。

勘違いのしたデバイスの一つがこれだ。

なんとなくだが、別途ディスプレイ拡張するならそれなりの基盤やチップが必要で物理的に大きめなら大丈夫なのではなんて考えていた。上記のデバイスは3台目の外部ディスプレイには対応しておらず、結果的に返品した。ただ、このデバイスは親切に説明にそのことが明記してあり、購入したこちらに責任がある。

多くの「USBディスプレイアダプタ」という単語で引っかかるデバイスには説明がなく、可能性が高そうなのはUSB3.0を用いたもので、これならHDMI ot Display Portなどといった変換ではなくディスプレイを拡張するものであろうが、如何せんMacBook Pro late2018にはtype-c形状のUSBしかなく、USB3.0をtype-cに変換して効果が得られる自身がなくてが出せないでいた。また、これらのデバイスは価格がそこそこするのも問題だ。

また、外付けGPUに期待もしたが、外部ディスプレイのためにはオーバースペックだし、何より外部ディスプレイ2台の制約は超えられないらしくこれもボツ。

ディスプレイのデイジーチェーンなども考えたが、ディスプレイはすでにあるのでThunderbolt3対応ディスプレイの使用等も視野にない。

調べていてこちらの記事にたどり着いた。

discussionsjapan.apple.com

読んでみるとどうやらDisplaylink社のチップの入ったUSBディスプレイアダプタを使用すれば良いらしい。ドライバが必要らしいが、目的を達成できるなら全然構わない。記事のリンクから対応する製品をAmazonで調べる。評判と値段、性能を見た結果、WAVLINK社の下記製品を購入した。


USB3.0ポートの拡張などもついているが、あるに越したことはない。
ドライバをインストールしたら特に問題もなく認識した。これで念願の外部ディスプレイだけでのトリプルディスプレイ環境を構築できた。しかも、こちらのUSBディスプレイアダプタは2台まで対応しているようで、4台目の外部ディスプレイの接続も確認できた。そこまでは必要ないので今のところはクラムシェルでのトリプルディスプレイ環境で使用している。発熱も殆どない(MacBookは熱いがw)。

以上で、念願のクラムシェルトリプルディスプレイ環境を構築ができた。なお、使用しているディスプレイは

といったウルトラワイドディスプレイとEIZO EV2736という古いディスプレイを使用している。捗る。

AdaCos: Adaptively Scaling Cosine Logits for Effectively Learning Deep Face Representationsを読んだ

詳細はこちら
qiita.com

以前からArcFaceというmetric learningの手法が優秀なので使っていたが、AdaCosはArcFaceのハイパーパラメータを調整してくれるということで使ってみた。そしたら想像以上に優秀だったのでAdaCosが自分のデファクトスタンダードになった。
ただ気になる点もある。cos(\min(\frac{4}{\pi}, \theta_{med}^{(t)}))ということろがあるのだが、 \theta_{med}^{(t)}が正数になるとは断言できないのではということだ。xとWを正規化しているが、正数にしてはいない。もしも\theta_{med}^{(t)}が負になったら大変である。なので\max(\cos {\theta_{med}^{(t)}, \cos{\frac{\pi}{4}}})としたほうが良いのではということ。式的には論文のほうがきれいかな?もしかしたら見落としがあるかもしれない。

Invertible Grayscale

Invertible Grayscaleを読んで、実装、実験をした。詳細はこちら。

qiita.com

コードなどについてはtrain部分はあまり必要ない気がし、model.pyについてのみ載せた

正直需要もない気がする(手法が手法ゆえ)。
グレースケールに見えれば良いという考えはなるほどと感じた。確かに。
実験してみたが、なかなかうまく行かず、良い初期値を引き当てる必要がある。
グレースケールにするためのGrayscale Conformity Lossがなければすんなりと学習するので、この制約がなかなかきついのだろう。

Learning Confidence for Out-of-Distribution Detection in Neural Networks

クラス分類などで実際にニューラルネットを実際に使うとわかるが、ある入力が特定のクラスである確率が9割を超えていても間違えている事がある。
Adversarial Attackなどを考えればよく分かる。
この論文では、入力に対してクラスラベルの推定と共にその予測分布に対しての確信度も同時に推定する手法を提案している。
入力に対して、クラスAである確率が90%という出力が得られたとしても、確信度が低いものは間違っている可能性がある。
要するにグレーゾーンというわけだ。実システムで使う場合は、確信度の低いものは人が確認するといった手続きになるだろう。でも、そのグレーゾーンがわかることは非常に役立つ。
提案手法は実装もしやすい。

p, c = f(x, \theta)
p_i, c \in [0, 1], \sum^{M}_{i=1}p_i =1

入力 xに対しての出力はクラス確率 pと確信度cを得る。 cはsigmoidを通している。
そして、クラス確率 p_iと入力 xの実際のラベル分布y_iを確信度でブレンドした

p_{i}'=cp + (1 - c)y_i

をネットワークの出力として、この p_{i}' y_iとのクロスエントロピーを誤差として学習を行う。

 \mathcal{L}_t = - \sum^{M}_{i=1}\log(p_{i}')y_i

しかし、このlossだけだとネットワークはc=0とすることで常に正解ラベルを参照でき、lossを0にできてしまう。そこで-\log(c)のペナルティを与える。

 \mathcal{L}_c = -\log(c)

結果として全体のloss関数は

 \mathcal{L} = \mathcal{L}_t + \lambda\mathcal{L}_c

となる。\lambdaは確信度のlossを調整するハイパーパラメータで、確信度のlossの大きさによって学習中に逐一調整を行う。

クラス確率の予測が正確になればなるほど正解ラベルに頼る必要がなくなり確信度が1に張り付いてしまう。そうならないように\lambdaを小さくすることで正解ラベルを参照するコストを小さくする。逆に予測がうまくできない初期状態などは、正解ラベルを参照しすぎ、学習をしなくなるので\lambdaを大きくし、正解ラベル参照コストを大きくする。

つまり、予測に自信が持てないときはコスト( L_c)を払うことで、正解ラベルを使うことができるわけだ。ただ、正解ラベルを使うのにはコストが必要で、これが予測を間違えるよりも安くなければならない。予測を間違えるより、正解ラベルを使うコストほうが高ければ当然正解ラベルを使わなくなり、普通のクロスエントロピー誤差を使った学習と同じになってしまう。


chainerで書くとしたら大体以下のようになるだろう。

# 正解ラベルtはone-hot エンコーディング
y = F.softmax(h_class)
confidence = F.sigmoid(h_confidence)
c = F.broadcast_to(confidence.reshape(batch_size, class_num), y.shape)
y_prime = y * c + t * (1 - c)
loss_classify = - F.mean(F.log(F.select_item(y_prime, t.argmax(1))))
loss_confidence = - F.mean(F.log(confidence)) * lm

h_class、h_confidenceはニューラルネットのそれぞれの出力、tはone-hot形式の正解ラベル、batch_sizeはバッチサイズ、class_numはクラスの数、lmは係数ラムダを表す。
注意点としては2つ。確信度自体の出力はスカラーなのでクラス予測と同じ形のベクトルに変換することと、y_primeはすでに分布になっているのでF.softmax_cross_entropyを使うのではなく、単純にクロスエントロピーをとること。なお、正解ラベルは出力した分布とブレンドするのでone-hotエンコーディングにしておくor 変換する必要がある。

係数ラムダの調整はchainerのExtensionsでlossを見て調整するか、ここで直接調整すればよいだろう。

lm += 0.01 if loss_confidence > 0.3 else -0.01

みたいな感じで。
論文では、確信度誤差を0.3に保つように\lambdaを調整するとあった。e^{-0.3} \fallingdotseq 0.741なので学習データの中に難しいサンプルが25%程度含まれているという事前知識がある気がする。この難しいサンプルの割合が事前にわかっているなら、それに合わせて\lambdaの調整も変えたほうがいいだろう。

実際に使用してみるとなかなか良い。自分がやった実験ではラムダは0.55前後で安定した。
また、面白いことに学習後のモデルのvalidation accuracyが僅かだが上昇した(正解ラベルを混ぜたわけではない)。
予想だが、確信度の低いものは学習に悪影響を与えるサンプルで、それを学習に使用しなかった(確信度を下げ、正解ラベルのみ使う)ことで、より良い特徴を捕らえられたのでは。データセットクリーニングに近いのかもしれない。

あいかわらずひどい日本語だ...