TensorFlow

【TensorFlow】Tensorの形状でサイズ1の次元を削除する方法

【TensorFlow】Tensorの形状でサイズ1の次元を削除する方法

Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensorの形状でサイズ1の次元を削除する方法を解説します。

Tensorの形状でサイズ1の次元を削除する方法

Tensorで形状はshapeプロパティを確認することで確認することができます。Tensorの情報確認方法は「Tensor情報の確認方法」で紹介していますので参考にしてみてください。

本記事では、Tensorの形状(shape)でサイズが1になっているような次元を削除する方法について紹介します。

tf.squeezeでサイズ1の次元を削除する

Tensorの形状でサイズ1の次元を削除するには、以下のようにtf.squeezeを使用します。

import tensorflow as tf

tf.random.set_seed(42)
tensor = tf.constant(tf.random.uniform(shape=(10,)), shape=(1, 1, 1, 1, 10))
print(tensor, "\n")

# サイズが1の次元を削除する tf.squeeze
squeezed_tensor = tf.squeeze(tensor)
print(squeezed_tensor)
【実行結果】
tf.Tensor(
[[[[[0.6645621  0.44100678 0.3528825  0.46448255 0.03366041 0.68467236
     0.74011743 0.8724445  0.22632635 0.22319686]]]]], shape=(1, 1, 1, 1, 10), dtype=float32) 

tf.Tensor(
[0.6645621  0.44100678 0.3528825  0.46448255 0.03366041 0.68467236
 0.74011743 0.8724445  0.22632635 0.22319686], shape=(10,), dtype=float32)

上記では、もともとのTensor形状は(1, 1, 1, 1, 10)でしたが、tf.squeezeを使用することでサイズが1の次元が削除されて(10, )となっていることが分かります。

Note

tf.squeezeの公式ドキュメントはこちらを参照してください。

tf.squeezeの使用場面例

tf.squeezeを用いるような場面例の一つを紹介したいと思います。例えば、回帰問題で正解値y_trueと機械学習モデルが予測した予測値y_predを用いて、指標のmae(mean absolute error)を計算する場面を考えてみましょう。

maeは以下のように正解値と予測値の差の絶対値の平均です。ここで$y_{i}$は$i$番目の正解値、$\hat{y}_{i}$は$i$番目の予測値を表し、$n$はデータ数です。

\[
\mathrm{mae} = \frac{1}{n}\sum_{i=1}^{n}|y_{i} - \hat{y}_{i}|
\]

なお、maeは、Kerasのtf.keras.metrics.mean_absolute_errorで簡単に計算ができます。

想定通りにならない場合

では、具体的に例を使って試してみましょう。以下のプログラムにおいて正解値や予測値は説明のために作成した適当な数字です。実際の例ではy_trueはテストデータなどの正解値で、y_predは訓練したモデルで予測した結果だと思ってください。

import tensorflow as tf

# 正解値
y_true = tf.constant([70, 74, 78, 82, 86, 90, 94, 98, 102, 106], dtype=tf.float16)
# 予測値
y_pred = tf.constant(
    [
        70.32939,
        74.9041,
        79.47879,
        84.05348,
        88.628174,
        93.202866,
        97.77756,
        102.35226,
        106.92695,
        111.50165,
    ],
    shape=(10, 1),
    dtype=tf.float16,
)

# mae (mean absolute error)を計算する (想定した結果にならない...)
mae = tf.keras.metrics.mean_absolute_error(y_true, y_pred)
print(mae)
【実行結果】
tf.Tensor([17.75 14.27 11.8  10.39 10.   10.64 12.3  15.1  18.94 23.5 ], shape=(10,), dtype=float16)

maeは差の絶対値の平均値なので、10個の正解値と予測値の差を計算し、その平均として結果が1つの値で出て欲しいわけですが、どうやら思った計算結果となっていません。

原因はTensorの形状がy_trueが(10, )であるのに対して、y_predが(10, 1)のように異なってしまっているためです。

tf.squeezeを使った対応

では、上記ような時にtf.squeezeを使用いて対応する例を見てみましょう。以下のようにtf.squeezeを使ってy_predのサイズが1の次元を削除すると計算がうまくいきます。

import tensorflow as tf

# 正解値
y_true = tf.constant([70, 74, 78, 82, 86, 90, 94, 98, 102, 106], dtype=tf.float16)
# 予測値
y_pred = tf.constant(
    [
        70.32939,
        74.9041,
        79.47879,
        84.05348,
        88.628174,
        93.202866,
        97.77756,
        102.35226,
        106.92695,
        111.50165,
    ],
    shape=(10, 1),
    dtype=tf.float16,
)

# mae (mean absolute error)を計算する (squeezeで形状を揃える)
mae = tf.keras.metrics.mean_absolute_error(y_true, tf.squeeze(y_pred))
print(mae)
【実行結果】
tf.Tensor(2.912, shape=(), dtype=float16)

結果を見てみると、maeが正確に計算できていることが分かります。

上記のように計算途中でTensorの形状により計算結果が想定した結果にならない場合があります。上記はあくまで一例ですが、このようにサイズ1の次元を削除する必要が出てきたときのためにtf.squeezeを覚えておくと便利です。

まとめ

Googleによって開発されている機械学習ライブラリであるTensorFlowで、Tensorの形状でサイズ1の次元を削除する方法を解説しました。

Tensorの形状でサイズ1の次元を削除するにはtf.squeezeを使用します。

ディープラーニングのプログラミングの計算時などで、Tensorの形状により計算結果が想定した結果にならない場合等もあります。このような時でサイズ1の次元が悪さをしているようであればtf.squeezeで削除してしまうのが便利です。tf.squeezeの使い方を覚えておくとよいでしょう。

Pythonによるディープラーニング」はTensorFlow/Kerasの中~上級者向けの本ですが非常におすすめです。CNN, RNN, Transformer, GAN等高度なモデルも扱っており面白い&TensorFlow/Kerasの実装力をつけることができます。