np.mean และ tf.reduce_mean ต่างกันอย่างไร


92

ในบทช่วยสอนสำหรับผู้เริ่มต้น MNISTมีคำสั่ง

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

tf.castโดยทั่วไปจะเปลี่ยนประเภทของเทนเซอร์ที่วัตถุคือ แต่อะไรคือความแตกต่างระหว่างtf.reduce_meanและnp.mean?

นี่คือเอกสารเกี่ยวกับtf.reduce_mean:

reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)

input_tensor: เทนเซอร์ที่จะลด ควรมีประเภทตัวเลข

reduction_indices: ขนาดที่จะลด ถ้าNone(defaut) ลดขนาดทั้งหมด

# 'x' is [[1., 1. ]]
#         [2., 2.]]
tf.reduce_mean(x) ==> 1.5
tf.reduce_mean(x, 0) ==> [1.5, 1.5]
tf.reduce_mean(x, 1) ==> [1.,  2.]

สำหรับเวกเตอร์ 1D ดูเหมือนว่าแต่ผมไม่เข้าใจสิ่งที่เกิดขึ้นในnp.mean == tf.reduce_mean เป็นเรื่องที่สมเหตุสมผลเนื่องจากมีค่าเฉลี่ยและเป็นแต่เกิดอะไรขึ้นกับ?tf.reduce_mean(x, 1) ==> [1., 2.]tf.reduce_mean(x, 0) ==> [1.5, 1.5][1, 2][1, 2][1.5, 1.5]tf.reduce_mean(x, 1)


พวกเขาให้ผลลัพธ์ที่แตกต่างกันสำหรับค่าจำนวนเต็มเนื่องจากการหารใน python
Salvador Dali

ความแตกต่างที่สำคัญอย่างหนึ่งสำหรับผู้ที่เพิ่งเริ่มใช้เทนเซอร์โฟลว์: tf.reduce_meanเป็นแบบมัลติเธรดซึ่งโดยทั่วไปจะคำนวณจาก GPU ของคุณในขณะที่np.meanคำนวณจาก CPU ตัวเดียว นอกจากนี้ยังtfออกแบบมาเพื่อประมวลผลชุดข้อมูลในขณะที่npทำหน้าที่ในอินสแตนซ์ข้อมูลเดียว
drevicko

คำตอบ:


114

การทำงานของnumpy.meanและtensorflow.reduce_meanเหมือนกัน พวกเขาทำในสิ่งเดียวกัน. จากเอกสารสำหรับnumpyและtensorflowคุณจะเห็นสิ่งนั้น มาดูตัวอย่างกัน

c = np.array([[3.,4], [5.,6], [6.,7]])
print(np.mean(c,1))

Mean = tf.reduce_mean(c,1)
with tf.Session() as sess:
    result = sess.run(Mean)
    print(result)

เอาต์พุต

[ 3.5  5.5  6.5]
[ 3.5  5.5  6.5]

ที่นี่คุณจะเห็นได้ว่าเมื่อaxis(numpy) หรือreduction_indices(tensorflow) เป็น 1 จะคำนวณค่าเฉลี่ยระหว่าง (3,4) และ (5,6) และ (6,7) ดังนั้นจึง1กำหนดว่าจะคำนวณค่าเฉลี่ยของแกนใด เมื่อเป็น 0 ค่าเฉลี่ยจะถูกคำนวณด้วย (3,5,6) และ (4,6,7) และอื่น ๆ ฉันหวังว่าคุณจะได้รับความคิด

ตอนนี้อะไรคือความแตกต่างระหว่างพวกเขา?

คุณสามารถคำนวณการดำเนินการ numpy ที่ใดก็ได้บน python แต่เพื่อที่จะดำเนินการ tensorflow ก็จะต้องทำภายใน Sessiontensorflow คุณสามารถอ่านเพิ่มเติมได้ที่นี่ ดังนั้นเมื่อคุณจำเป็นต้องดำเนินการใด ๆ สำหรับการคำนวณกราฟ tensorflow ของคุณ (หรือโครงสร้างถ้าคุณจะ) มันจะต้องทำภายใน Sessiontensorflow

มาดูตัวอย่างอื่นกันดีกว่า

