ソフトウェアエンジニアの勉強ログ

興味があるのは、computer vision, three.js, python, 深層学習, emacs

自分用メモ:C,C++経験者がpythonを一から勉強する2(逐次更新)

pythonプログラム

  • import sysのうえ、sys.argvでコマンドラインの入力にアクセスできる
  • import moduleで読み込めるが、module.関数という呼び方をしないといけない
  • from A import functionとすると、使いたい関数を直接importする
  • import long_module_name as hogeみたいな呼び方もできる
  • パッケージという考え方
    • __init__.pyというファイルがあるディレクトリを、パッケージとみなして、import対象なる

辞書の使い方

  • setdefault()関数やdefaultdict()関数を使って、例外のときの値出力を簡単に記述できる
  • Counterによる要素数の計算(from collections import Counter)
  • OrderedDict(from collections import OrderedDict)
  • deque
    • pop, popleft, append, appendleft
  • itertools
    • tertools.chain, itertools.cycle

オブジェクト

  • 継承したときにメソッドは完全にオーバーライドされる
    • 親クラスの処理をしたかったら、super()を呼ぶ
  • メソッドは追加できる
  • property
  • 非公開属性の名前のマンダリング
    • __prop_nameでマンダリングして、@propertyと@var_name.setterでデコレートするのが良さそう。
    • selfとクラス名を使い分けると、クラスで一つの変数を扱うことができる(C++のstaticメンバ変数)
    • @classmethod, @staticmethodを使う(デコレート)
    • vars関数を使うとプロパティがわかる
  • 特殊メソッド
    • 要するにoperatorのオーバーライド
__eq__, __ne__, __lt__, __gt__, __le__, __ge__, __add__, __sub__, __mul__, __floordiv__, __truediv__, __mod__, __pow__, __str__, __repr__, __len__
  • __str__などは便利だろう
  • コンポジションの方がリーダブルなコードがかける。つまり、子メンバー変数にオブジェクトを持つ
  • モジュールはシングルトンとして振る舞う

文字列

自分用メモ:C,C++経験者がpythonを一から勉強する1

基本事項

  • ブール、整数、float、文字列
  • //は整数の除算
  • **は指数
  • 基数は、0bが2進数、0oが8進、0xが16進
  • 整数型への変換はint()関数で、浮動小数点への変換がfloat()関数、文字列への変換はstr()関数
  • int型はpython3では任意のサイズなので大きさの上限を気にしなくて良い

文字列について

  • 文字列リテラルに関して、”と'の両方を表現したいときに、"""もしくは'''で囲うことができる。さらに、改行文字を入れることができる。
  • +を使った連結
  • *を使って繰り返し
  • []による文字の抽出
  • [start:end:step]による文字の切り出し
  • len関数による文字列の長さ
  • splitとjoin、joinは感覚と使い方が違うので注意が必要
  • strip関数は、デフォルトで空白などを削除する。文字を指定した削除も可能。
  • Cでprintf("%10d", x)などとするが、文字列に対して、str.center(30), str.ljust(30), str.rjust(30)
  • replace関数で文字を書き換える。正規表現は後ほど。数を指定しないと最初の一回のみの置換になってしまう。

リスト、タプル、辞書、集合

リスト

  • ほぼ配列
  • [ ]もしくはlist()で作成
  • array.append(new_elem)で末尾に要素追加
  • extend()関数もしくは+=や+で、リストを連結
  • insertで場所を指定して挿入
  • delで要素を指定した削除。del array[-1]のように使う。
  • removeでmatchする要素を削除
  • popでオフセットして切り出しながら削除
  • index()で要素のオフセットを知る
  • list.index(query, index)で0始まりの順番を指定できる。マイナスも指定できる
  • inで有無のテスト、countで個数を数える
  • copyの方法は、list.copy(), list(list), list[:]
    • copyのリスト関数はpython3からのようだ

タプル

  • 要するに、定数リストで初期化したら変更不可
  • ()
  • タプルのアンパック
    • そもそも、pthyonは、a,b,c = 1,2,3のような記述ができる
  • tupple(list)関数でタプルを作れる

辞書

  • 要するにstd::mapに近い
  • {}
  • dict()汎用関数を使って、タプルやリストを辞書にできる
  • [key]による追加、アクセス
  • get関数でアクセスできる。無い場合はNoneが返ってくる。C++のatと挙動が異なるので要注意。
  • update()辞書関数によって、辞書の結合ができる。
  • del ditct[key], dict.clear(), key in dictが使える
    • joinといいちょっと気になるが仕方がない
  • keys(), values, items()
    • 全て参照用の特殊な型(dict_keysなど)になるので注意

