我正在尝试仅根据公寓内所有电力的总和来分类哪些电子设备是打开的。我有一个设置,可以测量每个瓦特小时(LED闪烁一次),因此当前的瓦特消耗精度大约为10秒,这很不错。
我正在尝试使用tensorflow来做这件事,第一轮迭代中,我只想使用一个输入(总瓦特数,例如200W),并且我想为每件电子设备设置一个输出。我现在也使用虚拟数据来看看它是如何工作的(因为将每个测量值分类以便教算法会非常麻烦)。
这是我现在的代码:
import tensorflow as tfimport numpy as npLABELS = ['Nothing','Toaster', # Toaster uses 800W'Lamp'] # Lamp uses just 100WDATA_LENGTH = 20000np.random.seed(1) # To be able to reproduce# Create dummy data (1:s or 0:s)nothing_data = np.array([1] * DATA_LENGTH)toaster_data = np.random.randint(2, size=DATA_LENGTH)lamp_data = np.random.randint(2, size=DATA_LENGTH)labels = np.array(list(zip(nothing_data, toaster_data, lamp_data)))x_train = (toaster_data * 800 + lamp_data * 100) / 900 # Normalizey_train = labels# Split up train and test datax_test = x_train[15000:]y_test = y_train[15000:]x_train = x_train[:15000]y_train = y_train[:15000]# The modelmodel = tf.keras.models.Sequential([ tf.keras.layers.Dense(1, input_dim=1), tf.keras.layers.Dense(4, activation=tf.nn.relu), tf.keras.layers.Dense(4, activation=tf.nn.relu), tf.keras.layers.Dense(3, activation=tf.nn.sigmoid)])model.compile(optimizer='adadelta', loss='binary_crossentropy', metrics=['accuracy'])history = model.fit(x_train, y_train, epochs=10)val_loss, val_acc = model.evaluate(x_test, y_test)print(val_loss, val_acc)
现在的问题是,验证准确率(val_acc)是1.0,即100%。(val_loss=0.059, val_acc=1.0)然而,当我进行预测时,预测结果却非常不准确。
# Predictpredict_input = [0.88888, 0.111111, 1.0000, 0.222]predict_output = model.predict(predict_input)
第一个应该只有烤面包机和无,但结果却显示有33%的灯。我希望能得到二进制输出,如果可能的话。
我需要一个“无”输出吗?
回答:
你需要将模型类型与你的问题相匹配。你所应用的基本上是一种混合线性回归预测,用于二元分类问题。如果你想根据打开的电器来预测瓦特数,这个模型很好,但在相反的方向上就不那么好了。
它会尝试用给定的少量数据和模型固有的自由度做各种尝试。请注意,你实际上只有四个训练输入:制作多个等量的副本并不会真正改善你的训练效果。
最重要的是,为什么你不使用“总和目标”算法,这是一种更简单、更有效的解决问题的方法。所呈现的问题实际上并不是一个机器学习类型的问题。
如果你只是想通过训练模型来做这件事,那么构建一个具有多个二进制输出的模型。你可以研究“多标签”来寻找如何做到这一点的线索。如果你只是为家里的一小部分电器做这件事,你可能想用2^n个输出状态来解决它,而不必担心结构上的准确性。