Python 为什么我的神经网络准确度这么低?

Python 为什么我的神经网络准确度这么低?,python,tensorflow,machine-learning,keras,neural-network,Python,Tensorflow,Machine Learning,Keras,Neural Network,我是机器学习新手,一直在学习神经网络。本周,我尝试用这个数据集编写一个神经网络 该数据集包含鲍鱼个体的详细信息,如它们的大小、性别等。我使用该数据集的目标是预测鲍鱼的年龄。这可以通过将鲍鱼的年轮乘以1.5来实现,因为数据集还揭示了一个年轮如何影响1.5岁左右的年龄。因此,我的目标是使用神经网络预测鲍鱼的环数。这样,我也会知道它的年龄 我决定有4层,其中隐藏层有300个节点,输出层有1个节点。这是我的密码: abalone_ds = pd.read_csv('abalone_ds.csv', he

我是机器学习新手,一直在学习神经网络。本周,我尝试用这个数据集编写一个神经网络

该数据集包含鲍鱼个体的详细信息,如它们的大小、性别等。我使用该数据集的目标是预测鲍鱼的年龄。这可以通过将鲍鱼的年轮乘以1.5来实现,因为数据集还揭示了一个年轮如何影响1.5岁左右的年龄。因此,我的目标是使用神经网络预测鲍鱼的环数。这样,我也会知道它的年龄

我决定有4层,其中隐藏层有300个节点,输出层有1个节点。这是我的密码:

abalone_ds = pd.read_csv('abalone_ds.csv', header=None, prefix='V')
abalone_ds.columns = ['Sex', 'Length', 'Diameter', 'Height',
                   'Whole weight', 'Shucked weight',
                   'Viscera weight', 'Shell weight', 'Rings']


def one_hot(ds, column_name):
    return pd.get_dummies(ds, columns=[column_name])

abalone_ds = one_hot(abalone_ds, "Sex")

y_ds = abalone_ds["Rings"]
x_ds = abalone_ds.drop(columns="Rings")

x_train, x_val, y_train, y_val = skl.train_test_split(x_ds, y_ds, test_size=0.2)

model = Sequential()
model.add(Dense(300, activation='relu', input_shape=(10,), name='Layer_2'))
model.add(Dense(300, activation='relu', name='Layer_3'))
model.add(Dense(300, activation='relu', name='Layer_4'))
model.add(Dense(1, activation='relu', name='Output'))
model.compile(loss='mean_absolute_error', optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=100, epochs=5, verbose=1)

test = model.evaluate(x_val, y_val, verbose=1)

print(test)
我首先标记了数据集的列,因为它们没有标记。然后,当我分析数据的时候,我意识到只有“性”是非数字的,所以我把它编码成一个热张量。然后,我将数据拆分(8:2比例)并将其插入网络。结果并不乐观

您可以看到,对于输出层,我的精度是0。此外,误差为1.57环,相当于2.355年。无论我对节点数或层数进行了多少实验/更改,该精度值都不会更改


我不知道为什么会发生这种情况。也许,我对神经网络输出的理解是错误的?例如,可能(1.57,0.0)并不代表环的数量和精度级别。也许这个数据集不适合神经网络(这意味着其他算法更适合)。如果有人知道为什么会发生这种情况,或者我如何通过解释来改进我当前的代码,我将非常感激。

我认为问题可能如下:根据您对问题的描述,您正在尝试执行回归任务,即预测鲍鱼的年龄。理论上,年龄可以是任何正实数。因此,此处使用的精度度量不适合任务,因为它用于分类任务,也就是说,当输出属于固定和离散的可能性集合之一时。因此,我建议使用不同的度量标准来测量模型结果,例如均方误差或平均绝对误差,它们适用于回归


另外,请注意,虽然度量(精度)的值为0,但损失函数随着每个历元而减少,这表明模型正在改进:)

要将其作为分类问题,您必须创建20个类。您的培训集现在需要为每个培训样本分配一个类别(年龄)。您的模型必须对样本所属的类别进行分类。模型中的最后一个密集层是

classification=Dense(20, activation= 'softmax')
model.compile(Adam, loss=sparse_categorial_crossentropy, metrics=['accuracy']

因为这实际上不是一个编码问题,所以这个问题可能更适合堆栈站点。谢谢你的建议;我将来一定会做的好的,我理解你的意思。所以我应该使用回归模型而不是分类。如果我将模型表示为一个分类,知道年龄必须在0到19之间,该怎么办。那么我该如何更改代码?您可以将其转换为类别0、1、。,19(必须是整数)通过对响应进行热编码,并使用
y\u onehot=tf.keras.utils.to\u category(y\u ds,num\u classes=20)
。这里的
y\u onehot
将是一个形状数组
(num\u示例,20)
。现在,您的模型的输出必须具有相同的形状,因此您应该将最后一层更改为
Dense(20,activation=“softmax”)
,并将损失函数更改为
category\u crossentropy
。我尝试使用{y\u onehot=tf.keras.utils.to\u category(y\ds,num\u classes=20)}对y\u ds进行一次热编码,但出现了以下错误:{索引22超出了大小为22}Hmmm的轴1的范围…听起来您的年龄超过了20岁。在这种情况下,您可以使用
y_ds_trunc=np.最小值(y_ds,20)截断20到20岁之间的所有年龄
然后在
y\u-ds\u-trunc
上调用
进行分类,或者您可以将
num\u-classes
参数设置为
max(y\ds)+1
以确保涵盖所有类。谢谢,我能够解决此问题。似乎最多有29个环,因此我更改了one_hot编码部分和输出层中的节点。我能够获得25%的准确率。您有提高此准确率的建议吗?我明白了。我还看到许多人使用“分类交叉熵”作为它们的损失函数。“稀疏分类交叉熵”和“分类交叉熵”有什么区别?此外,如果未定义类,我的程序如何知道要对哪些类进行分类?例如,如果我希望输出值介于整数值0和19年之间,程序如何知道不产生十进制值?我还尝试了上述代码。我得到了一个错误,说“稀疏\分类\交叉熵”不是一个已知的函数。所以我只使用“分类交叉熵”作为损失函数,但我仍然得到一个错误“形状(无,1)和(无,20)不兼容”