20211007のTensorFlowに関する記事は2件です。

3次元配列の各列をシャッフルする

ほぼfeature importance用のコードです。 eli5は1系でしか動作しないと書いてあったし、フレームワーク側の変更で動作しないとかなっても困る。numpy配列のシャッフルが一番可用性が高そうなので作りました。 numpyのシャッフルからのtensor変換 イテレーションごとに配列の再定義 が必要です。 列ごとの要素をとってきてシャッフルして再代入(実際にはshuffleは破壊的処理ですが)するという素朴なつくり。もっとうまくできると思うんだけどなぁ。 特にメモリ・動作速度の観点でレビューお待ちしてます。 # 3次元のnumpyの列をシャッフルする。 # イテレーションごとに3次元配列を再定義しないとすべての列がシャッフルされてしまうので注意 def shuffletensorcolumns_loop(array,i: int) -> None: tmp = array[:,:,i] for j in range(array.shape[0]): np.random.shuffle(tmp[j]) # 破壊的処理なので代入不要 array[:,:,i] = tmp df = np.arange(1,201).reshape(5,4,10) for i in range(df.shape[2]): df2 = df.copy() shuffletensorcolumns_loop(df2,i) print(df2) 追記 メモリチェック df = np.arange(1,201).reshape(5,4,10) for i in range(df.shape[2]): df2 = df.copy() print(id(df)) shuffletensorcolumns_loop(df2,i) print(id(df2)) print(np.may_share_memory(df,df2)) >>> 140643364911504 140643364910064 False 140643364911504 140643365525984 False 140643364911504 140643364911824 False ... 出力を見てもまあメモリ浪費の問題はなさそうだけど、どうなんだろう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

言語処理100本ノック(2020)-72: 損失と勾配の計算(TensorFlow)

