PSM

プログラミング 初心者の メモ書き です

1週間で「ゼロから作るDeep Learning」に挑戦することにしました

1.はじめに

AlpfaGoの活躍で一躍話題となったDeep Learning.

機会があって「ゼロから作るDeep Learining」という本をいただいたので勉強してみるるのですが,せっかくなので敢えて1週間と短い時間設定で挑戦することにしました.

そもそも機械学習に関する知識が全くないばかりかプログラミング経験がほとんどない自分が手を出すのはどうなの?という毎回の疑問は今回も無視させていただくことにして,やっていきたいと思います.

人生万事,ノリと勢い!


2.Pythonのインストール

Pythonをインストールする.
Anacondaというディストリビューションでインストールすると良い,とあったのでお言葉通り,以下のリンクより3系を選んでダウンロードします.

Download Anaconda Now! | Continuum

pythonには2系と3系があり,3系の方が新しくこれからの拡張も期待されているために,初心者に薦められることが多いが,実際の現場では2系も多く使われているらしいです.
とりあえず「ゼロから作るDeep Learning」では3系を入れろと書いてあるのでそうしました.

ちなみに私はダウンロードとインストールの正確な定義もよくわかっていないくらいの雑魚で,webからデータを落としてくるのがDownload,落としてきたデータがアプリケーションならそれをマシンで使えるようにするのがInstallくらいに思っています.

3.atomをインストールする

Anacondaを入れるとjupyter notebookが使えるようになります.
これはこれでいいんですが,スクリプトがセルごとにわかれたりするし,UIがなんとなく気に入らなかったりしたので,atomというエディタでPython環境を構築してみることにしました.
atomを使う場合でも,packageを入れればスクリプト上で実行できるようになるそうです.
atomのダウンロードは以下.

atom.io

macの場合はzipで落ちてくるので,展開した後にアプリケーションにDrug&Dropしておきましょう.

この後,補助パッケージのatom-beautyやminimap,linterなどをいれます.

テストの結果はこんな感じ.
f:id:muromura:20170417235028p:plain

4.まとめ

本当はもう少し作業したかったのですが,夜も遅いので今日はここまで.

準備するところまではサクサク進みました.
本番はいよいよ明日からです.
予想通りに進まないことも多いかもしれませんが,宣言したからには頑張っていきたいところです.

それでは.

np.sum()より早い方法

1.はじめに

サイズの小さなベクトルに対してnumpy.sum()より早い方法

例のごとくまったく知らないので調べるしかないですが,せっかくなので,本当に早いのか処理時間をはかるところまでやってみます.

やりたいことを切り分けると,結局以下の3つの方法を調べる必要がありました.

  1. numpy.sum()より早い総和の方法
  2. 時間の計測方法 
  3. 少数の表示を指定する方法

2.サンプルコード 早い総和

np.add.reduce()を使うとよいらしいです.

import numpy as np

# 要素数100のランダムなベクトル
z = np.random.random(100)

#いつもの
sum1 = np.sum(z)
#はやいやつ
sum1=np.add.reduce(z)

3.サンプルコード 処理時間の計測

np.datetime64()でもやれそうですが,とりあえず調べてでてきたtime.time()を使ってみます.

import numpy as np
import time

# 要素数100のランダムなベクトル
z = np.random.random(100)

start1 = time.time()
#総和をとる
sum1 = np.sum(z)
end1 = time.time()
passtime1=end1-start1
#計測時間を出力
print(passtime1)

4.サンプルコード 少数表示

上ででてきた計測時間をシチュエーションごとに比較したい.
そこで少数点の桁数を揃えて表示する必要があったので.これも調べました.
printの部分で,"%.8f"%passtime1のように書くと8桁,のように表示できました.

import numpy as np
import time

# 要素数100のランダムなベクトル
z = np.random.random(100)

start1 = time.time()
#総和をとる
sum1 = np.sum(z)
end1 = time.time()
passtime1=end1-start1
#計測時間を出力
print("%.8f"%passtime1)

5.サンプルコード 比較

というわけで全シチュエーションについて出力すると

import numpy as np
import time

z = np.random.random(100)