集合

  • 初期化にはset()関数を使う。
    • リストやタプル、辞書(キー)を使える
  • 集合演算を使えるのが良さそう。
演算子 意味
& 積集合
| 和集合
- 差集合
^ 排他的OR
<= 部分集合チェック
>= 上位集合チェック
> 真上位集合チェック

コードの書き方

  • \によって行を継続できる。逆にいうと、1行に意味がある。
  • ネストする場合は、:を使う?
  • if, elif, else
  • while
    • whileの弟にelseを用意すると、breakが呼ばれなかった場合の処理を記述できる
  • for文
    • for letter in wordやfor item dict.items()のように使う
    • for文に対してもelseが使える
    • zip()を使えば、複数のシーケンスを並列的に反復処理を行えるし、それ以外にもlist(zip(list1, list2))みたいなことができる
    • range()関数は便利なので使いこなせたほうが良い
  • リスト内包
    • 結構なれない感じ
    • [expression for item in iterable]
    • [expression for item in iterable if conidtion]
    • [[val1, val2] for val1 in hoge for val2 in fuga]
  • 辞書内包や集合内包もある

  • 関数

    • 関数の定義にはdefを使う
    • 位置引数でも良いし、キーワード引数でも良い
    • デフォルト引数もできるが、実行時ではなく、「定義」されたときであることに注意
    • 以下のように返り値を複数持てる
def func2():
    return 1, 2, 3
a, b, c = func2()
  • *によって位置引数をタプル化して渡せる
  • **によって、キーワード引数を辞書化できる
  • 関数の戦闘にそのまま文字列をいれれば、関数の説明を入れられるらしい。これは良い。docstringというらしい。
  • 関数もオブジェクトなので、引数に渡せる。コールバックみたいなことがすぐにできる。
  • 関数の中に関数を定義できる(関数内関数)
  • 関数内関数はクロージャーとして機能する
  • ラムダ関数
    • lambda args : contentesで書く、直接関数オブジェクトとして渡すときに使うのだろう
  • ジェネレータ関数
    • 書くときは、returnの代わりにyieldを書く
    • 呼ばれる毎に最後にyieldした続きから始まる。
    • 記述の最後までいったら何も返さなくなって終わるということ
    • 馴染みはないがかなり面白い考え方で、巨大なシーケンスを扱えるようになる
    • ジェネレータ関数はvar in generatorになって初めて評価される
  • デコレータ
    • 関数を装飾するイメージ
    • 関数をラッピングする関数を用意する
    • ラッピングしたい対象の関数の上に@を使った記述をする(マクロみたい)
def doc_func(func):
  def new_function(*args, **kwargs):
    result = func(*args, **kwargs)
    print("result:", result)
    return result 

@doc_func
def my_func1(....)..
* さらに関数に対するデコレータは複数持てるらしい
  • 名前空間
    • 基本的にローカルからグローバル変数の変更は許容していない
      • 代入から始まる処理が書かれると同じ変数名であって、別の変数として扱われる
      • ただし、グローバルへのアクセスは普通にできる
        • グローバル変数にアクセスしたあとに代入しようとすると、グローバルへの代入とみなしエラーが起きる
    • global variableと宣言することで、代入雨も行えるようになる
    • 名前空間の状態をデバッグしたかったら、globals()とlocals()という関数があってチェックできる
  • 変数名について
    • 予約後は使ってはだめ、から始まりで終わる単語も予約語
  • try, except
    • C++ではtry,catchだった処理が、try, exceptとしてそれぞれのブロックで処理を行う
      • C++では、throwでエラーを出力するが、pythonではraiseのようだ
      • もちろん、独自のException型を用意することもできる

Ubuntu18.04のインストールと初期設定

久々の更新です。

lenovoのT450を中古で安く買って、ubuntu18.04を入れて、遊ぶことにしました。 今回は、デュアルブートでなくて良いので、ubuntu18.04のイメージをDVDに焼きこんで普通にインストールしました。 はまるとこは何もなく非常に簡単でした。 18.04で日本語でインストールすると、最初からMozc入っているし、半角/全角で日本語と英語変換してくれるし、すごい楽です。

初期設定

まずは、keyboardのレイアウトの設定

linux.just4fun.biz

これで、GUIから簡単にcapslockをctrlに上書きできました。 さらに設定にemcasキーバインドを使うなんていう項目もあって良さげです。 emacs厨の私としては、何も考えずこの項目を有効にしました。

あとは、以下の記事の気になるところを更新しました。

linuxfan.info

ほとんどやることなくて楽でした。

