Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 度量的定义是什么';keras历史对象中包含的值?_Python_Keras - Fatal编程技术网

Python 度量的定义是什么';keras历史对象中包含的值?

Python 度量的定义是什么';keras历史对象中包含的值?,python,keras,Python,Keras,文档说明将返回一个历史对象,该对象包含培训期间评估的各种指标。在培训期间,这些指标也会打印到标准输出(例如,请参见) 文档说明历史对象是 连续时期的培训损失值和度量值记录,[…] 现在我想知道这些指标是作为每个样本的平均值还是作为每个批次的平均值给出的?假设我有model.fit(x,y,batch\u size=16,…)。量度是否在批次内累积并平均(即,一个值将对应于批次中16个样本的组合值)?或者它们是按样本给出的(即整个数据集的平均值) 编辑 显然,度量不是按样本计算的,而是按输出计算的

文档说明将返回一个
历史
对象,该对象包含培训期间评估的各种指标。在培训期间,这些指标也会打印到标准输出(例如,请参见)

文档说明历史对象是

连续时期的培训损失值和度量值记录,[…]

现在我想知道这些指标是作为每个样本的平均值还是作为每个批次的平均值给出的?假设我有
model.fit(x,y,batch\u size=16,…)
。量度是否在批次内累积并平均(即,一个值将对应于批次中16个样本的组合值)?或者它们是按样本给出的(即整个数据集的平均值)

编辑 显然,度量不是按样本计算的,而是按输出计算的。这在以下文件中有粗略的说明:;也就是说,如果为每个输出节点指定不同的损耗,那么总损耗将最小化。这表明了两件事:首先,损失(指标)不是按样本计算的,而是按输出计算的(尽管在批内和批上平均)。如果每个输出的损失(指标)在各个输出上取平均值,则此过程类似于每个样本的计算。然而,第二,文件表明,不同产出的损失之和不是平均值。所以这需要更多的调查

深入研究源代码可以发现这一点。如果我们没有为各种输出手动指定任何权重。然后是相关的损失计算部分。损失和没有平均值似乎被采取。好的,我们应该从一个快速的实验中看到:

from keras.initializers import Ones, Zeros
from keras.models import Sequential
from keras.layers import Dense
import numpy as np

x = np.arange(16).reshape(8, 2).astype(float)
y = np.zeros((8, 2), dtype=float)

model = Sequential()
model.add(Dense(2, input_dim=2, kernel_initializer=Ones(), bias_initializer=Zeros(), trainable=False))
model.compile('sgd', loss='mean_absolute_error', metrics=['mean_absolute_error', 'mean_squared_error'])

# Metrics per sample and output.
ae = np.abs(np.sum(x, axis=1)[:, None] - y)  # Absolute error.
se = (np.sum(x, axis=1)[:, None] - y)**2  # Squared error.
print('Expected metrics for averaging over samples but summing over outputs:')
print(f'\tMAE: {np.sum(np.mean(ae, axis=0))}, MSE: {np.sum(np.mean(se, axis=0))}', end='\n\n')
print('Expected metrics for averaging over samples and averaging over outputs:')
print(f'\tMAE: {np.mean(np.mean(ae, axis=0))}, MSE: {np.mean(np.mean(se, axis=0))}')

for batch_size in [1, 2, 4, 8]:
    print(f'\n# Batch size: {batch_size}')
    model.fit(x, y, batch_size=batch_size, epochs=1, shuffle=False)
将生成以下输出:

Expected metrics for averaging over samples but summing over outputs:
    MAE: 30.0, MSE: 618.0

Expected metrics for averaging over samples and averaging over outputs:
    MAE: 15.0, MSE: 309.0

# Batch size: 1
Epoch 1/1
8/8 [==============================] - 0s 4ms/step - loss: 15.0000 - mean_absolute_error: 15.0000 - mean_squared_error: 309.0000

# Batch size: 2
Epoch 1/1
8/8 [==============================] - 0s 252us/step - loss: 15.0000 - mean_absolute_error: 15.0000 - mean_squared_error: 309.0000

# Batch size: 4
Epoch 1/1
8/8 [==============================] - 0s 117us/step - loss: 15.0000 - mean_absolute_error: 15.0000 - mean_squared_error: 309.0000

# Batch size: 8
Epoch 1/1
8/8 [==============================] - 0s 60us/step - loss: 15.0000 - mean_absolute_error: 15.0000 - mean_squared_error: 309.0000

