Machine Learning with TensorFlow Google Cloud
How Google does Machine Learning
トレーニング → 運用化
ML モデル 4000 個以上
問題を小分けにして複数のモデルを使う
1番目のモデルで 特定店舗での商品の需要を予測し 2番目のモデルで サプライヤーの倉庫と近隣店舗での 商品在庫を予測できます 3番目のモデルで 商品の確保にかかる時間を予測し さらに補充商品の注文先サプライヤーと 注文のタイミングを予測できます
直列にこういうのやると誤差が累積してイマイチにならないのか気になる
RankBrain
Cloud Video Intelligence API
Text-To-Speech
問題のフレーム化
製造業の需要予測
部品 X の製造量を予測する → どんなデータが必要か
売上個数の履歴、販売価格、返品個数、他社製品の価格、部品Xを使用する製品の数、すべての商品の数、経済統計、顧客の信頼性、金利情報...
誰のためのサービスか
エキスパートが注目している特徴を使う
モデルの複雑さよりモデルの量
タスクのために、単純なモデルをつなぎ合わせる、早く失敗する
最高
1人 → 委任 → デジタル化 → ビッグデータとアナリティクス → 機械学習
Launching into Machine Learning
https://gyazo.com/415ab45100b46f344942acac01c687a5
交差エントロピー
線形回帰モデルを作る回
ロジスティック回帰
用途に応じて閾値をどう設定するか → 混同行列の話 正負の方向に全体的にシフトしていないか(classification のバイアス)
予測の平均値とラベルの平均値を比較して近くになければ偏っている可能性がある
テストセットとの誤差が減っていって(学習が進んで)、増えていく(過学習)点で early stop する話
正則化と early stop 両方使う
キャリブレーションプロット
実際の値は 0, 1、予測値は (0,1) の確率
https://gyazo.com/c45222deb31891e979c2dbc4817085d9
gs://cloud-training/mlongcp/v3.0_MLonGC/toy_data/bank-marketing_toy.csv
RMSE が2値分類の損失関数に適していない話から交差エントロピーへ
勾配降下法
どの方向に進むか & どれぐらい進むか
傾きの正負 と 傾きの大きさ
学習率 スケーリングパラメータ
複数の最小値がある場合
凸表面かそうでないか
学習を早く終わらせるには
微分係数を計算する際のデータポイントの数 & 損失チェックの頻度
損失のチェックに使うデータポイントを減らすのはおすすめではない
https://gyazo.com/0f6516bc7ac621aa2e2c187bbe40f5e5
ミニバッチ勾配降下法
訓練データからサンプリングして一部を使う
TensorFlow Playground
学習率上げると Weight が大きくなる話
線形では無理なので特徴をふやそう
ここまでのだとうまくいかないね
活性化関数 & 隠れ層
非線形の特徴増やさなくても隠れ層でやる
8 > 8 > 5 で
バッチサイズを増やすと損失曲線がなめらかになる話
個々のデータポイントのノイズが出にくくなる
単純に収束率に影響するわけではない
パフォーマンス指標
完璧な損失関数を探すのは大変 or ない → 学習し終えたモデルを評価する指標
データセットのサンプリング
訓練・検証・テストを再現可能な形で分割する
MOD(ABS(FARM_FINGERPRINT(col)),10) < 8
Intro to TensorFlow
tensor = データのN次元の配列
scalar → vector → matrix → ...
= rank0 tensor → rank1 → rank2 → ...
グラフで演算を表現して移植性高い
高性能ハードウェアで訓練してモデルをモバイルで実行
エッジモデル
はい
https://gyazo.com/72c12ca8e5ac7660e446ed06d7baf3a4
API 階層
ハードウェア
CPU / GPU / TPU ...
Core TensorFolow (C++)
低レベル C++ APIがある
Core TensorFlow (Python)
tf.losses / tf.metrics / tf.optimizers, ...
機能別のコンポート群、カスタム NN モデルを作る時に使う(それほど使わない)
tf.estimator, tf.keras, tf.data
High-level API
tensor
tf で簡単な低レベル API で簡単な回帰を解く
loss_mse を定義
tf.data.experimental.make_csv_dataset
batch_size が1回に取り出すサイズ、dataset.take(1) で 帰ってくる行数
code:take.py
for batch, label in dataset.take(1):
for key, value in batch.items():
...
tf.stack
tf.feature_column は非推奨、Keras でやる
tf.data でパイプラインを作るために preprocessor を定義して map で加工する感じかな
tf.feature_column.numeric_column
tf.feature_column.indicator_column
untar, fname
tf.keras.preprocessing.image.ImageDataGenerator
flow_from_directory でバッチや画像サイズを指定
classes ごとにディレクトリが必要? → そう
ここでは keras は It lacks fine-grained control. なんだ
label 返すやつ意味不明と思ったけど、マッチするクラスが true な bool の tensor を返すのね
tf.constant([2]) == [1,2,3] #=> [False, True, False] みたいなかんじ
tf.strings.split したら結果も tensor
亀じゃん
https://gyazo.com/69d442fb31a374293748d260ee23dcc4
sklearn.model_selection.train_test_split
tf.data.Dataset.from_tensor_slices((dict(df), labels))
df → dataset へ加工するのに一番いい方法どれなんだろ?
for feature_batch, label_batch in train_ds.take(1): で回していく
tf.feature_column.numeric_column
normalizer_fn
tf.feature_column.bucketized_column
属するバケット以外 0 のベクトルになる
tf.feature_column.categorical_column_with_vocabulary_list & tf.feature_column.indicator_column
1-hot encoding になる、drop_first あまり見ないけど NN ではいいのかな?
tf.feature_column.embedding_column
でもこれ何をどうベクトルにしてるの? 辞書とかエンコーダーとか...
tf.feature_column.categorical_column_with_hash_bucket
ハッシュバケット特徴量、これもカテゴリが多すぎる時に
別の特徴が同じバケットに入ることもありうるけど、辞書なしで無理やり次元を減らせる
tf.feature_column.crossed_column
クロス特徴量、特徴の組をハッシュバケットに
今はだいたい Keras でやりそうなのでどうやるのか
年齢をバケット化するときにちょうどよい分割点はどう探す? なにか定番のやり方ないか
バケットの間隔は伸縮させてもいいだろう
相関係数の分散が大きくなるような分割点を探すみたいな
n 分位数で切ると各バケットに含まれる数が揃うとか
tf.data からの読み込み、これ知りたかった
dataset = dataset.batch(batch_size, drop_remainder=True)
batch_size ずつ取り出して末尾の足りないぶんは捨てる
dataset.map(...) で変換しつつイテレーションできる
dataset.map(...).cache()
dataset.shuffle(1000) の 1000 はバッファ、データサイズと同じかより大きく
dataset.prefetch(1) 1 で AUTOTUNE
ドキュメント読むと tf.data.AUTOTUNE は -1 なんだが...
pip install fairness-indicators
動かないなー & バージョン指定外したら後続がだめ
活性化関数
ReLU variants
Softplus / Leaky ReLU / Parametric ReLU / ELU / GELU
失敗例: 購買消失 / 勾配爆発 / 機能しなくなった層
feature columns guide が 404
tf.keras.model.Sequential で model を作る
compile に optimizer, loss function, metrics を渡す
metrics = 学習エポックごとに出力する指標
model の学習
.fit() メモリに収まる小さいモデルならこれ
.fit_generator()
.train_on_batch() 1バッチごとに細かく制御するためのもの
model.fit の引数
callbacks=[TensorBoard(LOGDIR)], ログ書きつつ TensorBoard を表示する?
model.summary()
なんか全然誤差減ってってないが...
tf.saved_model.save で書き出す
saved_model_cli
aiplatform.Model.upload
ここにきて API 有効済み & Workbench が作成済み
Dense(... input_shape=(4,)) DenseFeature が model の中に入ってないパターン?
tf.nn.relu
tf.nn.softmax
分類なので softmax で出力層の合計を 1.0 にして各クラスの確率にしている
tf.math.reduce_sum(..., axis=1) しても誤差はあるけどだいたい1
tf.keras.metrics.Mean() / tf.keras.metrics.SparseCategoricalAccuracy()
metrics 学習中の誤差や精度を記録するオブジェクト
不均衡データ
np.bincount まあつかわなそう
amount の範囲が広すぎるから log scale へ
keras.metrics.TruePositives みたいな 混同行列 のそれぞれのセルが metrics にある input_shape=(train_features.shape[-1],) このイディオムは度々使いそう
keras.layers.Dropout(0.5) 層を追加して過学習防ぐ / どこに追加するのが良いとかある?
ここでの bias _initializer は何?
np.log([pos/neg]) を bias に渡している
model.save_weights
plt.semilogy 片対数ね
model.fit の返り値に history
重み
登場頻度の低いデータに重みをつける
weight_for_1 = (1 / pos)*(total)/2.0 これは何由来?
oversampling
tf.data.experimental.sample_from_datasets([pos_ds, neg_ds], weights=[0.5, 0.5])
正例負例それぞれのデータセットを作って半々に取り出している?
サンプリングによって均衡させている感じかな
But when training the model batch-wise, as you did here, the oversampled data provides a smoother gradient signal: Instead of each positive example being shown in one batch with a large weight, they're shown in many different batches each time with a small weight.
あんまりわかってない
重みを増やすより繰り返し登場するほうがなめらかな勾配信号になる(ので良い)
学習が容易なのですぐにオーバーフィットしてしまうので callbacks.EarlyStopping を追加
リンク
tensorflow.keras.layers.Input で入力を定義
np.linspace(start=38.0, stop=42.0, num=NBUCKETS).tolist() で lat のバケット作って特徴量に
tf.keras.layers.Discretization で離散的な特徴に
エポックやステップ数の話
Links
Vertex AI Feature Store の話
https://gyazo.com/7a4ce9c2b36c8218ac29af115c554827
特徴量モニタリング
Online Serving に tf.dataset との連携とかないのかな
Batch Serving だと Clodu storage に TFRecord で書き出す機能がある
Featurestore > EntityType > Feature
先にデータ構造を一通り定義して BigQuery Table / Avro / CSV から import
カテゴリ変数だけど事前列挙できないものの扱い
欠損値として 0 のままにする / 平均などで埋める / HashBucket にする 等
batch normalization
ML.FEATURE_CROSS(STRUCT(features))
TRANSFORM(ML.FEATURE_CROSS(STRUCT(features)), ML.BUCKETIZ(f, split_points ...)
特徴クロスはスパースな入力になる
ML.EVALUATE で評価用データを渡さなくてよいのはモデルタイプによって勝手に内部で分割しているから
ST_SNAPTOGRID(geography_expression, grid_size) で緯度経度を離散化してクロス
ML.POLYNOMIAL_EXPAND(STRUCT(features), degree) これ
良い図
https://gyazo.com/46eda5c1c168cfa25142d9a05b7d5249
@tf.function これなに
code:dayofweek.py
@tf.function
def dayofweek(ts_in):
return tf.map_fn(
lambda s: tf.py_function(get_dayofweek, inp=s, Tout=tf.string), ts_in)
keras.layers.Lambda でスケーリングしたり変換したり
この notebook はサンプルコードとして良い
x と y を離散化して乗算するとグリッドになる → playground の渦巻きもグリッドに当てはめて分類できる
tf.transform で変換
ストリーミングしつつ最大値や最小値を利用できる
バックエンドが Apache Beam になるの...
ひどすぎる
https://gyazo.com/d3da9ad688172fd4b2adbc5073f5fe9b
正則化 (regularization)
学習の目的は誤差の最小化
過学習で Test Data と Training Data の誤差の曲線が乖離している様子
モデルの複雑さを抑制する
一般化理論 / オッカムの剃刀 / 仮定が少ないモデルが良い
モデルの複雑さと誤差のバランス
Early Stopping
Parameter Norm Penalties
L1 regulrization
L2 regularization
Max-norm regularization
Dataset Augmentation
Noise Robustness
Sparse Representations
...
複雑さにペナルティを与える
ここでは L1 & L2 regularization をやる
モデルの複雑さをどう測るか
重みベクトルの大きさ
$ w= \begin{pmatrix} a \\\ b \end{pmatrix}
L2 Norm: $ \sqrt{a^2+b^2}
L1 Norm: $ |a|+|b|
$ \lambda: モデルの単純さをどの程度にするか係数
$ L(w,D)+ \lambda||w||_2 を最小化する
ラッソ回帰: 正則化に L1 を使う
リッジ回帰: 正則化に L2 を使う
動かしながら右上の Test loss と Training loss の乖離を見ていく
L1 で使われる特徴がだいぶ絞られる / L2 だと他のもちょっと使われている 様子を見る
Regularization rate を上げすぎると何も学習できない
学習率とバッチサイズ
学習率小さいと時間かかるけど収束がスムーズ(学習曲線に変なガタツキがでない?)
ステップのサイズ
大きいとバウンドして最適なポイントを見逃す可能性がある
0.001 = ステップサイズが入力空間の 1/1000
バッチサイズは勾配の計算に使うサンプル数
小さすぎるとバッチジョブが入力を十分に表現しない
入力をシャッフルする
バッチ内で勾配を計算する際に学習データのソート順の影響を受けてしまう
バッチがデータセット全体を表現するようにシャッフルする
実際どのぐらいにするの
一定 epoch で学習率大きくしたり小さくしたり
最適化
GradientDescent(勾配降下法)
Adam ← AdaGrad
Ftrl (Follow the regularized leader)
keras デフォルトの学習率は?
ハイパーパラメータ
学習率、正規化率、バッチサイズ、隠れ層数、ニューロン数
https://gyazo.com/77f94dc5c2edea1f77481cabce5ae6dc
momentum がわかってない
Google Vizier
L2ノルムは通常 L1ノルムよりも 一般化可能なモデルを提供します ただしL1でなくL2を使用すると モデルははるかに複雑で重くなります これは特徴同士に高い相関性が あることが多いからです L1正則化ではその一方が使用され 他方は破棄されますが L2正則化では両方の特徴が維持され それらの重みは小さく保たれます そのためL1ではモデルは小さくなりますが 予測性は下がることがあります
Elastic nets
L1 と L2 を足したもの / ハイパーパラメータが2つになる
Regularization L1 オンにしたら2つの特徴だけでいけてる
ノイズめっちゃ増やすと?
50 とかだと収束しないけど、45 あたりでも2つの特徴になる
正則化なくしても loss はあんまかわらない
ロジスティック回帰
logit 関数で で 0~1 にマップして分類に使う
バイナリ分類の問題を確率の問題に
code:quote
シグモイド活性化関数では 基本的に線形回帰から 加重和のwTxに 線形回帰のBを加えましたが 単にそれを出力して 平均二乗誤差損失を計算する代わりに 活性化関数を直線から シグモイドに変換すると それが引数となりゼロと1の間に 滑らかに並べられます シグモイドへの入力は通常 線形回帰の出力ですが これがロジットと呼ばれます これが線形モデルの 非線形変換です ロジットが負の無限大になると 確率はゼロに漸近し 正の無限大になると1に漸近することに 注意してください これはトレーニングに どんな意味を持つでしょうか 平均二乗誤差と違いシグモイドでは 1.0や0.0の確率は推測されません つまり勾配降下法では損失が 限りなくゼロに近付けられるため 正則化を行わなければ 重みは限りなく正または負の無限大に近付き それによって問題が 生じることになります まずシグモイドの出力は どう解釈できるでしょうか 単なる0~1までの 数多くの関数でしょうか または何かそれ以上のものでしょうか 幸いこれは それ以上のものです これは校正された 確率の推定値です シグモイド関数は単なる範囲ではなく ロジスティック確率分布の 累積分布関数なので 分位関数はロジットの逆数になり これが対数オッズをモデリングします そのため数学的にはシグモイドの逆を 確率と考えることができます このように校正は 出力が確率のような実数値であることを 示す事実だと考えられます これは埋め込みベクトルのような 校正されていない出力が 内部的には参考になるが 値に真の相関関係はないのと対照的です 0~1の数値を提示できる 出力活性化関数は無数にありますが 訓練データセットの発生率の 校正済みの推定値だと実証されているのは このシグモイドだけです シグモイド活性化関数についての この事実を利用すれば バイナリ分類の問題を 確率の問題に変換できます
AUC の話
0.5 を閾値にするのではなく目的によって閾値を調整する
バイアスの確認、予測値とラベルの平均が近いか
非線形な活性化関数を入れないと単層の線形モデルと表現できることは変わらない
ReLU variants の話
Leaky ReLU: 負領域なら 0.01x
Parametric ReLU: 0.01 をパラメータ化
ReLU6
ELU
特徴を増やさずネットワークでがんばる回
勾配爆発 & 勾配消失 & ReLU の不感化
重み正則化・バッチサイズの縮小
勾配クリッピング
閾値を超えたら最大値を下回るようにする
空間的標準化
0中心にスケールを合わせる
適切な学習率が異なってうまく収束しない
対数スケーリング
範囲が広いデータ
標準化
学習率を下げる
ドロップアウト
目安 20~50% ぐらい
マルチクラス
二項分類: 1:他
他のクラスに入らない確率を予測する
データ分布が不均衡になる
出力クラスごとに 1, 0
よくあるやつ
ラベルと確率の両方が相互排他的な場合
tf.nn.softmax_cross_entropy_with_logits_v2
ラベルが相互排他的で 確率が違う場合
tf.nn.sparse_softmax_cross_entropy_with_logits
合計が1でなくてもいい場合?
ラベルが相互排他的でない場合
tf.nn.softmax_cross_entropy_with_logits
各クラスの確率を得られる(画像に犬と猫が入っててそれぞれ検出する)
クラスが多いとき
tf.nn.sampled_softmax_loss 0 部分の計算コスト下げる
学習時はこれ使って推論時は実際の softmax を使う
Links
Embedding の話、これ見たいがために遠回りした感
スパースデータの扱い / 次元数を削減/
再利用可能性
カテゴリ → Feature Cross → NN で使う
特徴クロスを 1-hot してそのまま利用する代わりに結合層の値を使う
結合層の値 = 特徴クロスから学習された加重和
https://gyazo.com/4cb362d331731fc48e6763d223a1abe8
曜日 * 時間帯 = 68 → 2個
時間帯 → 交通量の埋め込みを他のことに使う
学習したのと別の都市に使う / テレビの視聴率の予測
同じ潜在因子に依存している8
転移学習
映画のレコメンドで Embedding を使う
アートシアター系って言うんだ
50万作品 → 平均年齢 * チケットの売上 の2つの特徴を選んだ
どう学習するねんというところまで行ってない
スパースなテンソルの扱い
1-hot すると多すぎる
tf.feature_column.categorical_column_with_vocabulary_list でスパースなテンソル扱える
自然言語から embedding の学習
https://gyazo.com/048d04a670645d4dd58882cd0220b922
そぼぎ、横に置く num_rooms や num_beds に依存した値になったりしないのかな
MNIST のピクセルを 3 embedding にして Tensorboard で3次元空間に可視化
実際に同じラベルのものが近いところに位置している
クラスタリングにも使える話
Embedding の次元数はハイパーパラメータ
目安: 4乗根を使う
50万の映画 → 25くらいからはじめる、15~35 ぐらいのハイパーパラメータを探索
Math.sqrt(Math.sqrt(500000)) #=> 26.59
前やった
embeding をどう学習するか / 再利用するかあたりが興味あるんだが...
Links