Miyamoのブログ

技術ブログ(にしたい)

ゼロから作るDeep Learning 1章「Python入門」

脳の情報処理に興味があり,汎用人工知能の実現を目指したいとか言いながらかずー氏のブログとかサックスの本を読んだりしかしていない自分がそろそろ嫌になってきた.

情報系(というかエンジニア)はブログやQiitaでアウトプットしまくってる印象があり,強くなるにはそれをやっていくべきだと感じたので(発信しないことにはやってないのと同じ)技術ブログ(笑)をスタートさせることにした.

 

汎用人工知能の実現を目指す上で,現在脳の情報処理がどこまでコンピュータで再現されているかを理解しておくことが重要であると考えた.

ニューラルネットワークという脳の神経回路のモデルがあることを本や授業を通して知っていたので,それを勉強していこうと思った.

理論は分かっているか実装に関してはサッパリということにはなりたくないので,両者を解説している参考書を探したところ,ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装というのを見つけた.

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

 

評価も高く,かなり売れているようなので新宿の紀伊國屋本店で購入.

この本に沿って勉強を進めて行き,その過程を記事にしていきたいと思う.

今回は,その1章の「Python入門」から.

 

1.Pythonについて

・2系と3系のバージョンが存在

 -古い2系も多く利用されている.完全な互換性はないので慎重に選ぶ必要あり

 -今回は3系(Python 3系)をインストール

・2つの外部ライブラリを今回は使用

 NumPy

 -数値計算のためのライブラリ

 -数学アルゴリズムや配列(行列)を操作するためのメソッドが数多く存在

 Matplotilb

 -グラフ描画のためのライブラリ

 -実験結果の可視化や実行途中のデータを視覚的に確認することができる

 

2.Pythonのインストール

Anacondaというディストリビューションを利用

 -データ分析に重点を置いたディストリビューション

 - 今回使う外部ライブラリも含まれている

ディストリビューションとは

 ユーザが一括してインストールできるように,必要なライブラリなどがまとめられたもの

 

以下,インストール手順.

 

1.ダウンロードリンク(Download Anaconda Now! | Continuum)にアクセス

 

f:id:miyamo765:20170419235240p:plain

2.OSを選択してver 3.6をインストール

今回はGRAPHICAL INSTALLERを選択.

f:id:miyamo765:20170420000000p:plain

3. インストール

f:id:miyamo765:20170420184439p:plain

f:id:miyamo765:20170420184443p:plain

「自分専用にインストール」を選択して進める.

Launchpadを開くと「Anaconda-Navigator」が追加されていることが確認できる.

 以上でインストールが完了.

 

 

3.Pythonインタプリタ

インストールが完了したら,まずPythonのバージョンを確認.

$ python --version
Python 3.6.0 :: Anaconda 4.3.1 (x86_64)

次にPythonインタプリタを起動.

$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

 

インタプリタとは

人間がプログラミング言語で記述したソフトウェアの設計図(ソースコード)を、コンピュータが実行できる形式(オブジェクトコード)に変換しながら、そのプログラムを実行するソフトウェア。インタプリタ型の言語はプログラムの実行時に変換を行うため、その分だけコンパイラ型言語よりも遅い。

インタプリタとは - IT用語辞典 

 

Pythonインタプリタは「対話モード」とも呼ばれ,対話的にプログラミングを行うことができる.

>>> 1 + 2
3

 

4.Pythonプログラミングの簡単な例

・算術計算
>>> 1 - 2
-1
>>> 4 * 5
20
>>> 7 / 5
1.4
>>> 3 ** 2 #累乗
9

 

・データ型

type()でデータ型を調べられる.

>>> type(10)
<class 'int'>
>>> type(3.1415)
<class 'float'>
>>> type("hello")
<class 'str'>

 

・変数
>>> x = 10
>>> print(x)
10
>>> x = 100
>>> print(x)
100
>>> y = 3.14
>>> x * y
314.0
>>> type(x * y)
<class 'float'>

 Python動的型付き言語に分類され,自動的に変数の型が決定されるため,プログラマが型宣言しなくてもよい.

 

・リスト
>>> a = [1, 2, 3, 4, 5]
>>> print(a)
[1, 2, 3, 4, 5]
>>> len(a)
5
>>> a[0]
1
>>> a[4]
5
>>> a[4] = 99
>>> print(a)
[1, 2, 3, 4, 99]

スライシング(slicing)と呼ばれる記法が便利.サブリスト(部分リスト)に簡単にアクセスできる.

>>> print(a)
[1, 2, 3, 4, 99]
>>> a[0:2] #インデックスの0番目から2番目まで取得
[1, 2]
>>> a[1:]  #インデックスの1番目から最後まで取得
[2, 3, 4, 99]
>>> a[:3]  #最初からインデックスの3番目まで取得
[1, 2, 3]
>>> a[:-1] #最初から最後の要素の1つ前まで取得
[1, 2, 3, 4]
>>> a[:-2] #最初から最後の要素の2つ前まで取得
[1, 2, 3]

  

