我正在尝试创建一个keras神经网络,以预测城市两点之间道路上的距离。我正在使用Google Maps获取行进距离,然后训练神经网络来做到这一点。
@Configuration
public class CommonConfiguration{
...
@Value("${spring.kafka.topic}")
public String topic;
...
}
@Service
class KafkaService @Autowired()(producer: KafkaTemplate[String, Array[Byte]], config: CommonConfiguration){
def sendMessage(msg: String): Unit = {
val topics : Array[String] = config.getTopics();
println(s"Writing the message $msg ${topics.mkString(" ")}")
producer.send(config.topic, msg.getBytes());
}
@KafkaListener(id="test", topics="#{config.topic.split(',')}")
def consume(record: ConsumerRecord[String, String]): Unit = {
System.out.println(s"Consumed Strinsg Message : ${record.value()}")
}
}
神经网络架构:
import pandas as pd
arr=[]
for i in range(0,100):
arr.append(generateTwoPoints(55.901819,37.344735,55.589537,37.832254))
df=pd.DataFrame(arr,columns=['p1Lat','p1Lon','p2Lat','p2Lon', 'distnaceInMeters', 'timeInSeconds'])
print(df)
然后我将集合划分为测试/训练
from keras.optimizers import SGD
sgd = SGD(lr=0.00000001)
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential()
model.add(Dense(100, input_dim=4 , activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(1,activation='sigmoid'))
model.compile(loss='mse', optimizer='sgd', metrics=['mse'])
然后我将数据放入模型中,但损失保持不变:
Xtrain=train[['p1Lat','p1Lon','p2Lat','p2Lon']]/100
Ytrain=train[['distnaceInMeters']]/100000
Xtest=test[['p1Lat','p1Lon','p2Lat','p2Lon']]/100
Ytest=test[['distnaceInMeters']]/100000
我稍后打印数据:
history = model.fit(Xtrain, Ytrain,
batch_size=1,
epochs=1000,
# We pass some validation for
# monitoring validation loss and metrics
# at the end of each epoch
validation_data=(Xtest, Ytest))
但是所有输入的结果都相同:
prediction = model.predict(Xtest)
print(prediction)
print (Ytest)
我找不到问题。它是什么?我是机器学习的新手。
答案 0 :(得分:1)
您犯了一个非常基本的错误:由于您处于回归设置中,因此您不应该不为最终层使用sigmoid
激活(此方法用于二进制分类情况) ;将最后一层更改为
model.add(Dense(1,activation='linear'))
甚至
model.add(Dense(1))
因为根据docs,如果您未指定activation
参数,则默认为linear
。
在其他答案中已经提供的各种其他建议和注释可能会有用(较低的LR,更多的层,其他优化器,例如Adam
),并且您当然需要增加批量大小;但您目前用于最后一层的sigmoid
激活功能将无法使用。
对该问题有好处,但在回归设置中,您无需重复将损失函数用作指标;这个
model.compile(loss='mse', optimizer='sgd')
足够了。
答案 1 :(得分:0)
如果您可以在整个训练过程中发布损失和MSE(训练和验证/测试集)的进度,这将非常有用。更好的是,最好是按照https://machinelearningmastery.com/display-deep-learning-model-training-history-in-keras/对其进行可视化并在此处发布Vizualization。
同时,基于事实: 1)您说损失并没有减少(我假设在训练过程中,根据您的编译参数,得出训练集)。 2)您说测试集上的预测“准确性”不好。 3)我的经验/直觉(不是经验评估)告诉我,您的两层密集模型太小了,无法捕获数据固有的复杂性。也就是您的模型存在偏高https://towardsdatascience.com/understanding-the-bias-variance-tradeoff-165e6942b229
您可以尝试的最快,最简单的方法是尝试在每层中添加更多的层和更多的节点。
但是,我要注意的是,有很多因果信息会影响行驶距离和行驶时间,而不仅仅是两个坐标之间的距离,这可能是您的神经网络最容易提取的功能。例如,无论您是在高速公路上行驶,还是在小路旁,交通信号灯,道路转弯还是直行时……仅从数据中推断所有这些,您就需要大量数据(示例)意见。如果您可以使用例如添加输入列从这两个点到最近的高速路都不是,您也许可以用更少的数据进行训练
我也建议您将您正在喂食的食物(及其形状)作为输入来进行检查,并且还应该使用函数sklearn的一些标准化,这可能有助于模型学习更快并更快地收敛到更高的“准确性”。
如果并且当您发布更多代码或培训历史记录时,我可以为您提供更多帮助(以及多少培训样本)。
编辑1:如果可能,请尝试将批量大小更改为更大的数量,最好是batch_size=32
。您可以在处理“信息丰富”的输入(例如图像)时使用小批量(例如1),但是当使用非常“信息贫乏”的数据(例如4个浮点数(2个坐标))时,渐变将指向每个批次( batch_size=1
)移至实际上是随机(伪...)的方向,而不必一定更接近局部最小值。仅当对较大批次(例如32个,甚至更多)的总体损失进行梯度计算时,您会得到一个至少近似指向局部最小值方向并收敛到更好结果的梯度。另外,我建议您不要手动调整学习率,而最好改成“ adam”或“ RMSProp”之类的优化程序。
编辑2 :@Desertnaut提出了一个我完全没想到的要点,如果没有更正,您的代码将无法正常工作。他应得的功劳,所以我在这里不再赘述。请参考他的答案。另外,别忘了增加批量大小,不要“手动搞乱”您的学习率,例如“ adam”会帮您做到这一点。