Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.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 如何训练神经网络将整数转换成罗马数?_Python_Tensorflow_Machine Learning_Keras_Neural Network - Fatal编程技术网

Python 如何训练神经网络将整数转换成罗马数?

Python 如何训练神经网络将整数转换成罗马数?,python,tensorflow,machine-learning,keras,neural-network,Python,Tensorflow,Machine Learning,Keras,Neural Network,我试图训练一个神经网络将整数转换成罗马数字,但我的损失不会低于0.3。你能帮我找出我做错了什么吗 对于输入,我使用从0到4000的整数。我试过使用它们1。)原样,2。)标准化为z值,3。)最小最大缩放 对于输出y,我有21个二进制类。它们看起来像这样: {'MMM': 0, 'MM': 0, 'CM': 0, 'M': 0, 'CD': 0, 'D': 0, 'CCC': 0, 'CC': 0, 'XC': 0, 'C': 0, 'XL': 0, 'L': 0, 'XXX': 0, 'XX':

我试图训练一个神经网络将整数转换成罗马数字,但我的损失不会低于0.3。你能帮我找出我做错了什么吗

对于输入,我使用从0到4000的整数。我试过使用它们1。)原样,2。)标准化为z值,3。)最小最大缩放

对于输出y,我有21个二进制类。它们看起来像这样:

{'MMM': 0, 'MM': 0, 'CM': 0, 'M': 0, 'CD': 0, 'D': 0, 'CCC': 0, 'CC': 0, 'XC': 0, 'C': 0, 'XL': 0, 'L': 0, 'XXX': 0, 'XX': 0, 'IX': 0, 'X': 0, 'IV': 0, 'V': 0, 'III': 0, 'II': 0, 'I': 0}
model = tf.keras.models.Sequential()
model.add(Dense(56, input_shape=(1,), activation='relu'))
model.add(Dense(56, activation='relu'))
model.add(Dense(48, activation='relu'))
model.add(Dense(21))
这个模板允许我明确地表示1到3999之间的任何整数。 例如

17成为:

{'MMM': 0, 'MM': 0, 'CM': 0, 'M': 0, 'CD': 0, 'D': 0, 'CCC': 0, 'CC': 0, 'XC': 0, 'C': 0, 'XL': 0, 'L': 0, 'XXX': 0, 'XX': 0, 'IX': 0, 'X': 1, 'IV': 0, 'V': 1, 'III': 0, 'II': 1, 'I': 0}
3885变成:

{'MMM': 1, 'MM': 0, 'CM': 0, 'M': 0, 'CD': 0, 'D': 1, 'CCC': 1, 'CC': 0, 'XC': 0, 'C': 0, 'XL': 0, 'L': 1, 'XXX': 1, 'XX': 0, 'IX': 0, 'X': 0, 'IV': 0, 'V': 1, 'III': 0, 'II': 0, 'I': 0}
我的模型如下所示:

{'MMM': 0, 'MM': 0, 'CM': 0, 'M': 0, 'CD': 0, 'D': 0, 'CCC': 0, 'CC': 0, 'XC': 0, 'C': 0, 'XL': 0, 'L': 0, 'XXX': 0, 'XX': 0, 'IX': 0, 'X': 0, 'IV': 0, 'V': 0, 'III': 0, 'II': 0, 'I': 0}
model = tf.keras.models.Sequential()
model.add(Dense(56, input_shape=(1,), activation='relu'))
model.add(Dense(56, activation='relu'))
model.add(Dense(48, activation='relu'))
model.add(Dense(21))
我还尝试了
elu
激活功能,并尝试了稍大和稍小数量的神经元。我还尝试了再增加两层

我试过学习率在0.1到0.001之间

opt = Adam(learning_rate=0.1)
对于损失函数,我使用二进制交叉熵

loss = tf.keras.losses.BinaryCrossentropy(from_logits=True)
model.compile(optimizer=opt, loss=loss)
我还尝试将
sigmoid
from\u logits=False

似乎什么都不管用。损失不低于0.3

我已经培训了多达5000个时代,批量从500到2000不等

h = model.fit(scaled_x, y, batch_size=512, epochs=400, verbose=1, shuffle=True)
完整的Google协作工作簿位于此处:

你认为损失没有超过0.3的原因是什么?
您建议我下一步尝试什么?

我会在不登录的情况下添加您的乙状结肠激活

您还应该使用某种精度,因为损失本身并不能告诉您除原始进度之外的其他情况。Keras可以为您自动推断:

