grbl1.1+Arduino CNCシールドV3.5+bCNCを使用中。
BluetoothモジュールおよびbCNCのPendant機能でスマホからもワイヤレス操作可能。
その他、電子工作・プログラミング、機械学習などもやっています。
MacとUbuntuを使用。

CNCマシン全般について:
国内レーザー加工機と中国製レーザー加工機の比較
中国製レーザーダイオードについて
CNCミリングマシンとCNCルーターマシンいろいろ
その他:
利用例や付加機能など:
CNCルーター関係:



*CNCマシンの制作記録は2016/04/10〜の投稿に書いてあります。


2018年5月27日日曜日

Ubuntu 18.04 LTS: ファイアウォール、ファイル共有、画面共有、SambaやVNCなど(Macと)

MacとUbuntuでファイル共有しているので、その設定の覚書。
・ファイアウォールを設置する
・ファイアウォールで特定の通信を許可する
・Sambaへの登録
・MacからUbuntuへアクセス(smb://~)

ついでに、画面共有も(vnc://~)。
・MacからUbuntuを覗く
・UbuntuからMacを覗く


Ubuntuへのファイアウォール設置:
Ubuntuソフトウェアから「gufw」で検索し、

ファイアウォール(gufw)をインストールし起動。
要管理者パスワード。

設定画面でステータスを「オン」。
このままだと外部からのアクセスはできなくなるので、以下の方法で特定の通信を許可する。

「ルール」タブをクリック。
画面下の「+」を押して特定の通信を許可する設定を追加。

一番下の空欄へ「smb」を入力すると「アプリケーション: SAMBA」が選択される。
「追加」を押して終了。これでSambaによる通信が可能となるようです。


Ubuntu側のファイル共有設定をする:
Ubuntu側のホーム以下にあるPublicとPicturesを共有することにします。
まず、「Public」を右クリックで「ローカルネットワーク共有」を選択。
そうすると以下の画面。
とりあえず3箇所にチェックを入れて制限を緩めにしておく。
同様に「Pictures」など他のディレクトリも共有したい場合は同じようにチェックを入れておく。
一旦閉じて、再度「Public」を選んで中身を見る。
右上の「共有の設定」を押す。Sambaがインストールされていなければ「サービスのインストール」でインストールする。

「共有の設定」が押されると「設定」の「共有」へジャンプし、
ここで「ファイル共有」をクリックし、
パスワード入力やネットワークをオンにしておく。
以上で共有するディレクトリの設定は終了。
基本これだけでもファイル共有可能。


Sambaへユーザーとパスワードを登録:
ターミナルを起動し、Sambaステータス確認。

service smbd status

以下のような感じでステータスが出てくる。

次に、ユーザーとパスワードを登録しますが、登録名はUbuntu上のユーザー名と同じにしなければいけないようです。

sudo pdbedit -a username

を入力すると(usernameはUbuntu上のユーザー名)、ルート管理者パスワード入力のあとSamba用パスワード設定を求められるので入力設定(Ubuntuルート管理者パスワードとは異なってもOK)する。これで登録終了。
Ubuntu上のユーザー名以外を登録しようとすると、

Failed to add entry user username

と最後に出てきて登録失敗します。
ちなみにSambaに登録したユーザーの削除は以下。

sudo pdbedit -x username

Samba登録者リストの表示(登録されているかどうか確認)は以下。

sudo pdbedit -L

を入力すると、

username:1000:username

という感じで登録者が表示される。
より詳細にリスト内容を表示させるには-vをつけて、

sudo pdbedit -L -v

を入力。
以上でSambaへの登録終了。

もしSambaの再起動が必要なら以下。

systemctl restart smbd nmbd


MacからUbuntuへアクセス:
Macのメニューバー>移動>サーバへ接続...(Command+K)

「サーバアドレス:」へ「smb://UbuntuのIPアドレス」を入力。

smb://192.168.3.7

UbuntuのIPアドレスを調べるにはUbuntu上のターミナルで「ifconfig」を入力。
「127.0.0.1」はlocalhostなので、次にある「192.168.x.x」など。

ゲストで接続(パスワードなし)なら「ゲスト」を選択し「接続」。


また、Sambaの登録ユーザ+パスワードで接続する場合は以下。

Ubuntuの管理者パスワードを入力してもダメと言われるのでSamba用パスワードを入力。
接続すると、
ボリューム選択の画面へ。Ubuntu側では「Pictures」と「Public」の二つのディレクトリを共有化しているので、この二つが出てきます。
「Public」の方を選ぶと、
このようにMacのデスクトップ上にマウントされます。
ファインダーでは以下ような感じ。
画面右を見るとMac上に「Public」がマウントされており、「ネットワーク>192.168.3.7」以下には「Pictures」と「Public」もあります。
画面左の「共有」には「192.168.3.7」があり、画面右の「ネットワーク>192.168.3.7」に対応しています。
マウントされたのは「Public」でしたが、Ubuntu側では「Pictures」と「Public」を共有化しているため結局は両方にアクセス可能。あるいはゲストでも登録ユーザーでも同じ結果。
「共有」の「192.168.3.7」をアンマウントすると接続解除


しばらくすると再接続できなくなる:
接続解除したあと再接続しようとすると接続できなくなることがあります。
先ほどは「Finder>移動>サーバへ接続...(Command+K)」で、

smb://192.168.3.7

を入力して接続しましたが、以下のように接続失敗してしまいます。

どうやらUbuntu側のサーバがダウン(タイムアウト)しているようで、Ubuntu側のターミナルで、

systemctl restart smbd nmbd

を入力すればサーバが再起動されてMac側からサーバを認識できるようになるようです。

追記:
どうやらWifiドライバのせいで接続が途切れるようで、それについては以下。

Wifiが途切れる(解消)/ Ubuntu 18.04LTS / MSI GS43 GTX1060 / QCA6174



VNCによる画面共有/MacからUbuntuを覗く:
Ubuntuの「設定>共有」で「画面共有」をアクティブにする。

チェック項目、パスワード設定、それぞれをオンにしておく。

次にファイアウォールの設定。
一番下の空欄に「vnc」を入れると「アプリケーション:VNC」になります。
「簡易」タブをクリックし、「ポート:5900」などと任意のポート番号を入れておきます。「追加」、「閉じる」で設定終了。


Macのほうで、「移動>サーバへ接続...」から、
「vnc://UbuntuのIPアドレス」を入力して「接続」。

設定したパスワードを入力して「接続」。

少し反応が鈍いですが、MacからUbuntu上のターミナルも操作できます。


VNCによる画面共有/UbuntuからMacを覗く:
Macの「システム環境>共有」から、「画面共有」にチェックを入れておく。
そうすると「画面共有:オン」の下に「vnc://192.168.3.2/」などとアドレスが表示されるので、後でそのアドレスをUbuntu側で入力する。Macの設定は以上。

次にUbuntu側。
Ubuntuソフトウェアから以下をインストール。
「Remmina」というのもありますが、こちらの「デスクトップビューアー」が使いやすかったです。

起動すると以下の画面。
「VNC」を選び、その下にMacのIPアドレスを入れるだけ。
画面サイズ設定にチェックを入れ「接続」。

表示される前に、Mac側のユーザー名とパスワードを入れて「認証」を押す。
そうすると以下のように表示されます。

とりあえずウィンドウ内に映し出しサイズなど調整してからフルスクリーンにするといいと思います。
フルスクリーンでは、向こう側の画面を操作することが優先されるため画面を元に戻せなくなりますが、画面中央上部にマウスを持っていくと隠れスイッチが出てくるので、そこで元の画面に戻ることができます。

2018年5月25日金曜日

Ubuntu 18.04 LTS:各種設定・機能拡張(Extensions)など

Ubuntu 18.04インストール後、いくつかのセッティングをしました。今後インストールし直すときもあるかもしれないのでカスタマイズした設定の覚書。


日本語入力・切替え:
普段Macも使っているのでスペースキーを中心に、[英数][スペース][かな]の三つのキーで切替入力変換できるように[無変換][スペース][かな]のキーへ割り当て。

とりあえず以下から。
「日本語(Mozc)」だけでも日本語変換は可能でしたが、「日本語(OADG 109A)」を入れないとキー配列が日本語キーボードとずれてしまうので両方入れました。

デスクトップのメニューバー右端を見るとこんな感じででてきます。

最初は上下で日本語と英数を切り替えるのかと思っていたら、「日本語(Mozc)」だけを使って切替えるようです。普段は下の「日本語(OADG 109A)」には切り替えないらしい。これは単にキー配列のためだけに入っているのかもしれない。クリックでこれに切替えると半角英数のみで日本語切替してくれないため、挙動が変ならここをチェックしてみるといいのかもしれない。
ちなみに、何もしていないときに入力切替しても何も起こらず、実際に入力を行っているとき(画面などにフォーカスを与えて)にはじめて切替可能となるようです。試しにキーボード押して何も起こらないからといって焦らないように。

キーマッピング:
そして入力切替のためのキーマッピングですが、上画像のプロパティをクリックすると以下の画面が出てきます。
左画面下のほうの「キー設定の選択」で「MS-IME」を選んで「編集」を押すと、「MS-IME」ベースのキーマッピングをカスタマイズできるようです。ただし一つでも変更すると、「カスタム」という名前になってしまうようです。
今回は右画像にあるように、[Muhenkan]キーと[Hiragana]キーの二つに追加でマッピングしてみました。
英数に切替えるには、とにかく「IMEを無効化」すればいいようです。日本語の場合は、「直接入力」の時だけ「IMEを有効化」し、そのほかは「ひらがなに入力切替」にすればいいようです。基本的にはこの4種類の状況においてマッピングすればいいようですが、同じキーが使われていないかこのリスト内をチェックする必要があります(同じキーがある場合はその項目を削除)。
これで、Macのように日本語切替できるようになりました。


Homeディレクトリ以下を英字表示に変更:
日本語化してしまうと、ホーム以下にあるデスクトップ、ドキュメント、ダウンロードなどのディレクトリ名も日本語になってしまいcdコマンドなど使う際に面倒になるので、それらを英字表記に変更。

LANG=C xdg-user-dirs-gtk-update

をターミナルから入力して変更。変更内容について再度確認してくるので、「Don't ask me this again」にチェックを入れつつ「Update Names」をクリックして再ログイン。
そうすればこのように各ディレクトリが英字表記に切り替わります。
左側の「ホーム」と「デスクトップ」だけはなぜか変わらないけれども特に問題ない。


GNOME Tweaksをインストール:
GNOME Tweaksを使うとより細かい設定ができるようなので、「Ubuntuソフトウェア」から「gnome tweaks」で検索しインストール(sudo apt install gnome-tweak-toolでも構わない)。

通常使用している「設定」ではできないことが可能になりますが、「機能拡張」欄にあるようなGNOME Shell Extensionsを追加していくことでかなりカスタマイズできるようです。

現在はこのようなExtensionsを入れてあります。これらの一部は「Ubuntuソフトウェア」の「ユーティリティ」などからもインストールできますが、「GNOME Shell Extensions」というサイトに行けばもっと見つかります。


GNOME Shell Extensionsからインストール:
GNOME Shell Extensions(要ログイン)に行きキーワードで検索すればたくさん機能拡張が出てきます。すべてクリック操作なので気軽にインストールできます。
こんな感じで「Installed extensions」というページに行けば、パソコンにインストールしてあるExtensionsと同期して機能のON/OFF、設定、アンインストールがブラウザ上でできます。
特に気に入ったものが以下です。


これは画面上部のトップバーにアプリメニューバーを組み込む機能拡張です。
通常トップバーにはアプリの操作メニューがでてこないため、もう一段下にアプリ用メニューバーがでてくるところ、その二段をひとつにまとめてくれます。
特にChromeを開いているときには、Chromeのメニューバーが出てこないため不便でしたが、これを使うことで表示するようになりました。
こんな感じでMacと同じように「ファイル 編集 表示・・・」という感じでトップバーに現れます。他のアプリでも同じように現れてくれるので便利です。
ただ、Ubuntu 18.04の場合は最新のものを
からダウンロードし、解凍したファイルの中身を
~/.local/share/gnome-shell/extensions
の中に入れる必要があります。さらに、そのままでは設定ができないので、ここに書いてあるように
sudo apt install gir1.2-clutter-1.0 gir1.2-clutter-gst-3.0 gir1.2-gtkclutter-1.0
で依存ファイルをインストールすれば問題なく動きます。


NO Title Bar:
これはタイトルバー(アプリウィンドウ上部のバー)を消す機能拡張。ならびに、左上に設置したウィンドウボタンの位置も変えてくれます。
以下はAtomエディタを使った場合ですが、通常トップバー、タイトルバー、メニューバーの3段構成になって上2段が無駄に見えます。

しかし、先ほどのGnome global Application menu(HUD for Gnome)と合わせて使うと、以下のように1段にすっきりとまとまってくれます。
もともと、トップバーやタイトルバーが無駄だと感じていたので、これで納得です。

できるだけ一本のバーにまとめたいということから、似たようなもので「Dash to Panel」や「TaskBar」という機能拡張もあります。MacのDockのようにお気に入りのアプリなどを入れておくことができるトップバー(あるいはボトムバー)になり、さらにアプリのメニューもいっしょに入れることもでき、トップバー、Dock、メニューバーを一本化できます。試しにやってみましたが、アプリメニューもバーに入れてしまうと、あまりにもごちゃごちゃしたのでやめました。


Extensions:
これは、インストールしたExtensionsをトップバーからのメニューでON/OFF/設定できる機能拡張です。
GNOME Tweaksでも可能なのですが、手っ取り早く設定できるのであると便利です。一番下のAdd gnome shell extensions...をクリックすればサイトへ飛んでくれます。
一時的に機能を中断したり、Extensionsの品定めしているときには便利。


Gno-Menu:
トップバーからアプリなど選択できるメニューの機能拡張。グリッド状に複数のアイコンが配置されるため探しやすい。主なディレクトリ、最近使った書類、頻繁に使うアプリ、ブックマークなどもある。最近更新されたようでワークスペース選択もできる多機能。

トップバーにはこのMenu(上画像では足跡マーク)以外にもViewやAppsも追加できる。ViewやAppsは場所がとられてしまうので、最低必要なMenuだけでも十分。
このGno-menuだけでもたくさんのことができる。つい欲張って多機能にしようとすると煩雑になってくるので、必要な部分だけを使うと言う感じ。もともとトップバー左端には「アクティビティ」というクリックエリアがあったけれども、それも消してしまいました。


Dash to Dock
DashをDockに追加させるだけでなく、Dock自体いろいろ調節できる機能拡張。
Dockはデフォルトのままだと融通が効かないのでこれもExtensionsでなんとかならないかと。
トップバーとメニューバーの一本化はできたので、あとはよく使うアプリなどをいれておく場所なのですが、さきほどのGne-MenuがあるのでもはやDock自体あまり必要なさそう。ただ、以前もよく使っていたのでできれば使いたいという感じ。
画面左上に主な機能が集中しているので、今回もまた画面左にDockを設置することに。
・ダッシュを一番上に配置(たぶんあまり使わない)
・アプリ画面最大化(あるいは重なると)の際にDockが自動的に隠れる
・マウスを左端に持って行けば再びDockが出てくる
・Dock上でマウスホイールを動かすとworkspace移動
というくらいでしょうか。サイズ、色や透明度も変えられ、デフォルトよりは細かく設定できます。

左:Dockが隠れている時、右:マウスを画面左端につけるとDockが飛び出てくる。
もともと、トップバー1本(ボトムバーなし)にできるだけ機能を集中させ、必要に応じてDockが左から出てくるようにしたかったので、これで大体想定していた構成になりました。あとは以下にあるような細かなパーツをトップバーに組み込む感じ。


Clock override:
トップバー上の時計のフォーマットを自由に変えられる機能拡張。
年/月/日/曜日/時/分/秒の表示が可能。そのほか任意の言葉なども表示できます。
デフォルトだと年が表示できなかったような。


Show Desktop Button:
デスクトップを瞬時に見ることができるトップバー上のボタン。上画像真ん中の家型のボタン。


WorkspaceBar:
ワークスペースを移動するためのトップバー上のボタン。上画面左端。
ほかにもWorkspace用の機能拡張はいくつかあるのですが、これが使いやすそうでした。現在のワークスペースの数、そしてワンアクションで行きたい番号をクリック。マウスホイールでも移動可能。
ただしこのままだと設定をクリックするとバグってしまう。少し古いタイプなのか、gtk2.0開発環境をインストールしてみることに。

sudo apt-get install libgtk2.0-dev

でインストールすると無事設定ができるようになりました。以下が設定画面。位置が調節可能。
もしかすると、少し古いタイプでもgtk2.0を入れれば動くのかもしれません。


Trash:
ゴミ箱をトップバーに表示する機能拡張。
以前はDockの一番下の方にあったゴミ箱だけれども、Ubuntu17.04あたりからデスクトップの任意の位置に表示され、どこに置こうか迷ってしまう。というよりも邪魔なのでゴミ箱を非表示にして、そのかわりにこのTrashをトップバー上に置いてすっきりさせました。
一応トップバーから空にする/開く/中身の確認も可能です。
いつも不要ファイルを右クリックしてゴミ箱に入れているので、デスクトップ上になくても特に問題なし。


GDebi Package Installer:
Ubuntuソフトウェアからインストールするdebファイルインストーラアプリ。

いままではdpkgコマンドを使ってdebファイルをインストールしていましたが、gdebiコマンドを使うと依存関係も解決しながらインストールできるようです。それのGUIアプリで、ダウンロードしたdebファイルを選択してインストールボタンを押すだけなので使いやすい。


Atom editor:
普段使っているエディタ。前から使っているのでダウンロードしておきましたが、Ubuntuソフトウェアからインストールすると日本語入力できないAtomになってしまいます。再度、https://atom.ioからdebファイルをダウンロードして先ほどのgdebiでインストールし直したら日本語入力できるようになりました。
ちなみに、Anaconda NavigatorからはVSCodeが簡単にインストールできます。VSCodeのほうが軽快に動くので、そっちのほうがいいかもしれません。
Dockへのランチャー登録は、DashからAtomを見つけ出し右クリックで登録するか、ターミナルでatomと入力して起動するとDockにアイコンがでるのでそのまま右クリックで登録。


Polo File Manager:
二窓のファイルマネージメントアプリ。
複数のフォルダ間のファイル移動やコピーなど多い時は便利。


Obmin:
ワンクリックでファイルシェアリングできるHTTP(HTTPS)ファイルサーバー機能拡張。
トップバーからオンにすると、他のPCのブラウザ上からアクセスできるようになります。
ブラウザを通して画像など閲覧/ダウンロードできるので便利です。
これは設定画面ですが、共有したいディレクトリやフォルダを複数追加できます。チェックを外して停止させたり、サーバごとオフにすることも簡単にできます。
ちなみに他のPC上のブラウザ(http://192.168.3.2:8088にアクセス)からはこのように見えます。必要なファイルをダウンロード(あるいはドラッグ&ドロップ)するだけです。


Firewall Configuration:
Ubuntuソフトウェアから入手できるgufwというファイアウォール機能拡張。
起動と同時にパスワード入力が必要。設定画面内でオンにすればいいだけ。
ただし、ローカルネットワーク内でのファイル共有をするには、オンにしたあとに「ルール」ボタンを押して設定を追加(+ボタン)する必要がある(設定が面倒であれば一時的にオフにするしかない)。

関連:
Ubuntu 18.04 LTS: ファイアウォール、ファイル共有、画面共有、SambaやVNCなど(Macと)


まとめ:
いろいろカスタマイズするのは楽しいのですが、あまりにも機能を積み込みすぎると重くなりそうなので、できるだけ少なくしてみました。
結果的には大体頭に思い浮かべていたような感じにはなりました。個人的にはGnome global Application menu(HUD for Gnome)を使うことでトップバー周辺がすっきりしたのが一番の収穫。
MacとUbuntuの2台使っているのでファイル共有はあると便利。
GNOME Shell Extensionsにはたくさんの機能拡張がありますが、古いものの多く必ずしも動くとは限りません。しかし、gtk2.0など古い開発環境などインストールしておけば(sudo apt-get install libgtk2.0-dev)少しは動くかもしれません。

2018年5月22日火曜日

Ubuntu 18.04 LTSへアップグレード(不具合無事解決)

ようやく待望のUbuntu18.04LTSにアップグレードしました。



手持ちのパソコンは、MSiゲーミングノートパソコン(GeForce1060)であり、当初Ubuntu16.04LTSをインストールしたかったのですが、相性が悪いのかフリーズしまくりで、たまたま不具合の起こらない16.10をインストールしました(17.04、17.10も不具合発生)。
しかしながら、16.10はもうすでにサポートが切れており、必要なドライバやモジュールを自力で探してインストールしなければいけなくて大変でした。
そこで待望の18.04LTSが先月リリースされたので早速アップグレードしようと思いましたが、CUDAには正式に対応していないようだったので様子見していました。

現在CUDA9.2までリリースされていますが、Tensorflow1.8はまだCUDA9.0にしか対応しておらず、しかもCUDA9.0はUbuntu17.04までの対応なので、この組み合わせが難しいところ。ネットで検索してみると、Ubuntu18.04LTSにCUDA9.0をインストールしてTensorflow1.8も動く例を発見したので、今回ようやくアップグレードすることにしました。

またもやインストールで問題発生:
クリーンインストールしようと思いUSBメモリにイメージファイルをいれて起動させてみると、画面には現れるがクリックできないという現象が発生。
日本版、英語版の両方を試してみましたが、入力インターフェースのドライバの不具合なのかクリックが効きません。

試しにBIOSをアップグレード(特に効果なし):
クリックできない対策として、MSiゲーミングパソコンのBIOSをアップグレードする方法というのが見つかったので、試しにやってみることに。
・MSi BIOS更新方法
各型番に応じたサポートページに行くと、新しいBIOSが今月更新された模様。

USBメモリに解凍したダウンロードデータを入れ(他のデータが入っていても大丈夫)、BIOS画面内でデータを選択してアップデートするという手順。

再度Ubuntu18.04LTSインストールにチャレンジ:
BIOS更新後、USBメモリから起動してみましたが相変わらずクリックが効かない。そのままフリーズすることも。
USBメモリで起動する際に、

Try Ubuntu without Installing
Install Ubuntu
OEM install (for manufacture)
Check disk for detects

という選択肢がでてきて、通常は一番上の「インストールせずに起動」を選んでUbuntu内でGUIを使ってインストールするわけですが、2番目のいきなり「Ubuntuをインストールする」を選択してみました。
そうすると、インストール画面に移行しました。どうやらクリックできるようです(安心、しかしまだ何があるか分からない)。
今回は標準インストール(最小インストールという選択肢もある)で。ひと通り設定項目を入力して、再起動。
さてどうなるか?

相変わらず不具合:
しかし、不具合はまだ続く。ログイン画面でパスワード入れてリターンを押すとフリーズしてしまう。
一応、ある程度の入力、マウス操作ができるようになったので、さっきよりはまし。

リカバリーモードで起動:
さて次の方法は、起動の際に、
Ubuntu
Advanced options for Ubuntu
がありますが、通常は一番上で普通にUbuntuを起動するところ、二番目を選択して、リカバリーモードで起動させます。
リカバリーモードで起動すると解像度の低い画面が出てきます。そうすると、クリックできないとかフリーズするとか不具合は発生しないようなので、ターミナルを起動して
sudo apt-get update
sudo apt-get upgrade
でアップグレードしてみました。
そうすればいくつかバグ修正されて直るかもしれないので。

普通モードで起動(結果不具合解決):
恐る恐る普通モードで起動してみると、まずログイン成功。これはいけそうという予感。
無事、デスクトップが現れて、フリーズやクリックできないなどの不具合は解決されました。
他に不具合がないかいろいろ探ってみましたが、いまのところ大丈夫そうです(安心)。
これでなんとかロングタームサポートのUbuntuを利用できる状態になりました。

各種インストール:
CUDA関係:
CUDAは、Tensorflowの関係から9.0をインストール。Ubuntu 17.04用です。
以前はdebファイルからインストールしていましたがエラーがでるので、runファイルでインストールすると大丈夫でした。ちなみにドライバは390のままで、384はインストールしませんでした。インストール途中でサンプルもインストールするか聞かれますが、一応yesにしておいたほうがよさそうです。

CUDA 9.0
・cuDNN 7.1.2 for CUDA 9.0



Python関係:
・pyenv
・Anaconda
・Python3.6
・Tensorflow-gpu 1.8.0
・Pytorch 0.4.0

そのほか:
・Chrome
・Atom Editor
・dconf Editor
・gnome Tweaks


まとめ:
今回のインストールも不具合に遭遇しましたが、なんとか無事成功できてよかったです。一番の収穫はサポート切れのUbuntu 16.10からLTS(ロングタームサポート)に移行できたことでしょうか。これでしばらくは安心して使えそうです。
もしかしたら、以前もリカバリーモードでバグ修正していれば16.04LTSが使えたのかもしれません。
Linuxは不具合が多いので、毎回いろんな対処方法をしているうちに勉強になるという感じです。
おかげでBIOSも最新にアップデートできたということもあるので、このような不具合が起こらなければ、そんなこともしていなかったでしょう。


2018年5月2日水曜日

Bayesian Optimization / Gaussian Process

前回、matplotlibのアニメーションについては大体使えるようになったので、「ベイズ最適化・ガウス過程」を実験してみました。いろいろと専用のライブラリがあるのですが(GPy、GPFlow、Edward、Pyroなど)、今回はscikit-learn Gaussian Processesを使っています。

ベイズ最適化はハイパーパラメータチューニングに使われるようで、ブラックボックス関数における最大値(あるいは最小値)を全領域をスキャンしなくても探し出すことができる方法のようです。

今回の場合は、グラフ内の赤破線の最大値がどこにあるか探索しています。赤破線を見ると、左と右にピークが二箇所ありますが、微妙に右側のほうが高いという設定にしてあります。それを間違えないように探し出せるかという実験です。
右側の赤丸が正解(最大値)の地点です。この地点は、x座標-2〜2までの範囲を0.1刻みで200回スキャンし、その結果から最大値を求めています。
しかし、ベイズ最適化の場合は、200回スキャンしなくても約10回程度で、どこが最大値なのかを効率よく探してくれるようです。

今回の手順として:
・カーネル:Matern、獲得関数:UCBを選択
・xの範囲(-2〜2)からランダムにまず2点(青丸:start印)選んで初期観測値とする
・その観測値から、全域のμ(青破線)とσ(青塗)を求める
・μとσを獲得関数(UCB)に代入
・獲得関数の結果(緑実線)から最大値の箇所を見つける
・獲得関数の最大値から、それに相当するxの位置を見つける
・xの位置から、それに相当するyの位置を求める
・ここで求めたxとyの座標を次回の探索箇所にする
・次回探索箇所を観測値リストに加える
・あとは繰り返し

グラフ下部(緑実線)にあるのが獲得関数UCBの値です。緑実線の一番高いところが、次の探索地のx座標となります。
今回使用したUCBの中身は単純で、

UCB最大値 = mu + kappa * sigma

となっています。係数kappa=1.0の場合は、μ値(青破線)にσ値(青塗)を足した値がそのままUCB最大値となるので、グラフ内の青塗を含めた一番高い箇所が次の探索箇所となります。μ値が高いところほど選ばれがちですが、kappaを大きくするとσ値も大きくなるので、μ値が低い箇所でも探索される可能性があがります。


%matplotlib inline
import numpy as np
from matplotlib import pyplot as plt
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import Matern
import matplotlib.animation as animation
from IPython.display import HTML

np.random.seed(111)

def f(x):
    return -np.sin(x*4.5)*x*0.3+0.02*x                  # 真の関数(赤破線表示)

x = np.linspace(-2,2,200)                               # x値範囲
y = f(x)                                                # 真のy値

fig = plt.figure(figsize=(12,6))                        # 画面サイズ設定
ax = plt.subplot()                                      # サブプロットを用意
ax.axis([x.min(),x.max(),y.min()*2,y.max()*2])          # グラフ範囲設定(x,yの値に依存)
ax.set_aspect(1.0)                                      # アスペクト比設定

ax.plot(x,y,'r--',alpha=0.8)                            # 真の関数曲線をプロット(赤破線)
ax.plot(x[np.argmax(y)],y.max(), 'ro',alpha=0.8)        # y正解値;x全域スキャンによるy最大値(赤丸)

init_pt = 2                                             # 初期観測値個数
xi = np.random.uniform(x.min(),x.max(),init_pt)         # 初期観測値:xの範囲から2箇所ランダム選択
yi = f(xi)                                              # 初期観測値:yの値
ax.plot(xi,yi,'bo')                                     # 初期観測値プロット(青丸)
for i in range(len(xi)):
    ax.text(xi[i],yi[i],'  start'+str(i),color='b')     # 初期観測値:'start'文字表示

def UCB(mu_x, sigma_x, kappa=1.0):                      # 今回使用する獲得関数:upper_confidence_bound
    return mu_x + kappa * sigma_x                       # kappa増大-->σ増大-->探索領域拡大

kernel = Matern(length_scale_bounds="fixed")            # 今回使用するカーネル:Matern
gp = GaussianProcessRegressor(kernel=kernel,alpha=0.01) # scikit-learnガウス過程回帰オブジェクト

ims = []                                                # アニメ用リスト
itr = 15                                                # 探索ループ回数

for i in range(itr):
    gp.fit(xi[:,None],f(xi))                                 # 観測値フィッティング(xiをリシェイプして代入)
    mu_x, sigma_x = gp.predict(x[:, None], return_std=True)  # μ(x)とσ(x)を獲得(事後分布)

    a_x = UCB(mu_x, sigma_x, kappa=2.0)                      # UCBでa(x)最大値を得る
    index = np.argmax(a_x)                                   # a(x)最大値のindexを得る
    x_next = x[index]                                        # a(x)最大値のindexから次のx探索値を決定
    y_next = f(x_next)                                       # y探索値決定
    
    P1 = ax.plot(x, mu_x, 'b--')                                               # μ値(青破線)
    P2 = ax.fill_between(x, mu_x-sigma_x, mu_x+sigma_x, color='b', alpha=0.2)  # σの範囲(青塗)
    P3 = ax.plot(xi,yi,'bx',markersize=8)                                      # 探索済み箇所(青クロス)
    P4 = ax.plot(x_next, y_next, 'mo')                                         # 現在探索箇所(マジェンタ丸)
    P5 = ax.plot([x_next,x_next],[y.min()*2, y_next] ,'m-', alpha=0.6)         # 現在探索箇所(マジェンタ縦線)
    P6 = ax.plot(x_next,(a_x[index]-a_x.min())/2+y.min()*2, 'go',alpha=0.8)    # a(x)最大値:σ(青丸)
    P7 = ax.plot(x, (a_x-a_x.min())/2+y.min()*2, 'g-')                         # 獲得関数値:a(x)
    P8 = ax.plot([xi,xi],[[y.min()*2]*len(yi),yi], 'b-', alpha=0.2)            # 探索済み箇所(青縦線)
       
    xi = np.r_[xi,x_next]                                  # 現在探索箇所をリストに加える(r_: concatenateの代用)
    yi = np.r_[yi,y_next]
    
    ims.append(P1 + [P2] + P3 + P4 + P5 + P6 + P7 + P8)    # アニメ用リストへ各プロットを入れる
    
print('x :',x[y.argmax()], '   y :',y.max())               # 正解値出力(y値)
print('xi:',xi[yi.argmax()], '   yi:',yi.max())            # 最終最大値出力(yi値)

ani = animation.ArtistAnimation(fig, ims, interval=1000)   # アニメ関数
#ani.save("gp_sim.gif", writer = "imagemagick")            # GIFアニメ保存
plt.close()
HTML(ani.to_html5_video())                                 # HTML5 Video 出力(mp4ダウンロード可)
#HTML(ani.to_jshtml())                                     # JavascriptHTML 出力

GaussianProcessRegressor()にはカーネルを指定する箇所があり、今回は、scikit-learnのMaternを使っています。ちなみにカーネルを指定せずデフォルトのままだと、以下のような感じになります。
σ(青塗)の領域が結構変わります。
scikit-learnのこのページにカーネルの違いについて書いてあります。

ハイパーパラメータチューニングと言っても、カーネルの選び方でもかなり違いがでてきます。
また、獲得関数もUCB以外にいくつかあるので、それも選ばなければいけないという感じです。


参考にしたサイト:
Scikit-learn Gaussian Processes
llSourcell/hyperparameter_optimization_strategies
ベイズ最適化入門
機械学習のハイパーパラメータ探索 : ベイズ最適化の活用

関連:
GPyOpt: Digital Recognizer(MNIST) CNN Keras ハイパーパラメータ最適化

人気の投稿