奇怪的是,报告的度量值似乎是输出的平均值,而文档和源代码表明它们将被求和。如果有人能澄清这里发生了什么,我会很高兴。

为了简化这个问题,让我们定义一个“模型”,按原样返回输入

from keras.layers import Input
from keras.models import Model

inp = Input((2,))
model = Model(inputs=inp, outputs=inp)
model.summary()

#__________________________________________________________________
Layer (type)                 Output Shape              Param #   
#=================================================================
#input_3 (InputLayer)         (None, 2)                 0         
#=================================================================
#Total params: 0
#Trainable params: 0
#Non-trainable params: 0
#__________________________________________________________________
虽然没有要训练的参数,但让我们训练模型,看看keras如何计算度量

import numpy as np
x = np.arange(16).reshape(8, 2).astype(float)
y = np.zeros((8, 2), dtype=float)

model.compile(optimizer="adam", loss="mse", metrics=["mae"])

for bs in [1, 2, 3, 8]:
    print("Training with batch size", bs)
    model.fit(x, y, epochs=1, batch_size=bs)
    print("")
我得到:

Training with batch size 1
Epoch 1/1
8/8 [=============] - 0s 10ms/step - loss: 77.5000 - mean_absolute_error: 7.5000

Training with batch size 2
Epoch 1/1
8/8 [=============] - 0s 1ms/step - loss: 77.5000 - mean_absolute_error: 7.5000

Training with batch size 3
Epoch 1/1
8/8 [=============] - 0s 806us/step - loss: 77.5000 - mean_absolute_error: 7.5000

Training with batch size 8
Epoch 1/1
8/8 [=============] - 0s 154us/step - loss: 77.5000 - mean_absolute_error: 7.5000
因此,
MSE(损失)=77.5
MAE=7.5
,与批量大小无关

要复制结果,我们可以:

np.mean((x - y) ** 2)
# 77.5
np.mean(np.abs(x - y))
# 7.5
现在,关于keras文档中的“加权和”语句,这是一个输出列表,而不是多列输出

这个模型与上面的完全相同,只是输出被分成两部分

培训结果如下

model.compile(optimizer="adam", loss="mse", metrics=["mae"])
for bs in [1, 2, 3, 8]:
    print("Training with batch size", bs)
    model.fit(x, [y[:, 0:1], y[:, 1:2]], epochs=1, batch_size=bs)
    print("")

#Training with batch size 1
#Epoch 1/1
#8/8 [==============================] - 0s 15ms/step - loss: 155.0000 -
#Y1_loss: 70.0000 - Y2_loss: 85.0000 - Y1_mean_absolute_error: 7.0000 -
#Y2_mean_absolute_error: 8.0000
# 
#same for all batch sizes
Keras现在分别计算每个输出的损失,然后取它们的总和。 我们可以通过以下方式复制结果:

np.mean(np.sum((x - y) ** 2, axis=-1))
# 155.0
np.mean(np.sum(np.abs(x - y), axis=-1))
# 15.0 (= 7.0 + 8.0)

我不清楚两者之间的区别。你是在问度量值是按“最后一个小批量的平均值”还是“历元的平均值”计算的吗?我的问题是度量值以何种方式表示数据。例如,我可以想象以下方案。度量的计算可以通过求和或平均来完成。然后可以在小批量或完整数据集上完成。在小批量中,可以求和或求平均值。我想知道我的数据集的哪一部分是以何种方式由作为历史一部分呈现的度量值表示的。此外,如果这因不同指标而异;例如,准确度显然是指一组样本,而MSE可以计算每个样本。这是非常复杂的。我建议你举个小例子。假设一个时代有两个批次。第一批有三个样品,损失为
[1,2,3]
,第二批有四个样品,损失为
[4,5,6,7]
。你的不同方案是如何计算历元损失的?@KotaMori我发现损失显然不是按样本计算的,而是按输出(节点)计算的。现在剩下的问题是这些不同的损失是如何组合的(它们是总和还是平均值)?文档表明它们是汇总的,检查源代码也表明了这种行为。然而,当我通过运行一个测试片段进行交叉检查时,结果似乎正好相反,即取平均值。请看我更新的问题。你知道发生了什么吗?所以最后结果是损失是。多输出模式现在也很清楚了。非常感谢。
np.mean(np.sum((x - y) ** 2, axis=-1))
# 155.0
np.mean(np.sum(np.abs(x - y), axis=-1))
# 15.0 (= 7.0 + 8.0)