言語処理100本ノック 2020 (Rev2)の「第8章: ニューラルネット」の72本目「損失と勾配の計算」記録です。勾配計算はいつもkerasに任せていたので、勾配の取得などしようと思ったこともなく、調べるのに時間がかかりました。本当はkerasを使わずに、自分でコーディングすることこそが良い学習なのでしょうが、取り急ぎkerasを使い続けます。 記事「まとめ: 言語処理100本ノックで学べることと成果」に言語処理100本ノック 2015についてはまとめていますが、追加で差分の言語処理100本ノック 2020 (Rev2)についても更新します。 参考リンク リンク 備考 72_損失と勾配の計算.ipynb 回答プログラムのGitHubリンク 言語処理100本ノック 2020 第8章: ニューラルネット (PyTorchだけど)解き方の参考 【言語処理100本ノック 2020】第8章: ニューラルネット (PyTorchだけど)解き方の参考 まとめ: 言語処理100本ノックで学べることと成果 言語処理100本ノックまとめ記事 公式ガイド: モデルに関する勾配 勾配取得の公式ガイド 環境 後々GPUを使わないと厳しいので、Goolge Colaboratry使いました。Pythonやそのパッケージでより新しいバージョンありますが、新機能使っていないので、プリインストールされているものをそのまま使っています。 種類 バージョン 内容 Python 3.7.12 Google Colaboratoryのバージョン google 2.0.3 Google Driveのマウントに使用 tensorflow 2.6.0 ディープラーニングの主要処理 第8章: ニューラルネット 学習内容 深層学習フレームワークの使い方を学び,ニューラルネットワークに基づくカテゴリ分類を実装します. ノック内容 第6章で取り組んだニュース記事のカテゴリ分類を題材として,ニューラルネットワークでカテゴリ分類モデルを実装する.なお,この章ではPyTorch, TensorFlow, Chainerなどの機械学習プラットフォームを活用せよ. 72. 損失と勾配の計算 学習データの事例$x_1$と事例集合$x_1$,$x_2$,$x_3$,$x_4$に対して,クロスエントロピー損失と,行列$W$に対する勾配を計算せよ.なお,ある事例$x_i$に対して損失は次式で計算される. $$l_i=−log[事例x_iがy_iに分類される確率]$$ ただし,事例集合に対するクロスエントロピー損失は,その集合に含まれる各事例の損失の平均とする. 回答 回答結果 これ見ても何も判断できないですが、一応回答結果です。1行目がLossで、行列部分が勾配。 結果(事例1件) 1.3719598 dense_1/kernel:0, shape: (300, 4) [[-0.06244335 0.02067989 0.02176488 0.01999857] [-0.00420518 0.00139266 0.00146573 0.00134678] [-0.00508651 0.00168454 0.00177292 0.00162904] ... [-0.05607251 0.01857001 0.0195443 0.0179582 ] [-0.03232378 0.01070494 0.01126659 0.01035225] [ 0.06478423 -0.02145514 -0.02258081 -0.02074828]] 結果(事例集合4件) 1.3873249 dense_1/kernel:0, shape: (300, 4) [[-0.05536687 0.00082223 0.08464365 -0.03009901] [ 0.01126796 -0.01080388 -0.03230093 0.03183684] [-0.03271427 0.06947812 -0.0883422 0.05157837] ... [-0.09661584 0.08457799 -0.00822031 0.02025817] [-0.00410734 0.08742411 0.00315564 -0.08647241] [ 0.07903252 0.00211453 0.01354344 -0.09469048]] 回答プログラム 72_損失と勾配の計算.ipynb GitHubには確認用コードも含めていますが、ここには必要なものだけ載せています。 import tensorflow as tf from google.colab import drive drive.mount('/content/drive') BASE_PATH = '/content/drive/MyDrive/ColabNotebooks/ML/NLP100_2020/08.NeuralNetworks/' train_raw = tf.data.TFRecordDataset(BASE_PATH+'train.tfrecord') def _parse_function(example_proto): # 特徴の記述 feature_description = { 'title': tf.io.FixedLenFeature([], tf.string), 'category': tf.io.FixedLenFeature([], tf.string)} # 上記の記述を使って入力の tf.Example を処理 features = tf.io.parse_single_example(example_proto, feature_description) X = tf.io.decode_raw(features['title'], tf.float32) y = tf.io.decode_raw(features['category'], tf.int32) return X, y dense_layer = tf.keras.layers.Dense( 4, activation='softmax', input_dim=300, use_bias=False, kernel_initializer='random_uniform') def print_loss_gradients(batch_size): for X, y_true in train_raw.map(_parse_function).batch(batch_size).take(1): print('---y_true---') print(y_true.numpy()) with tf.GradientTape() as tape: y_pred = dense_layer(X) print('---y_pred---') print(y_pred.numpy()) loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred) print('---loss---') print(tf.math.reduce_sum((loss.numpy()/batch_size)).numpy()) grad = tape.gradient(loss, dense_layer.trainable_variables) for var, g in zip(dense_layer.trainable_variables, grad): print(f'{var.name}, shape: {g.shape}') print(g.numpy()) print_loss_gradients(1) print_loss_gradients(4) 回答解説 勾配の記録 GradientTapeを使って勾配を記録します。with内で記録するための計算を書きます。 with tf.GradientTape() as tape: y_pred = dense_layer(X) print('---y_pred---') print(y_pred.numpy()) loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred) print('---loss---') print(tf.math.reduce_sum((loss.numpy()/batch_size)).numpy()) gradient関数で勾配を入出力を渡して取得します。 grad = tape.gradient(loss, dense_layer.trainable_variables) 今回はバイアス項がないのでforでまわしても1件しか取得出来ませんが、バイアス項があると複数回ループして取得できます。 for var, g in zip(dense_layer.trainable_variables, grad): print(f'{var.name}, shape: {g.shape}') print(g.numpy()) 1件のみ取得するとこんな出力です。 結果(事例1件) ---y_true--- [[1 0 0 0]] ---y_pred--- [[0.25360948 0.24718848 0.2601575 0.23904456]] ---loss--- 1.3719598 dense_1/kernel:0, shape: (300, 4) [[-0.06244335 0.02067989 0.02176488 0.01999857] [-0.00420518 0.00139266 0.00146573 0.00134678] [-0.00508651 0.00168454 0.00177292 0.00162904] ... [-0.05607251 0.01857001 0.0195443 0.0179582 ] [-0.03232378 0.01070494 0.01126659 0.01035225] [ 0.06478423 -0.02145514 -0.02258081 -0.02074828]]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む