model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])
<>我也会考虑创建一个验证集来运行,这样您就可以看到模型如何对未见过的数据执行。如果这意味着训练集“过度学习”模式(过度拟合),那么试图提高训练集的准确性是没有意义的,因为这将导致训练集在以前从未见过的数据上表现更差:

h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True)
请注意,作为度量传入的任何内容实际上都不会影响模型的学习方式,它只是用于可读的输出。损失函数影响模型判断性能的方式,进而影响权重更新步骤的范围。所以也许考虑使用不同的损失函数:

!pip install tensorflow_addons

import tensorflow_addons as tfa

loss = tfa.losses.SigmoidFocalCrossEntropy()
h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True, callbacks=[reduce_lr])
我以前在处理像这样的多标签问题时,使用上述损失函数得到了很好的结果

另一个想法是引入学习率调度器,在
监视器未发生变化的特定时期后,该调度器会自动降低学习率:

reduce_lr = ReduceLROnPlateau(monitor='val_acc',min_delta=0.005 ,patience=2, factor=0.1, verbose=1, mode='max')
因此,我们正在监控验证准确性,但您可以指定“val_损失”、“损失”等

我们正在等待2个时期,如果val_acc没有增加0.5%(注意mode='max',所以它正在检查是否增加了),那么学习率将下降10%(
factor=0.1

然后将其作为回调传递到fit函数中:

!pip install tensorflow_addons

import tensorflow_addons as tfa

loss = tfa.losses.SigmoidFocalCrossEntropy()
h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True, callbacks=[reduce_lr])
更新

你完全正确地认为准确性是错误的。对于多标签分类,我通常使用top_k_categorical_准确性,因此当k=5时(由一些google paper iirc推荐),如果真实标签出现在前5个预测中,则认为模型是正确的。但请记住,这实际上不会影响模型的学习方式,它只会改变您自己对模型是否需要调整的解释

要使用它,请将其添加到
编译
中的
度量
参数中:

metrics=[tf.keras.metrics.TopKCategoricalAccuracy(k=5)]
PS我用建议的更改运行了您的代码,在某一点上它确实上升到93%,但是这没有意义,您必须使用一些验证数据来查看模型在未看到的数据上的表现,因为这是创建模型的第一步。它可以在训练集上完成93%,但在验证集上完成85%


一旦你做了所有这些,到了想哭的地步,我建议你去看看,特别是一个叫做“扫描”的过程。有一点学习曲线,但我在我所有的机器学习项目中都使用它。它允许您为您喜欢的任何参数设置一系列值,即learning_rate=[0.1,0.001,0.0001等],并将多次运行模型以搜索最佳的超参数集。

我将在不登录的情况下添加您的乙状结肠激活

您还应该使用某种精度,因为损失本身并不能告诉您除原始进度之外的其他情况。Keras可以为您自动推断:

model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])
<>我也会考虑创建一个验证集来运行,这样您就可以看到模型如何对未见过的数据执行。如果这意味着训练集“过度学习”模式(过度拟合),那么试图提高训练集的准确性是没有意义的,因为这将导致训练集在以前从未见过的数据上表现更差:

h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True)
请注意,作为度量传入的任何内容实际上都不会影响模型的学习方式,它只是用于可读的输出。损失函数影响模型判断性能的方式,进而影响权重更新步骤的范围。所以也许考虑使用不同的损失函数:

!pip install tensorflow_addons

import tensorflow_addons as tfa

loss = tfa.losses.SigmoidFocalCrossEntropy()
h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True, callbacks=[reduce_lr])
我以前在处理像这样的多标签问题时,使用上述损失函数得到了很好的结果

另一个想法是引入学习率调度器,在
监视器未发生变化的特定时期后,该调度器会自动降低学习率:

reduce_lr = ReduceLROnPlateau(monitor='val_acc',min_delta=0.005 ,patience=2, factor=0.1, verbose=1, mode='max')
因此,我们正在监控验证准确性,但您可以指定“val_损失”、“损失”等

我们正在等待2个时期,如果val_acc没有增加0.5%(注意mode='max',所以它正在检查是否增加了),那么学习率将下降10%(
factor=0.1

然后将其作为回调传递到fit函数中:

!pip install tensorflow_addons

import tensorflow_addons as tfa

loss = tfa.losses.SigmoidFocalCrossEntropy()
h = model.fit(scaled_x, y, validation_data=(val_x, val_y), batch_size=512, epochs=400, verbose=1, shuffle=True, callbacks=[reduce_lr])
更新

你完全正确地认为准确性是错误的。对于多标签分类,我通常使用top_k_分类精度,s