tf.reduce_sum() 関数と tf.reduce_mean() 関数をようやく理解しました

参考ブログ:

1. https://www.zhihu.com/question/51325408/answer/125426642

2. https://www.w3cschool.cn/tensorflow_python/tensorflow_python-5y4d2i2n.html

3. https://blog.csdn.net/dcrmg/article/details/79797826

ニューラル ネットワークの構築を学んでいたとき、他の人のコードをコピーしたのですが、理解できないコードが 1 行ありました。それは次の行です。

loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices=[1]))

当初、うp主が書いたコードは以下のようなものでした。

loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction)))

すると、次のような結果が表示されました。

709758.1
nan
nan
nan
nan
nan
nan
nan
nan
nan
nan

時間の無駄です。初心者の私が最初に考えたのは、女の子を見つけることでした。しかし、見つけた方法はどれも機能しませんでした。その後、関数をチェックし始め、最終的に理由を見つけました。問題は、reduce_sum() にあります。関数、ははは、そして Xiaobai で、reduce_sum() を学び、reduce_mean() も学ぶためにブログを探し始めました。いくつかの記事を読んだ後でも、まだ混乱していました。なぜ、reduction_indices=[0] ではなく、reduction_indices=[1] を使うのでしょうか?というか全く使わないのはもったいないので、苦労してやっとわかったので早速記録してみました!
-------------------------------------------------- - - - - - - - - - - -分割線 - - - - - - - - - - - - - - -------------------------------------------------- -----
1.tf.reduce_mean 関数は、指定された軸 (テンソルの特定の次元) に沿ったテンソルの平均値を計算するために使用されます。主に次元削減またはテンソルの平均値を計算するために使用されます。 (画像)。

reduce_mean(input_tensor,
                axis=None,
                keep_dims=False,
                name=None,
                reduction_indices=None)
  • 最初のパラメータ input_tensor: 削減される入力テンソル。
  • 2 番目のパラメーター axis: 指定された軸。指定されていない場合は、すべての要素の平均が計算されます。
  • 3 番目のパラメーター keep_dims: 次元を削減するかどうか。True に設定すると、出力結果は入力テンソルの形状を維持します。False に設定すると、出力結果は次元を削減します。
  • 4 番目のパラメータ名: 操作の名前。
  • 5 番目のパラメーターduction_indices: 以前のバージョンで軸を指定するために使用されていましたが、
    非推奨になりました。2.tf.reduce_sum 関数はテンソルの各次元の要素の合計を計算します。通常は 2 つのパラメーターを設定するだけで済みます。
reduce_sum ( 
    input_tensor , 
    axis = None , 
    keep_dims = False , 
    name = None , 
    reduction_indices = None
 )
  • 最初のパラメータ input_tensor: 入力テンソル
  • 2番目のパラメータreduction_indices: 要素の合計がどの次元に沿って計算されるかを指定します。

一番難しいのは次元の問題ですが、とにかくいくつかのブログを読んだのですがよく理解できず、結局自分の理解に基づいて例を挙げることにしました。

  • reduce_sum()
tf.reduce_sum
matrix1 = [[1.,2.,3.],            #二维,元素为列表
          [4.,5.,6.]]
matrix2 = [[[1.,2.],[3.,4.]],      #三维,元素为矩阵
           [[5.,6.],[7.,8.]]]

res_2 = tf.reduce_sum(matrix1)
res_3 = tf.reduce_sum(matrix2)
res1_2 = tf.reduce_sum(matrix1,reduction_indices=[0])
res1_3 = tf.reduce_sum(matrix2,reduction_indices=[0])
res2_2 = tf.reduce_sum(matrix1,reduction_indices=[1])
res2_3 = tf.reduce_sum(matrix2,reduction_indices=[1])

sess = tf.Session()
print("reduction_indices=None:res_2={},res_3={}".format(sess.run(res_2),sess.run(res_3)))
print("reduction_indices=[0]:res1_2={},res1_3={}".format(sess.run(res1_2),sess.run(res1_3)))
print("reduction_indices=[1]:res2_2={},res2_3={}".format(sess.run(res2_2),sess.run(res2_3)))

結果は次のとおりです。

axis=None:res_2=21.0,res_3=36.0
axis=[0]:res1_2=[5. 7. 9.],res1_3=[[ 6.  8.]
                                    [10. 12.]]
axis=[1]:res2_2=[ 6. 15.],res2_3=[[ 4.  6.]
                                   [12. 14.]]
  • tf.reduce_mean は、
    上記のコードのreduce_sum 部分を renduce_mean に置き換えるだけです。
res_2 = tf.reduce_mean(matrix1)
res_3 = tf.reduce_mean(matrix2)
res1_2 = tf.reduce_mean(matrix1,axis=[0])
res1_3 = tf.reduce_mean(matrix2,axis=[0])
res2_2 = tf.reduce_mean(matrix1,axis=[1])
res2_3 = tf.reduce_mean(matrix2,axis=[1])

