「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
について思う事。
について
について
ビビらなくて良い。
【応用数学】 ◆線形代数 ◇特異値分解 【機械学習】 ◆機械学習の基礎 ◇教師あり学習アルゴリズム ◇教師なし学習アルゴリズム ◇確率的勾配降下法 【深層学習】 ◆順伝播型ネットワーク ◇アーキテクチャの設計 ◇誤差逆伝搬法およびその他の微分アルゴリズム ※以下のみ ・全結合 MLP での誤差逆伝搬法 ◆深層モデルのための最適化 ◇基本的なアルゴリズム ※以下のみ ・ネステロフのモメンタム ◆畳み込みネットワーク ◇構造出力 ◇データの種類 ◇効率的な畳み込みアルゴリズム ◆回帰結合型ニューラルネットワークと再帰的ネットワーク ◇回帰結合型のニューラルネットワーク ※以下のみ ・教師強制と出力回帰のあるネットワーク ・有向グラフィカルモデルとしての回帰結合型のネットワーク ・RNNを使った文脈で条件付けされた系列モデリング ◇深層回帰結合型のネットワーク ◇再帰型ニューラルネットワーク ◇複数時間スケールのための Leaky ユニットとその他の手法 ※以下のみ ・時間方向にスキップ接続を追加 ・接続の削除 ◆深層学習の適応方法 ◇画像認識 ・VGG
※ 個人的には、以下の理由で数学的項目は今後も減って行くと思う。
シラバスにはない。
線形代数からの唯一の項も削除されたので線形代数の出題はナシ。
機械学習の最適化とは「経験損失最小化」で純粋な最適化とは異なる。
cross_entropyの実装にパターンあるけどコレ同じなの?
return -np.sum(tk * np.log(yk + 1e-7))
return - np.sum(t * np.log(y + 1e-8)) / y.shape[0]
return np.mean(-y*np.log(p)-(1-y)*np.log(1-p))
適切なバッチサイズを選ぶことが、学習を上手く行うために必要になる。
※loss(損失)とacc(正解率)の進捗を確認する。
def im2col(input_data, filter_h, filter_w, stride=1, pad=0): """ Parameters ---------- input_data : (データ数, チャンネル, 高さ, 幅)の4次元配列からなる入力データ filter_h : フィルターの高さ filter_w : フィルターの幅 stride : ストライド pad : パディング Returns ------- col : 2次元配列 """ N, C, H, W = input_data.shape # 何気に割り算は[//]なんだな。 out_h = (H + 2*pad - filter_h)//stride + 1 out_w = (W + 2*pad - filter_w)//stride + 1 # 画像をパティングして取り出す、 # 第1引数には元データ、第2引数には前・後の文字詰め量、第2引数のconstantは0埋め # ちなみに、第2引数はinput_dataの[高さ, 幅]の(上or前, 下or後)の部分以外を0指定。 img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant') # 2次元配列の意味だろうか? col = np.zeros((N, C, filter_h, filter_w, out_h, out_w)) # フィルターに対応する入力データの要素を抽出 for y in range(filter_h): # 最大値はOHを使って逆算 y_max = y + stride*out_h for x in range(filter_w): # 最大値はOWを使って逆算 x_max = x + stride*out_w # N, CH, H, F # ↓ # N, CH, FH, FW, OH, OW # a:b:c の指定はa~b-1までcステップずつと言う実装で、 # フィルタの要素に対応する畳込の入力データの要素を抽出する。 # 例えば3*3フィルタが適用される場合、1回目左上...3回目右上...7回目左下...9回目右下と、 # 1ステップで取得されるフィルタ[FH, FW]に対応する要素数は[a:b:c]の計算上、特徴マップ数と等しくなる。 # インデックスは単なる索引で構造と捉えない方が良い。 col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride] # インデックスをN, [OH, OW]に並び替えて # N, CH, FH, FW, [OH, OW] # ↓ # N, [OH, OW], CH, FH, FW # 行列に展開すれば意図した出力になる。 # ・行数N*OH*OWの列にはフィルタの左上から右下の順に対応する入力画像の要素が(*N)特徴マップ数分入る。 # ・列数CH*FH*FWの行にはフィルタの所定の場所[FH, FW]に対応する入力画像の要素が(*CH)チャネル数分入る。 col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1) return col
...
# Wは (フィルタ数, チャンネル, 高さ, 幅)の4次元配列からなるデータ # フィルタ毎、「チャンネル, 高さ, 幅」の行ベクトルに展開後に列ベクトルに転置する。 col_W = self.W.reshape(FN, -1).T
...
スマホ用CNNで、ボトルネックの畳み込みの分割で計算量を減らす。
log ab = log a + log b
log 1/a = log a^-1 = - log a
同じに見えない(笑)
2√2/3 = 4/3√2 = 4/√18
┌a b┐ A =└c d┘ ┌ d -b ┐ A^-1 = 1/(ab-cd)└ -c a ┘
┌a b c┐ A = │d e f│ └g h i┘ ┌a b c┐ ┌a b c | 1 0 0┐ ┌1 0 0 | r s t┐ │d e f│→│d e f | 0 1 0│→│0 1 0 | u v w│ └g h i┘ └g h i | 0 0 1┘ └0 0 1 | x y z┘ ┌r s t┐ A^-1 = │u v w│ └x y z┘
細工されたサイコロの出る目の確率分布表
確率変数 X | 1 | 2 | 3 | 4 | 5 | 6 |
確率 P | 0.5 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
確率変数 Y(X1=X2) | 1 | |||||
確率 P | 0.5*(0.5)=0.25 | 0.1*(0.1)=0.01 | ||||
確率変数 Y(X1≠X2) | 0 | |||||
確率 P | 0.5*(1-0.5)=0.25 | 0.1*(1-0.1)=0.09 |
a
確率変数 X | 1 | 2 | 3 | 4 | 5 | 6 | ||
確率 P | 0.5 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | ||
確率変数 Y | 0(X1≠X2) | 0.5 | 0.25 | 0.09 | 0.09 | 0.09 | 0.09 | 0.09 |
1(X1=X2) | 0.5 | 0.25 | 00.1 | 00.1 | 00.1 | 00.1 | 00.1 |
※ ビットでの回答になる場合は、logの底は2となる。
log(1 / 0.1) = -log0.1
= - (0.5 * log0.5) - (0.1 * log0.1)*5 = -0.5 * log0.5 - 0.1 * (log0.1)*5
= - (0.5 * log0.5)*5
= - {(0.25 * log 0.25)*2 + (0.01 * log 0.01)*5 + (0.09 * log 0.09)*5}
f(x) = x
f(x) = 1 (x ≧ 0) f(x) = 0 (x < 0)
f(x) = 1/(1+e^-x)
f'(x) = f(x)(1-f(x))
f(x) = (e^x - e^-x)/(e^x + e^-x)
f(x) = 1 - f(x)^2
f(x) = x (x ≧ 0) → 傾き 1 f(x) = 0 (x < 0) → 傾き 0
f(x) = x (x ≧ 0) f(x) = αx (x < 0)(※αは0.01)
k分割 & xEpochで 1 学習 = kx Epoch
n = 1/n Σ|ti-yi|^2 i=1
n = 1/n Σ(ti-yi)^2 i=1
n = 1/n Σ(log(yi+1)-log(ti+1))^2 i=1
K = -Σ tk log yk k=1
n m = -Σ Σ ti,j log yi,j i=1 j=1
p(A|B) = p(B|A)p(A) / p(B)
p(x) = Σ p(x|Ck)p(Ck) p(Ck|x) = p(x|Ck)p(Ck) / p(x) p(Ck|x) = p(x|Ck)p(Ck) / Σ p(x|Ck)p(Ck)
p(Ck|x)
SVMとかDNNとか?
𝒇(𝒙) = 𝒔𝒊𝒈𝒏(𝒘𝒙 + 𝒃)
∥w∥1=(|w1|^1+|w2|^1+...+|wd|^1)^(1/1) = |w1|+|w2|+...+|wd| =Σ|wi|
∥w∥2=(|w1|^2+|w2|^2+...+|wd|^2)^(1/2) = √(w1^2+w2^2+...+wd^2) = √(Σwi^2)
LIME, SHAP, CAM
y = σ(xWx + ht-1Wh + (Ct-1 * V) + b)
o = σ(xWo + ht-1Wo + (Ct * Vo) + b)
(オートエンコーダー、自己符号化器)
y = f2(W2 f1(W1x + b1) + b2)
import tensorflow as tf import tensorflow hub as hub IMAGE_SIZE = (224, 224) out_features = 10 model_handle = "https://tfhub.dev/google/bit/s-r50x3/1" do_fine_tuning = False do_dense_train = True model = tf.keras.Sequential([ tf.keras.layers.InputLayer(input_shape=IMAGE_SIZE + (3,)), hub.Keras.Layer(model_handle, trainable=do_fine_tuning), tf.keras.layers.Dense(out_features, trainable=do_dense_train) ]) model.summary()
N = BP exp(∑wn log pn) n=1
┌ 1 ( if c≧r) BP = ┤ └ e^(1-(r/c)) ( if c < r) BP = min(1, e^(1-(r/c)))
(Generative Adversarial Networks)
min max V(D, G) = E [logD(x)] + E [log(1-D(G(z)))] G D x~Pdata(x) z~Pz(z)
real_loss = tf.keras.losses.binary_crossentropy(tf.ones_like(real_pred), real_pred) fake_loss = tf.keras.losses.binary_crossentropy(tf.zeros_like(fake_pred), fake_pred)
fake_loss = -tf.keras.losses.binary_crossentropy(tf.zeros_like(fake_pred), fake_pred)
self.update_discriminator(noize, batch_train_data) self.update_generator(noize)
conv4 = Conv2DTranspose (64, (5, 5), (2, 2), "same", activation="tanh", kernel_initializer-self.w_init)(conv3)
ゼロ除算防止
@、dot、matmul (違いは?)
演算子は「*」になる(RNN)。
k = 4 #クラスタ数 n = 200 # データ数 data = np.random.randn(n, 2) # 200行2列 # 初期値の重心をdataの中からランダムに4 index選択。 centroids = data[np.random.choice(np.arange(n), size=(k,))]
for 1 in range(10): indexes = np.zeros(data.shape[0]) # dataの行数と同じ配列 for centroid in centroids: for i, x in enumerate(data): # 最も近い重心のindex番号をindexesに入れる。 indexes[i] = np.argmin(np.sum((x - centroids) ** 2, axis=1))
# 重心を再計算し更新する。 for i in range(k): centroids[i] = data[indexes==i].mean(axis=0)
for i in range(k): # 確率に従って重心となる点をdataから選ぶ。 centroids[i] = data[np.random.choice(np.arange(n), p=probabilities, size=(1))] # data centroidsの距離の二乗をとる。 distances[:, i] = np.sum((data - centroids[i]) ** 2, axis=1) # probabilitiesを0から1の値に正規化する。 probabilities = np.sum(distances, axis=1) / np.sum(distances)
def forward(self, x): self.x = x return np.dot(x, self.params["w"]) + self.params["b"]
def backward(self, dout): self.grads["w"] = np.dot(self.x.T, dout) self.grads["b"] = np.sum(dout, axis=0) return np.dot(dout, self.params["w"].T)
def forward(self, x): self.mask = (x <= 0) out = x.copy() out[self.mask] = 0 return out
def backward(self, dout): dout[self.mask] = 0 dx = dout return dx
λ⋅sign(W)
λ⋅W
# 設定 grads = {} for idx in range(1, self.hidden_layer_num+2): weight_decay_gradient = self.weight_decay_lambda * self.layers['Affine' + str(idx)].W grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + weight_decay_gradient grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db
for key in params.keys(): self.v[key] = self.momentum * self.v[key] - self.lr * grads[key] params[key] += self.v[key]
for key in params.keys(): self.h[key] += grads [key] * grads [key] params[key] -= self.lr * grads[key] * (1/np.sqrt(self.h [key] + 1e-7))
((h (or w) + 2p - f) / s) + 1
np.pad(array, range, mode(,そのほか)) img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], "constant") img = np.pad(img, [(0,0), (0,0), (p_h, p_h), (p_w, p_w)], 'constant')
# N, CH, H, F # ↓ # N, CH, FH, FW, OH, OW # a:b:c の指定はa~b-1までcステップずつと言う実装で、 # フィルタの要素に対応する畳込の入力データの要素を抽出する。 # 例えば3*3フィルタが適用される場合、1回目左上...3回目右上...7回目左下...9回目右下と、 # 1ステップで取得されるフィルタ[FH, FW]に対応する要素数は[a:b:c]の計算上、特徴マップ数と等しくなる。 # インデックスは単なる索引で構造と捉えない方が良い。 col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
# インデックスをN, [OH, OW]に並び替えて # N, CH, FH, FW, [OH, OW] # ↓ # N, [OH, OW], CH, FH, FW # 行列に展開すれば意図した出力になる。 # ・行数N*OH*OWの列にはフィルタの左上から右下の順に対応する入力画像の要素が(*N)特徴マップ数分入る。 # ・列数CH*FH*FWの行にはフィルタの所定の場所[FH, FW]に対応する入力画像の要素が(*CH)チャネル数分入る。 col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
def conv2d(x, kernel, stride=(1,1), pad=(0,0)): """畳み込み演算を行う - x : 入力画像 (ミニ・バッチサイズ, チャンネル数, 縦幅, 横幅) - kernel : カーネル (カーネル枚数, チャンネル数, カーネル縦幅, カーネル横幅) - stride : ストライド (垂直方向のストライドサイズ, 水平方向のストライドサイズ) - pad: パディング (垂直方向のパディングサイズ, 水平方向のパディングサイズ) """ N, C, H, W = x.shape KN, _, KH, KW = kernel.shape SH, SW = stride PH, PW = pad # 入力画像とフィルタの計算がし易い並びにim2colで展開する col, OH, OW = im2col(x, (N, C, H, W), (KH, KW), (SH, SW), (PH, PW)) # ★フィルタの各要素を展開するが転置するのでKNが列数の # - 行には各フィルタの所定の位置に対応する要素が並ぶ。 # - 列にはフィルタの所定の位置に対応する要素が並ぶ。 kernel_col = kernel.reshape((KN, -1)).T # 行列積を求める(colの行とkernel_colの列が出力に対応するようにする) # - colの行:フィルタの所定の場所[FH, FW]に対応する入力画像の要素が並ぶ。 # - kernel_colの列:フィルタの所定の位置に対応する要素が並ぶ。 conv = np.dot(col, kernel_col) # (枚数, チャンネル数, 縦幅, 横幅) の形に戻して返却 return conv.reshape((x.shape[0], OH, OW, -1)).transpose (0, 3, 2, 1)
import numpy as np n_input = 100 n_hidden = 256 # 重みの行数は入力と隠れ層の列ベクトルの共通化のため要素数を合計したもの。 # 重みの列数は出力の要素数に対応するがゲート3とコンテキスト1の共通化のため4倍にする。 w = np.random.randn(n_input + n_hidden, n_hidden * 4) b = np.zeros (n_hidden * 4) def 1stm(x, h, c): """LSTMの各時刻での中間層を計算する x : 入力層 (バッチサイズ,入力長)の行列 h : 中間層 (パッチサイズ,中間層ユニット数) の行列 c : CEC (パッチサイズ,中間層ユニット数) の行列 # 前述の式の通り入力と隠れ層の列ベクトルを列追加方向に結合 inputs np.concatenate((x, h), axis=1) # ゲートおよび入力のxw + hU + bの項をまとめて計算 inputs = np.matmul(inputs, w) + b # 出力の列ベクトルを4分割 z, i, f, o = np.hsplit(inputs, 4) #※以下省略
#ゲート用のシグモイド関数 def sigmoid (u): return 1.0 / (1.0 + np.exp(-u)) # 各種ゲートを用意 input_gate = sigmoid(i) forget_gate = sigmoid(f) output_gate = sigmoid(o) # CECおよび中間層出力を計算 next_c = c * forget_gate + np.tanh(z) * input_gate next_h = next_c * output_gate return next_c, next_h
L = 1/2(yd^2 + (1−y) max(m−d, 0)^2)
L = max{0, m + dp − dn}
金額が易いプログラムはそれなり。
(ゼロから作るDeep Learning)
徹底攻略ディープラーニングE資格エンジニア問題集 第2版 - インプレスブックス
https://book.impress.co.jp/books/1120101184
(E資格対策)
深層学習ではないんだけど深層学習系の生成モデルばっかなのでココ