・ディクショナリ

キーと値をペアとしてデータを格納する.

>>> me = {'height':180} #ディクショナリを作成
>>> me['height']        #要素にアクセス
180
>>> me['weight'] = 70   #新しい要素を追加
>>> print(me)
{'height': 180, 'weight': 70}

 

ブーリアン
>>> hungry = True
>>> sleepy  = False
>>> type(hungry)
<class 'bool'>
>>> not hungry
False
>>> hungry and sleepy
False
>>> hungry or sleepy
True

 

・if文
>>> hungry = True
>>> if hungry:
...     print("I'm hungry")
... 
I'm hungry
>>> hungry = False
>>> if hungry:
...     print("I'm hungry")
... else:
...     print("I'm not hungry")
...     print("I'm sleepy")
... 
I'm not hungry
I'm sleepy
>>> 

色付けがうまくいかない…

インデントが期待されているというエラーが出たのでメモ.

>>> if hungry:
... print("I'm hungry")
  File "<stdin>", line 2
    print("I'm hungry")
        ^
IndentationError: expected an indented block

IndentationErrorはPython使いならたまに出くわすエラー

Pythonでは空白文字が重要な意味を持つ.

インデントはタブで表現できるが,Pythonは空白文字を使うことを推奨(タブは環境によって幅が異なる).

pythonのインデント

Pythonを書くときに、タブじゃなくてスペースでインデントする

 

・for文

for…in…:という構文でリストなどの各要素に順にアクセスできる.

>>> for i in [1, 2, 3]:
...     print(i)
... 
1
2
3

 

・関数
>>> def hello():
...     print("Hello World!")
... 
>>> hello()
Hello World!

関数は引数をとることができる.

>>> def hello(object):
...     print("Hello " + object + "!")
... 
>>> hello("cat")
Hello cat!

 

5.Pythonスクリプトファイル

まとまった処理を行う場合は,Pythonプログラムをファイルとして保存(スクリプトファイル)し実行するのがよい.

 

テキストエディタhungry.pyを作成し,保存して実行.

$ cd ~/deep-learning/ch01
$ python hungry.py 
I'm hungry!

 

6.クラス

・今まで見てきたデータ型(intstrなど)は初めからPythonに組み込まれたデータ

・新しいクラスを定義することで,ユーザが独自にデータ型を作成することができる

・オリジナルのメソッドや属性を定義することもできる

 

classというキーワードを使ってクラスを定義する.

class クラス名:
	def __init__ (self, 引数, …):	#コンストラクタdef メソッド名1 (self, 引数, …):	#メソッド1def メソッド名2 (self, 引数, …):	#メソッド2

コンストラクタはクラスのインスタンス生成時に一度だけ呼ばれる.メソッドの第一引数に自分自身(自分自身のインスタンス)を表すselfを明示的に書くのが特徴である.

 

例としてクラスを一つ作成してみる(man.pyとして保存).

class Man:
	def __init__ (self, name):
		self.name = name
		print("Initialized!")
		
	def hello(self):
		print("Hello " + self.name + "!")
		
	def goodbye(self):
		print("Good-bye " + self.name + "!")

m = Man("Miyamo")
m.hello()
m.goodbye()

Manというクラスを定義し,インスタンスmを生成する.

コンストラクタはnameという引数をとり,インスタンス変数self.nameを初期化する.

セミコロンを付けないの違和感しかない.

実行してみる.

$ python man.py 
Initialized!
Hello Miyamo!
Good-bye Miyamo!

 

7.NumPy

数値計算のためのライブラリ

・数学アルゴリズムや配列(行列)を操作するためのメソッドが数多くある

・配列クラス(numpy.array)に便利なメソッドが多くあり,DLの実装においてもそれらを利用する.

 

・NumPynのインポート

NumPyは外部ライブラリ(標準のPythonには含まれていない)のでインポートする.

>>> import numpy as np

as npとすることでNumPyに関するメソッドはnpとして参照できるようになる.

 

・NumPy配列の生成

NumPyの配列を作成するにはnp.array()というメソッドを用いる.

np.array()の引数はPythonのリストで,NumPy用の配列(numpy.ndarray)を作成する.

>>> x = np.array([1.0, 2.0, 3.0])
>>> print(x)
[ 1.  2.  3.]
>>> type(x)
<class 'numpy.ndarray'>

 

・NumPyの算術計算
>>> x = np.array([1.0, 2.0, 3.0])
>>> y = np.array([2.0, 4.0, 6.0])
>>> x + y
array([ 3.,  6.,  9.])
>>> x - y
array([-1., -2., -3.])
>>> x * y
array([  2.,   8.,  18.])
>>> x / y
array([ 0.5,  0.5,  0.5])
>>> 