結果は次のとおりです。

axis=None:res_2=3.5,res_3=4.5
axis=[0]:res1_2=[2.5 3.5 4.5],res1_3=[[3. 4.]
                                       [5. 6.]]
axis=[1]:res2_2=[2. 5.],res2_3=[[2. 3.]
                                 [6. 7.]]

実際には、reduction_indices と axis が次元を表していることがわかります。None の場合、reduce_sum とreduce_mean はすべての要素に対して動作します。[0] の場合、実際には行単位で動作します。[1] の場合、列単位で動作ます。操作は、3 次元の場合、最も内側の括弧を数値として扱い、2 次元の場合に置き換えることができます。最終的な結果は、元の基準で 1 次元だけ削減されます。以下は専門的に説明されています。方法:

多次元配列の場合、最も外側の括弧内の要素の軸は 0 で、最後の要素が 1 つの数値になるまで、下の括弧ごとに軸が 1 ずつ増加します。

上の例のように、matrix1 = [[1., 2., 3.], [4., 5., 6.]]:

axis=0 の場合、含まれる要素は [1.、2.、3.]、[4.、5.、6.] です。 axis=1 の場合、含まれる要素は 1.、2.、3 .
、 4., 5., 6.
したがって、reduction_indices/axis=[0] の場合、axis=0 の要素を操作する必要があるため、reduce_sum() で得られる結果は [5. 7. 9.]、つまり2 配列の対応する要素を加算します。reduction_indices/axis=[1] の場合、演算は axis=1 の要素に対して実行される必要があるため、reduce_sum() によって得られる結果は [6. 15.] になります。各配列の要素が追加されます。同じことがreduce_mean()にも当てはまります。

同じ考え方が、matrix2 = [[[1,2],[3,4]], [[5,6],[7,8]] のような 3 次元の場合にも当てはまることを理解するのは難しくありません。 ] 上記の例では次のようになります。

axis=0 の場合、含まれる要素は次のとおりです: [[1., 2.],[3., 4.]], [[5., 6.],[7., 8.]] axis= 1 の場合
、含まれる要素は次のとおりです: [1., 2.]、[3., 4.]、[5., 6.]、[7., 8.] axis=2 の場合、含まれる要素は 1.、2 です
。 ., 3., 4., 5., 6., 7.,
8.duction_indices/axis=[0] の場合、reduce_sum() によって得られる結果は [[ 6. 8.], [10 . 12. ]]、つまり 2 つの行列の対応する位置要素を加算します。reduction_indices/axis=[1] の場合、reduce_sum() によって得られる結果は [[ 4. 6.], [12. 14.]]、つまり、配列の対応する要素を追加します。同じことがreduce_mean()にも当てはまります。

どの次元を操作しているのかを 1 文で説明すると、計算後に外側の括弧が削除されます。これは次元削減と同等です。

そこで問題は、reduction_indices/axis=[2] の場合に何が起こるかということです。? ?

  • 2 次元の場合は、最大軸が 1 であるため、当然エラーが報告されます。
ValueError: Invalid reduction dimension 2 for input with 2 dimensions. for 'Sum_4' (op: 'Sum') with input shapes: [2,3], [1] and with computed input tensors: input[1] = <2>.
  • 3 次元の場合、reduce_sum() によって得られる結果は [[ 3. 7.], [11. 15.]] になります。つまり、最も内側の括弧内の要素が合計されます。

-------------------------------------------------- - - - - - - - - - - -分割線 - - - - - - - - - - - - - - -------------------------------------------------- -----

元の質問に戻りますが、パラメータduction_indices=[1]が設定されている場合にのみ損失がNanではないのはなぜですか?

loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys -予測),reduction_indices=[1]))
このプログラムは 3 層のニューラル ネットワークを構築します。入力層には 1 つのニューロンと 100 の入力データのみがあります。サンプルpoint は (100,1) の形状を持つ列ベクトルです。隠れ層には 10 個のニューロンがあり、出力層にも 1 つのニューロンしかありません。したがって、最終的な出力データの形状も (100,1) の列ベクトルになります。 ). この場合、reduce_sum のパラメータは 2 次元配列になります。

  • duction_indices=[0]の場合、最終結果は要素を1つだけ含む配列、つまり[n]になります。
  • duction_indices=[1] の場合、最終結果は 100 個の要素を含む配列、つまり [n1,n2…n100] になります。
  • duction_indices=None の場合、最終結果は数値になります。

次に、reduce_mean() を使用して平均を計算すると、望ましい結果は sum/100 になります。このとき、望ましい効果を達成するには、reduce_sum() のみがパラメータ Reduce_indices=[1] を渡します。

完璧な解決策!

おすすめ

転載: blog.csdn.net/weixin_42149550/article/details/98759006