Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.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_Tensorflow_Machine Learning_Neural Network_Keras - Fatal编程技术网

Python 用Keras建立的回归神经网络只能预测一个值

Python 用Keras建立的回归神经网络只能预测一个值,python,tensorflow,machine-learning,neural-network,keras,Python,Tensorflow,Machine Learning,Neural Network,Keras,我正试图用Keras和Tensorflow建立一个神经网络来预测歌曲的最终图表位置,给出了一组5个特征 在玩了几天之后,我意识到尽管我的MAE越来越低,这是因为模型刚刚学会预测所有输入的训练集的平均值,这是最佳解决方案。(如下面的散点图所示) 这是从我的测试集中随机抽取的50个数据点,与网络认为的数据点相比 起初我意识到这可能是因为我的网络太复杂了。我有一个带有shape(5,)的输入层和输出层中的一个节点,但是有3个隐藏层,每个层有超过32个节点 然后,我剥离了多余的层,并移动到只有一个隐藏

我正试图用Keras和Tensorflow建立一个神经网络来预测歌曲的最终图表位置,给出了一组5个特征

在玩了几天之后,我意识到尽管我的MAE越来越低,这是因为模型刚刚学会预测所有输入的训练集的平均值,这是最佳解决方案。(如下面的散点图所示)

这是从我的测试集中随机抽取的50个数据点,与网络认为的数据点相比

起初我意识到这可能是因为我的网络太复杂了。我有一个带有shape
(5,)
的输入层和输出层中的一个节点,但是有3个隐藏层,每个层有超过32个节点

然后,我剥离了多余的层,并移动到只有一个隐藏层和一对节点,如下所示:

self.model = keras.Sequential([
keras.layers.Dense(4,
    activation='relu',
    input_dim=num_features,
    kernel_initializer='random_uniform',
    bias_initializer='random_uniform'
    ),
keras.layers.Dense(1)
])
使用梯度下降优化程序进行训练,仍然会在整个过程中产生完全相同的预测结果

然后我突然想到,也许我试图解决的实际问题对于网络来说还不够难,也许它是线性可分的。因为这对根本没有隐藏层会有更好的响应,基本上就是做常规线性回归,所以我尝试了。我将模型更改为:

inp = keras.Input(shape=(num_features,))
out = keras.layers.Dense(1, activation='relu')(inp)
self.model = keras.Model(inp,out)
这也没有改变什么。我的MAE,预测值都是一样的。 我尝试过很多不同的东西,优化功能、学习速度、网络配置的不同排列,但没有什么能帮上忙。我很确定数据是好的,但我已经包括了一个样本以防万一

chartposition,tagcount,dow,artistscore,timeinchart,finalpos
121,3925,5,35128,7,227
131,4453,3,85545,25,130
69,2583,4,17594,24,523
145,1165,3,292874,151,187
96,1679,5,102593,111,540
134,3494,5,1252058,37,370
6,34895,7,6824048,22,5
作为我数据集的一个样本,finalpos是我试图预测的值。数据集包含约40000条记录,分为80/20条-培训/测试

与网络建设和培训相关的所有规范

输入数据的标准化。我的测试和训练数据均标准化为测试集的最大值和最小值

带有adamoptimiser的单隐层网络的损失与验证曲线图,学习率0.01

相同的图形,但具有线性回归和梯度下降优化


因此,我非常确定您的规范化是一个问题:您不是按特性(如反事实行业标准)进行规范化,而是跨所有数据进行规范化。 这意味着,如果您有两个不同的功能,它们的数量级/范围非常不同(在您的案例中,将
timeinchart
artistscore
进行比较)

相反,您可能希望使用类似scikit learn的东西进行规范化。这不仅可以规范化每列(这样您就可以一次传递所有特性),还可以规范化单位方差(这是关于数据的一些假设,但也可能有帮助)

要转换数据,请使用以下内容

from sklearn.preprocessing import StandardScaler
import numpy as np

raw_data = np.array([[1,40], [2, 80]])
scaler = StandardScaler()
processed_data = scaler.fit_transform(raw_data) 
# fit() calculates mean etc, transform() puts it to the new range.
print(processed_data) # returns [[-1, -1], [1,1]]
请注意,有两种方法可以规范化/标准化培训数据: 或者将它们与训练数据一起缩放,然后拆分, 或者只拟合训练数据,然后使用相同的定标器转换测试数据。
永远不要将测试集与训练数据分开进行变换!
由于平均值/最小值/最大值可能不同,因此最终可能会得出完全错误的预测!从某种意义上说,StandardScaler是您对“数据源分布”的定义,对于您的测试集,它本质上仍然是相同的,尽管它们可能是不完全遵循相同属性的子集(由于样本量小等原因)


此外,您可能希望使用更高级的,如Adam,或者为SGD指定一些动量属性(根据经验法则,0.9在实践中是一个不错的选择)。

事实证明,该错误是一个非常愚蠢且容易忽略的错误

当我导入我的数据集时,我将其洗牌,但是当我执行洗牌时,我意外地将洗牌仅应用于标签集,而不是整个数据集

结果,每个标签都被分配到一个完全随机的特征集,当然模型不知道该怎么做


感谢@Denninger建议我去寻找最终发现这个bug的地方。

你是否正在规范化你的输入数据?培训损失/验证损失曲线是什么样子?@Denninger我已经用这些细节编辑了原始帖子。谢谢!现在就实施,并会让你知道结果。我是ri吗我认为我不应该规范我的“标签”栏
finalpos
?只是功能?哦,完全忘了提到这一点。当然,你是对的!
def normalise_dataset(df, mini, maxi):
    return (df - mini)/(maxi-mini)
from sklearn.preprocessing import StandardScaler
import numpy as np

raw_data = np.array([[1,40], [2, 80]])
scaler = StandardScaler()
processed_data = scaler.fit_transform(raw_data) 
# fit() calculates mean etc, transform() puts it to the new range.
print(processed_data) # returns [[-1, -1], [1,1]]