selecao3のブログ

技術系の備忘録

PC(Windows10)からラズパイへ有線でSSHログインする

経緯

アルバイトで表題のことをすることになったため

やること

Windows10側の設定をちょっと弄ってteratermSSHログインする

やったこと

PCとラズパイをLANケーブルで繋ぎ、Windows10側で

  1. コントロールパネル>ネットワークとインターネット>ネットワークと共有センター>アクティブなネットワークの表示の右側にある"イーサネット"をクリック
  2. イーサネットの状態という画面が表示される。下のプロパティをクリック
  3. 下の項目からインターネットプロトコルバージョン4を一度だけクリックし、右下のプロパティをクリック
  4. 次のIPアドレスを使うをクリックし、IPアドレスに任意のIPアドレス(例えば、ターゲットの静的IPアドレスが133.68.10.2なら133.68.10.3とか)を入力、サブネットマスクには255.255.255.0を入力し、OKをクリック

これでteratermを起動し、ターゲットのIPアドレスを入力すると行ける・・・はず

ちなみに

Windows10上でVMware使ってUbuntuを起動していて、Ubuntuからsshログインしたいなら、上記の設定は必須である。(土台のWindows10の設定に問題があるなら、その土台に乗っているUbuntuは永遠にラズパイと接続できない)
なお、VMware上のOSは特に設定せずにDHCPからIPアドレスを指定する方法で、VMware上のOSからSSHログインすることができる。

グローバル変数の問題点メモ

これ is 何?

よくグローバル変数は良くないと聞くがなぜそれがダメなのかの具体例

経緯

最近、バイトで「この書き方はクソコードだよ」とふんわりと教えてもらったので。

本題

よくグローバル変数はヤバいと聞く。結論から言うと、関数と関数の関係が密になりやすいからである。例えば

filename = "hoge.txt"

function init_file()
     local time = tostring(os.date("_%H%M%S"))
    filename = "hoge"..time..".txt"
    local f = io.open(filename, "w")
    if f == nil then
        io.stderr:write("failed open file")
        return nil
    else
        f:write("header hoge\n")
        return f
    end
end

function write_to_file(file, mes)
	file:write(mes.."\n")
end

function close_file(file)
	file:write("close file\n")
	file:flush()
	local ret = file:close()
        if ret == nil then
           local ret = false
        end
	return ret
end

function execute_cat_file()
    local ret = os.execute("cat "..filename)
    if ret == nil then
        local ret = false
    end
    return ret
end

こんなLuaコードを書いたとする。一見問題なさそう、むしろinit_file()したらグローバル変数のfilenameに格納されて、他の関数にfilenameを入れることなく使えて楽やん。と、思ってしまう(少なくとも自分は思っていた)
が、このコードには2点問題がある。

  1. init_file()しないと他の関数は使えない点。例えば、execute_cat_file()したいだけなのにわざわざinit_file()しないとダメ
  2. 他のfilenameが使えない。例えば、hoge_100001.txtを生成した後にhoge_100010.txtをinit_file()で生成した場合、hoge_100001.txtは上書きされてしまうので扱うことができなくなる(closeしてないやんっていう問題もあるが)

つまり、最初に話した通り密な関係になってしまう。じゃあどうすればええねんっていうと、

  1. グローバル変数削除
  2. init_file()内でファイルを開く処理を削除。
  3. write_to_file()以外の全ての関数の引数にfilenameを追加する。

以上の3点である。グローバル変数を引数にすることで各関数を疎の関係にする。
外部で生成したいファイルの名前を生成してもらうことになるが、こっちの方が使い勝手が良い。

まとめ

グローバル変数使った時は無意識に密な関係になっていてアレなコードになっている可能性がある。引数で使えるようにして疎な関係にしよう。

URLブロッカー日記1

何を作るのか

Android端末であるURLにアクセスすると、そのURLがもしブロック対象ならアクセスする前にブロックするAndoroidアプリ

URLブロッカーを作る経緯

1日にTwitterをおそらく数時間見てるので、Twitterをやめたい。
でも、Twitterをやめる気はない(矛盾)なので、アプリの力を借りて禁止薬物をやめるのと同じ要領でやめようと決意

具体的には(ロジック)

Android->Chrome->URLブロッカー(local proxy server)-> ルーター
プロキシサーバをAndroid内に立てて、特定のURLならブロックする。という感じで。

必要そうなもの

プロキシサーバの知識(chromeからのパケットを受け取る仕組み)

現状の問題点

スマホWi-Fi設定で、localhostのproxy serverに向かうようにしたらインターネットに繋がらなくなる。
というか、URLブロックするのにローカルでプロキシサーバ立てる必要はあるのか。これがわからない

全く日記を更新してなかったので、無理矢理ネタを引っ張り出して更新した。このBlogを開設した時の「1週間に1回はブログを更新する」という崇高な意識はどこへ行ってしまったのか。

VScodeでデバッグしたら変数が表示されなかった

環境

  • GCE(Debian 9.9)
  • VScode insider(1.36)
  • Rust(1.38.0-nightly)
  • lldb(3.8)

