ライブラリのインポート
import numpy as np
配列 NdArray
数値処理系の作業と相性が良く、非常に良く利用される。
生成方法 np.array()関数
NdArray
のコンストラクタ __init__(self, ...)
を使うこともできるが、通常はnp.array()
を使うことが多い。
入力値 list:リスト型
出力値 a: ndarray型
list = [[1,2][3,4]]
a = np.array(list)
np.zeros(shape), np.ones(shape), np.eye(N)
- np.zeros(shape): 要素全てが0の配列を生成。
- np.ones(shape): 要素全てが1の配列を生成。
- np.eye(N): N*Nの単位行列を生成。
.astype('float32')
などで、要素の型を指定しないとうまく行かないことがあるので、要注意。
# 重み (入力の次元数: 2, 出力の次元数: 1)
W_or = np.random.uniform(low=-0.08, high=0.08, size=(2, 1)).astype('float32')
b_or = np.zeros(shape=(1,)).astype('float32')
要素数取得
list = [[1,2,3],[4,5,6]]
a = np.array(list)
print(a.size) # 全要素数:6 = 2 * 3
print(a.shape) # 形状(行数、列数)をTaple型で表示:(2,3)
print(a.shape[0]) # タプル型の第0要素:2
乱数
乱数のseedを固定
結果の再現性のため。
seedを固定しないと、例えば、notebook上で2回同じ計算を回すと、異なる結果を得ることになる。
理由は不明だが、seed=42がMagic numberとか書かれていたりする。
np.random.seed(34)
乱数生成
# Uniform (一様乱数)
u = np.random.uniform(low=-0.08, high=0.08, size=(2, 1)).astype('float32')
# Gauss (ガウス(正規)乱数)
z = np.random.normal(loc=-0.1, scale=2.0, size(2, 1)).astype('float32')
関数
Log関数
底はeのlog関数。logの中身が0になるのを防ぐため、np.clipを利用する。
nplog(x)=\ln(\max(x,10^{-10}))
def np_log(x):
return np.log(np.clip(a=x, a_min=1e-10, a_max=x))
Sigmoid関数
2クラス分類で使われる。
\sigma(x)=\frac{1}{1+\exp(-x)}
ここでは、expのオーバーフローを防ぐため、numpy組み込みのtanhを利用する(tanhのオーバーフロー処理に関して、詳細は未調査)。
def sigmoid(x):
return np.tanh(x * 0.5) * 0.5 + 0.5
Softmax関数
多クラス分類で使われる。
\mathrm{softmax}(x)_k = \frac{\exp(x_k)}{\sum^K_{k'=1} \exp(x_{k'})} = \frac{\exp(x_k-\max_{k'=1}^{K}(x_k'))}{\sum^K_{k'=1} \exp(x_{k'}-\max_{k'=1}^{K}(x_k'))} \hspace{10mm} \text{for} \, k=1,\ldots, K
sigmoid関数と同様、exp関数のオーバーフローとアンダーフローを防ぐように実装。
def softmax(x):
x -= x.max(axis=1, keepdims=True) # expのunderflow & overflowを防ぐ
x_exp = np.exp(x)
return x_exp / np.sum(x_exp, axis=1, keepdims=True)
# 以下、使い方一例
l = [[0.4,0.3,0.6],[0.5,0.1,0.4],[0.8,0.1,0.1],[0.2,0.2,0,6]] # shape: (batch_size=4, nclass=3)
x = np.array(l)
y = softmax(x)
#演算
##np.max
-
axis
: 最大値を計算する方向(次元)を決める。 -
keepdims=True/False
:Trueにすると、最大値を取る前と、次元を同じに保つ。
list = [[1,2],[4,3],[2,2]]
x = np.array(list)
max_true = x.max(axis=1, keepdims=True) # np.array([[2],[4],[2]])
max_false = x.max(axis=1, keepdims=False) # np.array([2,4,2])
##Positive/Negative Part
A = np.array([[-1, 2, -3], [4, -5, 6], [-7, 8, -9]])
B = np.where(A > 0, A, 0)
C = np.where(A < 0, A, 0)
#行列演算
転置
x = np.array([[1,2,3],[4,5,6]]) # shape: (2,3)
xt = x.T # np.array([[1,4],[2,5],[3,6]]), shape: (3,2)
行列積
b = np.array([[1,1,1],[1,1,1]]) # (2,3)
c = np.array([[1,1],[1,1],[1,1]]) # (3,2)
# 以下3つは、全て同じ結果を生む。
# a = b * c = np.array([[3,3],[3,3]])
a = np.matmul(b, c)
a = np.dot(b, c)
a = b.dot(c)
行列要素の抽出
分類問題で、整数値の答え(例:0,1,...,9の10クラス分類)をOne-hotベクトル表現に変換したい。以下で簡単にできる。
tgt_class = [1,9,0,5,8] # batch_size=5のケースで、10クラス分類の答えの配列
x = np.eye(N=10)[tgt_class]
# [[0,1,0,0,0,0,0,0,0,0],
# [0,0,0,0,0,0,0,0,0,1],
# [1,0,0,0,0,0,0,0,0,0],
# [0,0,0,0,0,1,0,0,0,0],
# [0,0,0,0,0,0,0,0,1,0]]