まずは、python3を一から学ぼうと思っているのですが、 以前先にanacondaでpythonを入れたら、ROSのインスールでハマった記憶があります。 ROS2も試していきたいので、とりあえずROS2をインストールするのが良い気がしています。

ros2のインストールは以下のページに習ってやればすぐにできました。

qiita.com

Google Apps Script (GAS) をローカルで開発する環境を整えた

突然ですが、GoogleのSpreadsheet便利ですよね。 私はSpreadsheet上でオリジナルの家計簿を作っているのですが、いかんせんブラウザ上でプログラミングするのが辛い… ローカルで開発でできないかなと調べたら以下の方法があることを知りました。

qiita.com

早速、claspなるものを導入しました。 結構簡単に導入できるのでおすすめです。

ついでにemacsjavascriptのインデントを4から2に変更しました。

stackoverrun.com

.init.elのような場所を直接編集する方法もいいですけど、 変更しても反映されたりされなかったりが面倒そうだったので、 「M-x customize-group」から変更するのが確実な気がして、そっちを採用しました。

ROSを試してみたがインストールでこけてしまった

久々の更新ですが、ただの自分用備忘録です。

ROSを試してみようと思って、以下のサイトを参考にROSをインストールした

ja/kinetic/Installation/Ubuntu - ROS Wiki

その後、catkinが必要だったような気がして、

apt-get install catkin

とすると、以下のエラーでインストールができない。

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
インストールすることができないパッケージがありました。おそらく、あり得
ない状況を要求したか、(不安定版ディストリビューションを使用しているの
であれば) 必要なパッケージがまだ作成されていなかったり Incoming から移
動されていないことが考えられます。
以下の情報がこの問題を解決するために役立つかもしれません:

以下のパッケージには満たせない依存関係があります:
 catkin : 依存: python-catkin-pkg しかし、インストールされようとしていません
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。

なんとなくバージョンの依存関係で矛盾が生じてしまっているのはわかるが、 どうすればよいかわからない。 調べてみると以下のサイトを見つけた。

Ubuntuで依存関係が壊れている時の対応 - tizen.moe

早速

aptitude install catkin

一度目の選択肢に対して「.」を押して、次の選択肢を表示させると以下のようなメッセージが。。。

以下のアクションでこれらの依存関係の問題は解決されます:

       以下のパッケージを削除する:                                       
1)       python-catkin-pkg-modules                                       
2)       python-rosdep                                                   
3)       python-rosdistro                                                
4)       python-rosdistro-modules                                        
5)       ros-kinetic-actionlib                                           
6)       ros-kinetic-actionlib-tutorials                                 
...
134)     ros-kinetic-turtlesim                                           
135)     ros-kinetic-urdf                                                
136)     ros-kinetic-urdf-tutorial                                       
137)     ros-kinetic-visualization-tutorials                             
138)     ros-kinetic-viz                                                 
139)     ros-kinetic-xacro                                               

       以下のパッケージをインストールする:                               
140)     python-funcsigs [0.4-2 (xenial)]                                
141)     python-mock [1.3.0-2.1ubuntu1 (xenial)]                         
142)     python-pbr [1.8.0-4ubuntu1 (xenial)]                            

       以下のパッケージをダウングレードする:                             
143)     python-catkin-pkg [0.4.1-100 (now, xenial) -> 0.2.10-2 (xenial)]
144)     python-rosinstall [0.7.8-1 (now, xenial) -> 0.7.7-1 (xenial)]   


この解決方法を受け入れますか? [Y/n/q/?] 

さすがにこれは受け入れられない。。。

ここで一度、ROSのインストール記事を見ているときに手動でcatkinを入れろと書いていないなと思い、 そのまま以下のコマンドを試す。

$ catkin_init_workspace
$ catkin_make

以下のエラーが出てうまく行かない。

ImportError: "from catkin_pkg.package import parse_package" failed: No module named 'catkin_pkg'

このエラーについて調べると、anacondaが悪さをしているようだ。。。

Google グループ

Anacondaのアンインストールはあまりしたくないな。。。と思い、 そもそも環境を汚さない方法として、Dockerがあるじゃないか、と思い出す。

Dockerについては、名前以外はほとんど知らないので以下の記事を一通り読んだ。

www.atmarkit.co.jp

つづいて、以下の記事のとおりに作業を行うことで、とりあえず確認はできた

Docker + ROS(kinetic)でチュートリアル - Qiita

ただ、Dockerのイメージをベースに自分のコードを動かす方法がわかっていないので、それを学ぶ必要がある。

深層学習の超基礎知識を勉強した(学習に関するテクニック)