VScode拡張機能一覧

  • CodeLLDB(1.2.3)
  • Rust(rls)(0.6.1)

問題点

VScode(insider)でRustのコードをデバッグした際、左側の変数が表示されなかった。

f:id:selecao3:20190719104914p:plain
赤枠のローカル変数の部分が表示されなかった

結論

lldbのバージョンが古すぎたのと、python-lldbがインストールされていなかった。
sudo apt install python-lldb-6.0
sudo apt install lldb-6.0
をコンソール上で実行すれば解決。

経緯

VScodeでRustのデバッグ環境がないのツラすぎるっぴと思い始めたので下記のサイト様を参考にデバッグ環境を作成。
qiita.com
作成して、いざテストコードを走らせてみたらRegisters以外何も表示されていない現象が起きた。
調べまくると以下のissueに辿り着いた
stackoverflow.com
lldbのバージョンが古すぎると動かんぞとのこと。
いや、わいはちゃんと
sudo apt install lldb
ってやったし最新版がインストールされてるはずやと思っていたが
sudo apt search lldb
としてみるとlldb-6.0というものがあった。トラップかなにかか?
というわけで
sudo apt remove --purge lldb
sudo apt install lldb-6.0

とすると、python-lldbがインストールされてへんぞと怒られたので
sudo apt install python-lldb-6.0
sudo apt install lldb-6.0

としてデバッグを開始したところ、左側の変数が表示されるようになった。

備考

デバッグ環境の必要性

以下、淡々と

  • デバッグが必要な状況:重めの開発。フレームワーク抜きで自作で1000行とか書いてたりするようなプログラムとか(?)
  • デバッグが不必要な状況:軽めの開発。フレームワーク有りで自分は100行ぐらいしか追記していないようなプログラムとか(?)。print関数で大抵のバグが取れるようなもの。

以下、だらだらと
以前は簡単なWEBアプリしか作成していなかったため、「デバッグ?printで十分やろうがい!?」と考えていたが、最近、DeepLearningのモデル開発という重めな作業を始めてからはprintでいちいち確認するのがしんどい(どころか無理)と思うようになってきた。
プログラミングめちゃつよマンが作ったエディタ上でデバッグ環境を作成したうえでデバッグ機能を使うと、自動的に変数の中身が分かり、どのタイミングで変数に値が代入されたかなどが分かる。
授業の課題並のコードや軽いアプリ開発ならprintで十分だと思うが、重めの開発はprintだけではバグが取りきれない可能性があるのでそういう場合はデバッグ環境を整えた方がええんでないでしょうか

Google Console Engineやってみた(SSH接続でつまづいた)

なにこれ

Google Console Engine(以下、GCE)をやってみた。が、ローカルPCからSSH接続ができないという問題が発生した。
今回はそれの対応のメモ

結論

最初に結論を書くと以下のことを行うとSSHができた。

  • GCEのVMインスタンスインスタンス名>上部の編集をクリックし、下にスクロールして、SSH 認証鍵付近にあるテキストボックスにローカルPCの公開鍵をコピペ
  • ブラウザでVMにログインし、別のユーザーを作成した。

解決できるまでの問題点

以下の問題でSSH接続が出来なかった。

追記:id_rsaの公開鍵はダメかもしれない。
ssh-keygen -t rsa -C "{鍵の名前}"
で作成して、GCEに登録して、
ssh {鍵の名前}@{VMの外部IPアドレス}
としないとダメかも

  • ~/.ssh/authorized_keysが消える。

なんでやねんである。ブラウザからVMにログインしてから一定時間経つと~/.ssh内のファイル全てが削除されていた。そのせいでローカルPCからSSH接続が出来なかった。
この問題はVMで別のユーザーを作成すると解決した(削除されなくなった)。

  • 直接authorized_keysに編集してはいけないことを知らなかった。

直接編集してはいけないらしい。もしかすると、こいつを直接編集したからauthorized_keysが削除されたのか?(編集してなくっても削除されていたが・・・)
参考URL:
cloud.google.com

根本的に自分がsshキーについてあまり詳しくないのを痛感させられた(大感並)

誤差逆伝播法についてメモ

何これ

誤差逆伝播法について、なぜ誤差の関数を微分するのかが分からなかったのでメモ

なぜ誤差の関数を微分するのか

ざっくり言うと誤差(損失関数)を変化量から重みを修正するために微分をしている
例えば損失関数が下に凸の二次関数の時、その二次関数から誤差が最小となるパラメータが分かる。
で、どうするねんと言う話だが、そこで微分を使う。その二次関数を微分することでその二次関数の接線の傾き(勾配)が分かる。
すると、その二次関数の最小値から左側では勾配が負になり、その右側では正になる。それらの傾きがゼロになるようなパラメータに修正すれば誤差はゼロとなる。
ちなみに前の記事で勾配が消失するとか爆発するとか言っていた勾配と言うのは微分時の傾きのこと。勾配が異常な値を出すと重みが修正できない=正確に学習ができない