配列の要素数が同じ場合,算術計算は各要素に対して行われる.

素数が違う場合はエラーになる.

>>> x = np.array([1.0, 2.0])
>>> y = np.array([2.0, 4.0, 6.0])
>>> x + y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2,) (3,) 

ちなみに「要素ごと」は英語で "element-wise" と言うらしい.

例えば「要素ごとの積」は "element- wise product"

 

NumPy配列と単一の数値(スカラ値)の組み合わせでも算術計算できる.

>>> x = np.array([1.0, 2.0, 3.0])
>>> x / 2.0
array([ 0.5,  1. ,  1.5])

 

・NumPyのN次元配列

 2次元配列の作成

>>> A = np.array([[1, 2], [3, 4]])
>>> print(A)
[[1 2]
 [3 4]]
>>> A.shape
(2, 2)
>>> A.dtype
dtype('int64')

行列Aの形状はshape,要素のデータ型はdtypeで参照できる.

行列どうしの計算

>>> B = np.array([[3, 0], [0, 6]])
>>> A + B
array([[ 4,  2],
       [ 3, 10]])
>>> A * B
array([[ 3,  0],
       [ 0, 24]])

行列に対するスカラ値の算術計算

>>> A * 10
array([[10, 20],
       [30, 40]])

 

・ブロードキャスト

上の行列に対するスカラ値の算術計算では,10というスカラ値が2×2の要素に拡大されて演算が行われている.これをブロードキャストという.

 

 

f:id:miyamo765:20170421233113p:plain

 

※行列の積について

行列A(i行j列)*行列B(j行k列)=行列C(i行k列)

行列Aの列数と行れるBの行数が等しくなければ積は定義できない.

 

・要素へのアクセス
>>> X = np.array([[51, 55], [14, 19], [0, 4]])
>>> print(X)
[[51 55]
 [14 19]
 [ 0  4]]
>>> X[0]
array([51, 55])
>>> X[0][1]
55

 for文を使ってもアクセスできる.

>>> for row in X:
...     print(row)
... 
[51 55]
[14 19]
[0 4]

 NumPyはインデックスだけでなく配列によってアクセスすることもできる.

>>> X = X.flatten()     #Xを1次元の配列へ変換
>>> print(X)
[51 55 14 19  0  4]
>>> X[np.array([0, 2, 4])]      #インデックスが0,2,4番目の要素を取得
array([51, 14,  0])

この記法を応用すると,ある条件を満たす要素だけを取り出すことができる.

>>> X > 15
array([ True,  True, False,  True, False, False], dtype=bool)
>>> X[X > 15]
array([51, 55, 19])

NumPy配列に対して演算子を使うと結果はブーリアンの配列になる.

このブーリアン配列を使って各要素を取り出している.

 

8.Matplotlib

グラフ描画のためのライブラリ

・実験結果の可視化や実行途中のデータを視覚的に確認することができる

 

・単純なグラフの描画

pyplotというモジュールを利用して,sin関数を描画してみる.

>>> import matplotlib.pyplot as plt
>>> x = np.arange(0, 6, 0.1)
>>> y = np.sin(x)
>>> plt.plot(x,y)
>>> plt.show()

f:id:miyamo765:20170421235813p:plain

流れは以下のような感じ.

1.NumPyのarangeメソッドで [0,0.1,0.2,,…,5.8,5.9]というデータを生成する

2.この各要素に対し,NumPyのsin関数(np.sin())を適用する

3.x,yのデータ列をplt.plotメソッドに与えることでグラフを描画する

4.plt.show()でグラフを表示して終了

 

・pylotの機能

cos関数も加えて,タイトルやラベル名などをつけてみる.

>>> import numpy as np
>>> import matplotlib.pyplot as plt

>>> x = np.arange(0, 6, 0.1)
>>> y1 = np.sin(x)
>>> y2 = np.cos(x)

>>> plt.plot(x, y1, label="sin")
>>> plt.plot(x, y2, linestyle="--", label="cos")
>>> plt.xlabel("x")
>>> plt.ylabel("y")
>>> plt.title('sin & cos')
>>> plt.legend()
>>> plt.show()

f:id:miyamo765:20170422000834p:plain

 

・画像の表示

画像の読み込みにはmatplotlib.imageモジュールのimread(),画像表示にはメソッド

がそれぞれ利用できる.

>>> import matplotlib.pyplot as plt
>>> from matplotlib.image import imread
>>> img = imread('./deep-learning/ch01/lena.png')
>>> plt.imshow(img)
>>> plt.show()

f:id:miyamo765:20170422001809p:plain

 

 

参考にしたサイト

qiita.com

 

次:ゼロから作るDeep Learning 2章「パーセプトロン」