はじめに
少し前から機械学習、特にディープラーニングの勉強をしています。
理解を深めるには自分でコーディングしてみるのが良い、と考え慣れ親しんできたObjective-Cで色々とコーディングしてみました。ある程度理解できてCNNによる手書き数字認識ができ、次に何をしようか、というタイミングで自作のツールの拡充はやめてpython3とkerasを使用することにしました。ずっと速そうだったからです。
pythonもkerasも不慣れなので、忘備録として、いつもお世話になっているQiitaに投稿することにしました。
お気付きの点がありましたらご指摘いただけますと幸いです。
##課題
全4回のシリーズでは、以下の3つの課題をクリアしたいと思います。
- 平均と標準偏差を出力するNN
- 正規分布に従う波形データから、その正規分布を描画するのに必要な3つのパラメータを出力するNN
- 画像中にある円についての4つのパラメーター(x座標、y座標、半径、線の太さ)を出力する畳み込みNN(CNN)
第1回の今回は準備編です。
##numpyのndarrayの使い方の復習
kerasを用いるには、学習用のデータをnumpyのndarray(N次元の配列)として準備する必要があり、ndarrayの取り扱いについて、あれこれ知っておく必要があります。
まずはnumpyをimportします。
# numpyのimport
import numpy as np
# numpyの配列を作って変数aに格納。角括弧を忘れるとダメ。
a = np.array([1,2,3,4,5,6]) #良い
a = np.array(1,2,3,4,5,6) #ダメ
# 配列の中身を確認するには
a
# array([1, 2, 3, 4, 5, 6])
numpyのndarrayを取り扱う時は、その形(shape)を意識する必要があります。shapeを確認してみます。
#行列の形(shape)を確認するには、
a.shape #良い (6,)
a.shape() #ダメ。エラーが出ます。
np.shape(a) #これでも良い。
a.shape()ではなくて、a.shapeなのでndarrayの属性(attributes)の1つということでしょうか。
続いて行列の形(shape)をreshape()で変更してみます。
a.reshape(2,3) #ダメ...shapeが変わったものが返されるが、a自身は変わらない。
# array([[1, 2, 3],
# [4, 5, 6]])
a = a.reshape(2,3) #良い
a.reshape(2,3)は新しくndarrayを作って返すので、ここでは同じ変数aに入れなおしています。メソッドによって、新しいndarrayが作られるのか、既存のndarrayが変更されるのか、区別する必要があります。
##ndarrayの部分を取り出す方法(1次元配列)
続いてndarrayからのデータの取り出し方です。新しくndarrayを1つ作ります。
b = np.arange(10) #array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b[2:5] # array([2, 3, 4]) indexは0から始まっており、5番目は含まれない。
b[3:] # array([3, 4, 5, 6, 7, 8, 9]) index 3から最後まで。
b[:4] # array([0, 1, 2, 3]) index 4の直前まで。
b[:] # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。全部。
b[-4:] # array([6, 7, 8, 9]) 後ろから4つ目から最後まで。
b[:-4] # array([0, 1, 2, 3, 4, 5]) 後ろから4つ目まで(後ろから4つ目は含まれない)。
##ndarrayの部分を取り出す方法(3次元配列)
続いて3次元のndarrayについてです。ここで示す例は要素数30とちょっと大きいndarrayです。3つの次元の要素数が「互いに素」になるようにするとわかりやすいかなと思って30ですが、それ以外に30にあまり意味はありません。
c = np.arange(30).reshape(5,3,2) #np.arange(30)で作ったndarrayを、(変数にしまわずに)reshapeして変数cに入れる。
c
# array([[[ 0, 1],
# [ 2, 3],
# [ 4, 5]],
#
# [[ 6, 7],
# [ 8, 9],
# [10, 11]],
#
# [[12, 13],
# [14, 15],
# [16, 17]],
#
# [[18, 19],
# [20, 21],
# [22, 23]],
#
# [[24, 25],
# [26, 27],
# [28, 29]]])
これを5つのトレーニングデータだと思って2つ目(index 1)を取り出すには、
c[1,:,:]
# array([[ 6, 7],
# [ 8, 9],
# [10, 11]])
index 3まで(index 3は含まれない)を取り出すには、
c[:3,:,:]
# array([[[ 0, 1],
# [ 2, 3],
# [ 4, 5]],
#
# [[ 6, 7],
# [ 8, 9],
# [10, 11]],
#
# [[12, 13],
# [14, 15],
# [16, 17]]])
index 3からを取り出すには、
c[3:,:,:]
# array([[[18, 19],
# [20, 21],
# [22, 23]],
#
# [[24, 25],
# [26, 27],
# [28, 29]]])
とします。
##ndarrayに要素を追加する方法
np.append(c,100) #1次元のndarrayが新たに作られて返される。
#要素を追加したもので自身を置き換えるには、
c = np.append(c,100) #とする。
#中身の確認
c
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
# 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
# 26, 27, 28, 29, 100])
ただし上記の方法は、追加する要素数が多数の場合は使うべきではありません。ndarrayを新しくなんども作るのは、それなりにCPU/メモリ負荷が高いからです。要素を多数含むようなndarrayを作成する場合は、pythonの配列(リスト)をまず作成し、それを使ってndarrayを作るようにします。
#遅い方法
d = np.array([]) #空のndarray
for i in range(100000):
d = np.append(d,i)
#早い方法
d = [] #空のリスト
for i in range(100000):
d.append(i)
d = np.array(d)
#短く書くなら
d = np.array([i for i in range(100000)])
#まとめ
ndarrayを、作り、形を変え、分割して取り出すことができるようになりました。
シリーズ第1回 準備編
シリーズ第2回 平均と標準偏差
シリーズ第3回 正規分布
シリーズ第4回 円