start1 = time.time()
sum1 = np.sum(z)
end1 = time.time()
passtime1=end1-start1

start2 = time.time()
sum2 = np.add.reduce(z)
end2 = time.time()
passtime2=end2-start2

z = np.random.random(10000000)
start3 = time.time()
sum3 = np.sum(z)
end3 = time.time()
passtime3=end3-start3

start4 = time.time()
sum4 = np.add.reduce(z)
end4 = time.time()
passtime4=end4-start4

print("%.8f"%passtime1,"%.8f"%passtime2,"\n","%.8f"%passtime3,"%.8f"%passtime4)
0.00014186 0.00010800 
0.00583005 0.00585008

5.まとめ

というわけで,やっぱりサイズの小さいベクトルに対してはadd.reduce()の方が早いようでした.
調べたところによると,np.sum()ってのが小さいベクトルに対しては結局内部的にadd.reduce()を呼び出しているので,そりゃadd.reduce()をそのまま使った方が早いよね,とのことでした.

それでは.

0.3 != 3*0.1問題


pythonで以下のように書くと

>>> 0.3 == 3 * 0.1
False

とかえってきます.

いや0.3が0.3じゃないってどういうことやねんと思っていろいろ調べてみると

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

なるほど.
つまりpythonの0.1や0.3が,人間の思っているようなぴったり(0.00000000000000001の狂いもなく)0.1や0.3ではなく,ちょっとずれているというのが原因らしいですね.
そういえば、二進数の浮動小数点として扱うために近似しているという話を聞いたことがあるのでwikiセンセに聞いてみました.

(1*1/3の結果について)
しかし、実際にはコンピュータや電卓では 0.9999999999999999 のような結果となり、場合によっては 0.99999999923475 のような値になることもある。「実数型」などという概念は、それ自体が誤謬であるとも言える。
後者の値はバグの存在を示しているわけではなく、二進法の浮動小数点数による近似の結果生じるのである。ある種の任意精度演算系や、何らかの数式処理システムでそういった演算に対応している場合は、1 や 0.9999999999999999... という結果が得られるものもある。
Wikipedia:コンピュータの数値表現

はい,そういうことらしいですね.
99.9999%,つまりほとんど100%のことをシックス・ナインなどと言ったりするようですが,コンピュータは6桁どころではない十分に小さな誤差で整数を表現しているとのことです・

ちなみに

>>> 1 == 2 * 0.5
True

だったりします.
つまり1は0.5を2倍した数であるために,上で出てきたような”ほんのちょっとのズレ”もちょうど2倍されて等しくなるということですか.
なるほど.

それでは.

プログラミング初心者がUnityでゲーム作ってみました1 Roll a Ball

 プログラミングスキルがほぼ皆無の素人ですが,突然Unityの勉強を始めることになりました.別に深い理由があってのことではなく,単純に面白そうだったからです.紹介してくれたそっちに精通する友人もとにかくやべえやべえと繰り返していたので,まあやべえツールなんでしょう.

 

 私はというと,触ったことある言語なんてR(という統計解析用言語)くらいで,CとC++C#の違いも全くわからないくらいなのですが,まあなんとかなるんじゃん精神でなんとかやっていきたいと思います.

 

 ということで.今回はとりあえずチュートリアルに沿って"Roll a Ball"というゲームを作ってみました.

 

 結論から言うとかなり簡単にできました.もっと難しい処理をたくさんやらされるものだとばかり思って身構えていましたが,ほとんどつまづくことなく実装を終えられました.そういう難しい部分は全部向こうで用意してくれているみたいです.

 まずチュートリアルがわかりやすいです.そしてUnityはすごいです.

 

 

 

1.とりあえずUnityをPCにいれる

japan.unity3d.com

 とりあえず検索窓に"Unity"と打ち込んで一番上に出てきたサイトを見てみます.どうやらこれが公式サイトのようです.さて,どっからダウンロードできるん?とあちこち見てみるとどうやら最上部のバーの"Unity" のところにあるようです.

 そこから

  Personal -> 今すぐダウンロード -> インストーラをダウンロード

と進み,後は指示に従っていくと,unityが無事入りました.

