В руководстве для начинающих 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
(по умолчанию), уменьшает все размеры.
# '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.]
Для одномерного вектора это выглядит так np.mean == tf.reduce_mean
, но я не понимаю, что в нем происходит tf.reduce_mean(x, 1) ==> [1., 2.]
. tf.reduce_mean(x, 0) ==> [1.5, 1.5]
вроде имеет смысл, так как mean of [1, 2]
and [1, 2]
is [1.5, 1.5]
, но что с этим происходит tf.reduce_mean(x, 1)
?
tf.reduce_mean
многопоточность, обычно вычисляется на вашем графическом процессоре, тогдаnp.mean
как вычисляется на одном процессоре. Кроме того,tf
он предназначен для обработки пакета данных, в то время какnp
работает с одним экземпляром данных.Ответы:
Функциональные возможности
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. Но чтобы выполнить операцию тензорного потока, она должна выполняться внутри тензорного потока
Session
. Вы можете прочитать об этом здесь . Поэтому, когда вам нужно выполнить какие-либо вычисления для вашего графа тензорного потока (или структуры, если хотите), это должно быть сделано внутри тензорного потокаSession
.Давайте посмотрим на другой пример.
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
in,numpy
как это было бы естественно, но для того, чтобы сделать это в тензорном потоке, вам нужно выполнить это внутриSession
, без использованияSession
вы не можете этого сделать. Другими словами, когда вы вычисляетеtfMean = tf.reduce_mean(c)
, тензорный поток не вычисляет его. Он только вычисляет это в файлеSession
. Но numpy вычисляет это мгновенно, когда вы пишетеnp.mean()
.Надеюсь, это имеет смысл.
источник
Ключевым моментом здесь является слово «сокращение», концепция из функционального программирования, которая позволяет
reduce_mean
в TensorFlow сохранять текущее среднее результатов вычислений из пакета входных данных.Если вы не знакомы с функциональным программированием, это может показаться загадочным. Итак, сначала давайте посмотрим, что
reduce
делает. Если вам дали список вроде [1,2,5,4] и попросили вычислить среднее значение, это легко - просто передайте весь массив в,np.mean
и вы получите среднее значение. Однако что, если бы вам пришлось вычислить среднее значение потока чисел? В этом случае вам нужно сначала собрать массив, прочитав из потока, а затем вызватьnp.mean
полученный массив - вам придется написать еще код.Альтернативой является использование парадигмы сокращения. В качестве примера рассмотрим, как мы можем использовать сократить в питона , чтобы вычислить сумму чисел:
reduce(lambda x,y: x+y, [1,2,5,4])
.Это работает так:
Подробнее здесь Функциональное программирование на 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))
источник
В новой документации указано, что
tf.reduce_mean()
дает те же результаты, что и np.mean:Также он имеет абсолютно те же параметры, что и np.mean . Но вот важное отличие: они дают одинаковые результаты только для значений с плавающей запятой :
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
производят одни и те же значения, что и там Numpy аналогов. Очевидно, поскольку это операции, они могут выполняться только изнутри сеанса.источник
tf.reduce_mean
что результатdtype
соответствует вводуdtype
. Результатnp.mean()
всегда является плавающим. Это правильно?1
обычно относится к строкам и2
обычно относится к столбцам. Уменьшение индекса «сверх»1
означает уменьшение по строкам.[1., 2.]
просто[ <row 1 mean> , <row 2 mean> ]
.Это соглашение о нумерации индексов типично для программного обеспечения статистики, особенно R.
источник