npMean = np.mean(c)
print(npMean+1)

tfMean = tf.reduce_mean(c)
Add = tfMean + 1
with tf.Session() as sess:
    result = sess.run(Add)
    print(result)

เราสามารถเพิ่มค่าเฉลี่ยโดย1ในnumpyตามที่คุณต้องการตามธรรมชาติ แต่ในการที่จะทำมันใน tensorflow คุณจำเป็นต้องดำเนินการว่าในSessionโดยไม่ต้องใช้Sessionคุณไม่สามารถทำเช่นนั้นได้ กล่าวอีกนัยหนึ่งคือเมื่อคุณกำลังคำนวณtfMean = tf.reduce_mean(c)เทนเซอร์โฟลว์จะไม่คำนวณมัน คำนวณเฉพาะในไฟล์Session. แต่คำนวณ numpy np.mean()ว่าทันทีเมื่อคุณเขียน

ฉันหวังว่ามันจะสมเหตุสมผล


23
แต่สิ่งที่ไม่ลดส่วนหนึ่งหมายถึงที่นี่?
rsht

22
@ โรมันเป็นคำศัพท์จากการเขียนโปรแกรมเชิงฟังก์ชัน คุณสามารถอ่านได้ที่นี่: python-course.eu/lambda.php
Daniyar

1
@rsht REDUCE = ลดจำนวนโดยรวมได้สูงสุด 1 ค่า MEAN = การหาค่าเฉลี่ยของผลรวมนั้น
Meghna Natraj

1
@rsht สมมติว่าคุณมีองค์ประกอบ N และคุณต้องการคำนวณค่าเฉลี่ย (M) ของตัวเลข N เหล่านั้น วิธีดูปัญหานี้คือเรามีเวกเตอร์ขนาด (1, N) และเหนือแกน = 0 เราจะลดองค์ประกอบ (ที่นี่เรามีองค์ประกอบ N) การลด (หรือการรวม) มาพร้อมกับฟังก์ชันและในตัวอย่างของเราฟังก์ชันคือฟังก์ชันค่าเฉลี่ย
เปลี่ยน

23

กุญแจสำคัญในที่นี้คือคำว่าลดซึ่งเป็นแนวคิดจากการเขียนโปรแกรมเชิงฟังก์ชันซึ่งทำให้reduce_meanใน TensorFlow สามารถเก็บค่าเฉลี่ยของผลลัพธ์ของการคำนวณจากชุดอินพุตได้

หากคุณไม่คุ้นเคยกับการเขียนโปรแกรมเชิงฟังก์ชันสิ่งนี้อาจดูลึกลับ ก่อนอื่นให้เราดูว่ามีอะไรreduceบ้าง หากคุณได้รับรายการเช่น [1,2,5,4] และได้รับคำสั่งให้คำนวณค่าเฉลี่ยนั่นเป็นเรื่องง่ายเพียงแค่ส่งอาร์เรย์ทั้งหมดไปก็จะnp.meanได้ค่าเฉลี่ย อย่างไรก็ตามถ้าคุณต้องคำนวณค่าเฉลี่ยของกระแสตัวเลขล่ะ? ในกรณีนี้คุณจะต้องรวบรวมอาร์เรย์ก่อนโดยการอ่านจากสตรีมจากนั้นเรียกnp.meanใช้อาร์เรย์ที่เป็นผลลัพธ์ - คุณจะต้องเขียนโค้ดเพิ่มเติม

อีกทางเลือกหนึ่งคือการใช้กระบวนทัศน์ลด reduce(lambda x,y: x+y, [1,2,5,4])เป็นตัวอย่างให้ดูที่วิธีการที่เราสามารถใช้ลดในหลามในการคำนวณผลรวมของตัวเลขที่:

การทำงานเช่นนี้:

  1. ขั้นตอนที่ 1: อ่านตัวเลข 2 หลักจากรายการ - 1,2 ประเมินแลมด้า 1,2. ลดการจัดเก็บผลลัพธ์ 3 หมายเหตุ - นี่เป็นขั้นตอนเดียวที่มีการอ่านตัวเลข 2 หลักจากรายการ
  2. ขั้นตอนที่ 2: อ่านตัวเลขถัดไปจากรายการ - 5. ประเมินแลมด้า 5, 3 (3 เป็นผลลัพธ์จากขั้นตอนที่ 1 ซึ่งลดการจัดเก็บ) ลดร้านค้าผลลัพธ์ 8.
  3. ขั้นตอนที่ 3: อ่านตัวเลขถัดไปจากรายการ - 4. ประเมินแลมด้า 8,4 (8 เป็นผลลัพธ์ของขั้นตอนที่ 2 ซึ่งลดการจัดเก็บ) ลดผลการจัดเก็บ 12
  4. ขั้นตอนที่ 4: อ่านตัวเลขถัดไปจากรายการ - ไม่มีเลยดังนั้นให้ส่งคืนผลลัพธ์ที่เก็บไว้เป็น 12

อ่านเพิ่มเติมได้ที่นี่Functional Programming ใน Python

หากต้องการดูว่าสิ่งนี้นำไปใช้กับ TensorFlow อย่างไรให้ดูที่บล็อกของโค้ดต่อไปนี้ซึ่งกำหนดกราฟอย่างง่ายซึ่งใช้เวลาในการลอยตัวและคำนวณค่าเฉลี่ย อย่างไรก็ตามอินพุตของกราฟไม่ใช่โฟลทเดี่ยว แต่เป็นอาร์เรย์ของโฟลต reduce_meanคำนวณค่าเฉลี่ยมากกว่าลอยทุกคน

import tensorflow as tf


inp = tf.placeholder(tf.float32)
mean = tf.reduce_mean(inp)

x = [1,2,3,4,5]

with tf.Session() as sess:
    print(mean.eval(feed_dict={inp : x}))

รูปแบบนี้มีประโยชน์เมื่อคำนวณค่าในชุดภาพ ดูตัวอย่าง Deep MNISTที่คุณเห็นรหัสเช่น:

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

4

เอกสารใหม่ระบุว่าtf.reduce_mean()ให้ผลลัพธ์เช่นเดียวกับ np.mean:

เทียบเท่ากับ np.mean

นอกจากนี้ยังมีอย่างพารามิเตอร์เดียวกับnp.mean แต่นี่คือความแตกต่างที่สำคัญ: พวกมันให้ผลลัพธ์เดียวกันกับค่า float เท่านั้น :

import tensorflow as tf
import numpy as np
from random import randint

num_dims = 10
rand_dim = randint(0, num_dims - 1)
c = np.random.randint(50, size=tuple([5] * num_dims)).astype(float)

with tf.Session() as sess:
    r1 = sess.run(tf.reduce_mean(c, rand_dim))
    r2 = np.mean(c, rand_dim)
    is_equal = np.array_equal(r1, r2)
    print is_equal
    if not is_equal:
        print r1
        print r2

หากคุณจะลบการแปลงประเภทคุณจะเห็นผลลัพธ์ที่แตกต่างกัน


นอกจากนี้อีกหลายคนที่tf.reduce_ฟังก์ชั่นเช่นreduce_all, reduce_any, reduce_min, reduce_max, reduce_prodผลิตค่าเดียวกันที่มี analogs numpy เห็นได้ชัดว่าเนื่องจากเป็นการดำเนินการจึงสามารถดำเนินการได้จากภายในเซสชันเท่านั้น


อาจเป็นประโยชน์หากคุณอธิบายความแตกต่างนอกเหนือจากตัวอย่าง จากการทำงานตัวอย่างของคุณผมมีความรู้สึกว่าtf.reduce_meanมั่นใจว่าการส่งออกตรงกับการป้อนข้อมูลdtype dtypeผลลัพธ์ของnp.mean()เสมอลอย ถูกต้องหรือไม่
craq

-1

1มักจะหมายถึงแถวและ2มักจะหมายถึงคอลัมน์ การลดดัชนี "มากกว่า" 1หมายถึงการลด rowwise

[1., 2.][ <row 1 mean> , <row 2 mean> ]เป็นเพียง

หลักการกำหนดเลขดัชนีนี้เป็นเรื่องปกติในซอฟต์แวร์สถิติโดยเฉพาะ R


1
ฉันเชื่อว่า 0 หมายถึงคอลัมน์ไม่ใช่ 2
hfz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.