やったぜ.

インストーラーをDLするとき,OSなどの要件も勝手に判定してくれるみたいで楽です.

 

2.Unityを立ち上げる

 ダウンロードしたUnityを立ち上げると,「アカウント情報を入力してね」みたいな画面がでてきました.

f:id:muromura:20170411221510p:plain

 昨日Unityという単語を聞いたような人間が,アカウントを持っているわけがありmせん.

 というわけで早速登録してアカウント情報を入力します.gmailなどのフリーアドレスを用意すれば問題なく終わります.

そのあとも何回か「pesonal?(本当に個人使用?)」という確認が出てくるので,「はい個人使用です」「マジで」「いやほんとマジで」と進んでいくと,とうとう初期画面にたどり着きます.

 少し真面目に書いておくと,やはりゲーム開発に最高の環境であるということもあって,普通に使用しようと思うとすごくお高くなってしまうところを,個人用には特別無料で提供しているとのことです.非常にありがたい話です.

 

 さて,unityが起動しました.1番上にProjectsLearnの2つのタブがあります.

 よくわかんないままに初心者だしlearnしたいぜ!とLearnの方に進んでみました.

f:id:muromura:20170411222404p:plain

 なるほど...どうもここに並んでいるのはチュートリアルとして実際に作れるゲームのようですね.

 えーこんなクオリティ高いの自分でつくれるの? 初心者なんですけどこっちは

 とワクワクを通り越して尻込んでしまうくらいですが,そんなこと言っていても仕方がないので,とりあえず一番上の"Roll a Ball"というのを選びました.

 右側の Download -> Startと進むと,いよいよなんかそれっぽい画面が立ち上がりました.もう既にこれだけで達成感を覚えつつありますが,まだ早すぎますね.

 コンピュータに詳しくない人間としては環境の導入(インストール)のハードルがまた高いんですよね.

f:id:muromura:20170411223129p:plain

 

3.とにかくチュートリアルに従う

 さあやるぞ!

 ...と意気込んだところで,まあわからないものです.何をしたらいいんですか? 何ができるんですか?

 再び途方にくれ,ただただ”?”ばかりが頭の中を渦巻くところですが,よく見ると画面の右のほうに救いの女神がいました.

f:id:muromura:20170411223447p:plain

 Roll a Ball Tutorial? あ! これやんけ!

 というわけで早速上のリンクをクリックします.するとUnity-玉転がしというpageにつながりました(以下リンク)

unity3d.com

 いやはや,これでなんとかなりそうです.あとは下のほうにあるセクションにそって進めていくだけですね.

 全く問題ないです...動画が全て英語であることを除けば.

 

 以下,50%も聞き取れない英語を相手に四苦八苦が続きますが,基本的には動画なので画面の通りになぞっていき,問題なく完成まで辿りつくことができます.

 ただ,途中で「複数やり方あって,こうやってもできるんだけど,こっちの方がいいよHAHAHA」みたいなことを何回か言っているようですが,こちらとしては理由が聞き取れないのでイマイチしっくりこないところが少しありました.

 この辺りも含め,一度しっかり聞き直して細かくまとめてみたいです.時間さえあれば.

 

4.作ったもので遊ぶ

 実際のプレイ動画です.

 ...正直,ゲームとしてのクオリティはめっちゃくちゃ低いと思います.文字通り玉を転がしてるだけで複雑なことをしているわけでもないです.

 しかし,自分の手でつくれたという喜びが何より大きいものです.今なら何でもできる気がします.何でもは言い過ぎかな.でもそれくらい楽しかったです.

 

5.まとめ

 意外になんとかなりました.それに尽きます.

 正確に言うと,object?の属性やtagについていまいち理解していなかったり,コピーやインスタンスの概念が怪しかったりして,チュートリアルありきでしかないのですが,それでも一通り終えられたということが重要だと思っています.

この調子で頑張っていけば,簡単なゲームならすぐ自作できるようになったり...しませんかね?

 

 とりあえずチュートリアルのゲームは全部作ってみるつもりなので,次は"Space Shooter"とかいうロケットのやつに挑戦してみたいと考えています.

 

 それでは.