こしあん
2019-01-12

TensorFlowで値のソートをする方法

Pocket
LINEで送る


TensorFlowでNumpyのnp.sortやnp.argsortのようなソートを行うことを考えます。一般にTensorFlowで値のソートというと、自動微分もあわさって難しいように思えますが、実はちゃんとソートできます。うまくやればKerasからも使うことができます。

tf.nn.top_k()を使う

tf.nn.top_k (tf.math.top_kも同じ)
https://www.tensorflow.org/api_docs/python/tf/math/top_k

本来この関数はImageNetなど、分類問題での「Top-5 Acuuracy」といった評価関数の計算に用いられるものです。「top_k」という名前がついていてわかりづらくなっていますが、内部的にやっているのはソートに他なりません。

入力次元=kの値ならただのソート

例えば、「入力次元=kの値」とすると、完全なソートになります。np.sort()とほぼ同じ感覚で使えます。

import numpy as np
import tensorflow as tf
import keras.backend as K

# 点数のソート
score = np.array([70,90,80,95], dtype=np.float32)
score_tensor = tf.Variable(score)
sorted = tf.nn.top_k(score_tensor, k=4).values

result = K.eval(sorted)
print(result)
# [95. 90. 80. 70.]

出力は降順となりますが、昇順で取りたければスライス([::-1])で取るか、「sorted=False」と指定します。ただし、「sorted=False」かつ入力次元=kの値の場合は、降順ソートのままの出力になってしまうバグがある(1.12.0時点)ので注意してください。スライスの場合は特に問題ないです。

ちなみにsortedの中身をvaluesではなくindicesとすると、“np.argsort()“`とほぼ同じになります。

# 点数のソート
score = np.array([70,90,80,95], dtype=np.float32)
score_tensor = tf.Variable(score)
sorted = tf.nn.top_k(score_tensor, k=4).indices

result = K.eval(sorted)
print(result)
#[3 1 2 0]

ちなみに、「.indices」や「.values」による指定をなくすとKerasのK.eval()で評価することができなくなります。

    return to_dense(x).eval(session=get_session())
AttributeError: 'TopKV2' object has no attribute 'eval'

Keras側からtf.nn.top_kを呼び出す際は、「.indices」や「.values」の指定をしたほうがいいかもしれません。TensorFlowで完結する場合は特に問題ないでしょう。

kの値を指定すると「ORDER BY desc~LIMIT k」に相当

SQLでよくやるやつ

score = np.array([70,90,80,95], dtype=np.float32)
score_tensor = tf.Variable(score)
sorted = tf.nn.top_k(score_tensor, k=2).values

result = K.eval(sorted)
print(result)
# [95. 90.]

うまくいきました。

行列に対してもできる

行列の場合もソートできます。最後の次元に対してソートを行います。

import numpy as np
import tensorflow as tf
import keras.backend as K

# 1行目が数学、2行目が英語
score = np.array([[70,90,80,95], [8,6,10,9]], dtype=np.float32)
score_tensor = tf.Variable(score)
sorted = tf.nn.top_k(score_tensor, k=3)

print(K.eval(sorted.indices))
#[[3 1 2]
# [2 3 0]]
print(K.eval(sorted.values))
#[[95. 90. 80.]
# [10.  9.  8.]]

教科別の得点(axis=1)でソートされているのがわかります。便利ですねこの関数。

Related Posts

pix2pixを1から実装して白黒画像をカラー化してみた(PyTorch)... pix2pixによる白黒画像のカラー化を1から実装します。PyTorchで行います。かなり自然な色付けができました。pix2pixはGANの中でも理論が単純なのにくわえ、学習も比較的安定しているので結構おすすめです。 はじめに PyTorchでDCGANができたので、今回はpix2pixをやり...
pipからインストールしたTorchVisionにImageNetがないときの対応... TorchVisionの公式ドキュメントにはImageNetが利用できるとの記述がありますが、pipからインストールするとImageNetのモジュール自体がないことがあります。TorchVisionにImageNetのモジュールを手動でインストールする方法を解説します。 発生状況 Pytho...
ディープラーニング=最小二乗法のどこがダメなのか解説する... あるニュース記事で、ディープラーニング=最小二乗法で三次関数なんていう「伝説の画像」が出回っていたので、それに対して突っ込みつつ、非線形関数という立場からディープラーニングの本当の表現の豊かさを見ていきたいと思います。 きっかけ ある画像が出回っていた。日経新聞の解説らしい。 伝説の画像にな...
条件に応じた配列の要素の抽出をTensorFlowで行う... Numpyで条件を与えて、インデックスのスライスによって配列の要素を抽出する、というようなケースはよくあります。これをTensorFlowのテンソルでやるのにはどうすればいいのでしょうか?それを見ていきます。 Numpyではこんな例 例えば、5×5のランダムな行列をデータとします。この配列を左...
PyTorch/TorchVisionで複数の入力をモデルに渡したいケース... PyTorch/TorchVisionで入力が複数あり、それぞれの入力に対して同じ前処理(transforms)をかけるケースを考えます。デフォルトのtransformsは複数対応していないのでうまくいきません。しかし、ラッパークラスを作り、それで前処理をラップするといい感じにできたのでその方法を...
Pocket
Delicious にシェア

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です