本当に久しぶりですが、ゼロから作るDeepLearningの6章、学習に関するテクニックを読んだときのメモを残します。 今年は継続的な勉強を頑張りたいです。継続は力なり。

  • SGDとは、確率的勾配降下法のこと
    • 勾配方向に向かう一番単純な方法
    • stochastic gradient descent
  • SGDは解く関数の形状が等方的でないと収束がうまくいかない
    • x方向の勾配は急だけど、y方向の勾配が非常に緩い場合など
    • このとき、勾配の方向が本来の最小値の方向を指しているとは限らない
      • この辺が、ガウス・ニュートンだと解決されているのか?
        • 自分の理解が正しければ、方向というよりは、収束点がわかっているイメージ
          • 勾配降下法は学習率のパラメータが必要だけど、いらないということ
  • Momentum
    • 収束に慣性を持たせる
  • AdaGrad
    • パラメータ毎に適応的に学習係数を調整する
    • 各パラメータの勾配の二乗和(スカラー)を逐次的に足し合わせてその分だけ学習係数を小さくする
    • 一回でも間違って大きく更新されてしまうとその後戻るステップが遅くなるみたいな性質を想像すると、結構イマイチな気がする
    • RMSPropという方法の方が良さそう
  • Adam
    • MomentumとAdaGradの融合
    • Qiitaなどをみていても、未だにAdamが鉄板だと思う。ライブラリでAdamを使えば良い
  • 初期値はとりあえずランダムで良い?←あとから、ダメという話がある
    • 何か学習済みのパラメータがあればそれを流用するのが良い
  • 勾配消失問題
    • 微分値が0になってしまうと、重みパラメータが更新できないという話
    • シグモイドならば0付近と1付近
  • 「表現力の制限」の問題は、逆にニューラルネットをコンパクトにしたい際に使用されている気がする
    • ニューロンが違う挙動しないと、ニューロンがたくさんある意味がないという話なので、逆に性能が出ているのに同一挙動のニューロンがあればそれは減らせる、みたいな
  • 初期値について
    • Xavierの初期値という考え方がある
      • できるだけ偏りなく勾配消失しない形でアクティベーションされることを目指したのかな
      • ところで、活性化関数に用いる関数は、原点対象であることが望ましい性質として知られているらしい
    • 活性化関数にReLUを使う場合は、「Heの初期値」を用いると良い
      • 考え方はほとんどXavierと変わらない
  • Batch Nomalization
    • 恥ずかしいことに、バッチノーマライゼーションとミニバッチ学習を混同していたが、全然違う
    • ミニバッチ学習
      • (ちょっとまだ自信がないが)ミニバッチ学習をせずに一つのデータだけで勾配を計算してしまうと、勾配方法が信用できなくなってしまうという話だと思う
      • 100個とか適当にサンプリングしたデータの塊を全データの近似とみなすということは、勾配方向がそこそこだ正しいとみなすことかな?
      • なので、ミニバッチ学習のサンプリング数は小さぎてはいけないと思う
    • Batch Normalizationは、ニューラルネットにBatch Nomaizationレイヤを挿入する
    • 角層でのアクティベーションの分布を適度な広がりになるように調整する専用の層を設計するということ
      • ミニバッチごとに正規化を行う
      • データの分布が平均が0で分散が1になるように正規化
      • 逆伝播の解説は省略されていたが、定性的な理解をしたうえで、基本的にライブラリを信じれば良いだろう
  • 過学習を抑制する手段として下の手法が有名
    • Weidht decay
      • 重みパラメータにペナルティをつける
      • 割と昔からある考え方
    • Dropout
      • 訓練時に、わざとランダムに使用しないニューロンを設定する
      • 擬似的に、アンサンブル学習を行っているという解釈になる
  • 最近はBatch Normalizationの方が有力ということなんだろうか
  • ハイパーパラメータの最適化
    • 今後重要な領域だろうが、今は興味外なので省略
    • ハイパーパラメータを遺伝的アルゴリズムで最適化とかあった気がする

すごい久々だけど大したことは書けない

すごいどうでも良い話だけど、久々に勉強しようとした際にメモをどこに残そう?と少し悩んだ。 要求仕様としては、

  • 基本的にはweb上に残したい
    • DesktopとノートPCの両方でアクセスしたいので
  • いざというときに、オフラインでローカルで編集したい

これだけ。そこで、以下の記事を見つけた。

d.hatena.ne.jp

要するに、全部GitHubで管理すれば良しちゃえということ。 これは凄く良いと思うので、早速レポジトリを作った。

とにかくここにメモをマークダウンで残してある程度まとまったら、記事にするとかありかもしれない。