Keras 单输入多输出 - 为什么与单输出相比损失如此之高?
Keras Single Input Multiple Outputs - why losses are so high comparing with Single Output?
我认为我的 Keras 多输出编码有问题,与 Sequential 模型相比会导致高损失。请帮我看看哪里错了
import os, random, string, pandas, math, numpy
import tensorflow as tf
from tensorflow import keras
训练数据:
feature_data = [] # common feature data
label_data = [] # for multiple outputs
single_data = [] # for single output
size = 10000
features = ['x1', 'x2']
labels = ['y1', 'y2']
for i in range(size):
a = random.random()
b = random.random()
c = math.sin(a)
d = math.cos(b)
feature = [a, b]
label = [c, d]
feature_data.append(feature)
label_data.append(label)
single_data.append(c)
这是我的单输出模型,运行良好:loss < 2e-05
single = keras.Sequential([
keras.layers.Dense(2, input_shape=(2,), activation=tf.nn.softmax),
keras.layers.Dense(4, activation=tf.nn.softmax),
keras.layers.Dense(1)])
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
single.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
single.fit(x=feature_data, y=single_data, epochs=100, batch_size=100)
这应该是相同的多输出模型,但损失真的很高:0.1
def build_model():
input_shape=(2, )
inputs = keras.Input(shape=input_shape)
outputs = []
for label in labels:
u = keras.layers.Dense(2, input_shape=input_shape, activation=tf.nn.softmax)(inputs)
v = keras.layers.Dense(4, activation=tf.nn.softmax)(u)
w = keras.layers.Dense(1, name=label)(v)
outputs.append(w)
model = keras.Model(inputs = inputs, outputs = outputs)
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
model.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
return model
model = build_model()
model.fit(x=feature_data, y=label_data, epochs=100, batch_size=100)
我猜输入层或标签数据格式有问题,但仍然不知道如何解决。请帮忙。
[忽略这个]
第二个模型与第一个模型不一样:它在开始时使用了不同的Dense层。
这个结构匹配第一个模型:
def build_model():
input_shape=(2, )
inputs = keras.Input(shape=input_shape)
outputs = []
d = keras.layers.Dense(2, input_shape=input_shape, activation=tf.nn.softmax)
for label in labels:
u = d(inputs)
v = keras.layers.Dense(4, activation=tf.nn.softmax)(u)
w = keras.layers.Dense(1, name=label)(v)
outputs.append(w)
model = keras.Model(inputs = inputs, outputs = outputs)
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
model.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
return model
该结构与第一个模型匹配,因为它使用相同的密集层(完全相同的权重)来解释两个链中的输入。
尝试绘制第二个网络的丢失历史记录。您可能会看到双重振荡值:一个变好,另一个变坏,并且它们交换位置。
没注意。
Softmax 用于从多个可能的输出中选择一个。你做的是连续电平输出,而不是单热编码。
如果您在正确的密集层选择正确的激活函数,我认为您的第二个模型应该可以工作。
查看您的数据,您正在预测 (0->1) 的 sin 和 (0->1) 的 cos。从图表上看,这些都是正弦和余弦范围内的非常平坦的线。这是一个非常小的模型,可能任何或所有密集层上的 tanh 或 sigmoid 都可以完成这项工作。
我认为我的 Keras 多输出编码有问题,与 Sequential 模型相比会导致高损失。请帮我看看哪里错了
import os, random, string, pandas, math, numpy
import tensorflow as tf
from tensorflow import keras
训练数据:
feature_data = [] # common feature data
label_data = [] # for multiple outputs
single_data = [] # for single output
size = 10000
features = ['x1', 'x2']
labels = ['y1', 'y2']
for i in range(size):
a = random.random()
b = random.random()
c = math.sin(a)
d = math.cos(b)
feature = [a, b]
label = [c, d]
feature_data.append(feature)
label_data.append(label)
single_data.append(c)
这是我的单输出模型,运行良好:loss < 2e-05
single = keras.Sequential([
keras.layers.Dense(2, input_shape=(2,), activation=tf.nn.softmax),
keras.layers.Dense(4, activation=tf.nn.softmax),
keras.layers.Dense(1)])
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
single.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
single.fit(x=feature_data, y=single_data, epochs=100, batch_size=100)
这应该是相同的多输出模型,但损失真的很高:0.1
def build_model():
input_shape=(2, )
inputs = keras.Input(shape=input_shape)
outputs = []
for label in labels:
u = keras.layers.Dense(2, input_shape=input_shape, activation=tf.nn.softmax)(inputs)
v = keras.layers.Dense(4, activation=tf.nn.softmax)(u)
w = keras.layers.Dense(1, name=label)(v)
outputs.append(w)
model = keras.Model(inputs = inputs, outputs = outputs)
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
model.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
return model
model = build_model()
model.fit(x=feature_data, y=label_data, epochs=100, batch_size=100)
我猜输入层或标签数据格式有问题,但仍然不知道如何解决。请帮忙。
[忽略这个] 第二个模型与第一个模型不一样:它在开始时使用了不同的Dense层。
这个结构匹配第一个模型:
def build_model():
input_shape=(2, )
inputs = keras.Input(shape=input_shape)
outputs = []
d = keras.layers.Dense(2, input_shape=input_shape, activation=tf.nn.softmax)
for label in labels:
u = d(inputs)
v = keras.layers.Dense(4, activation=tf.nn.softmax)(u)
w = keras.layers.Dense(1, name=label)(v)
outputs.append(w)
model = keras.Model(inputs = inputs, outputs = outputs)
optimizer = tf.optimizers.RMSprop(learning_rate=0.001)
model.compile(loss='mse', optimizer=optimizer, metrics=['mae'])
return model
该结构与第一个模型匹配,因为它使用相同的密集层(完全相同的权重)来解释两个链中的输入。
尝试绘制第二个网络的丢失历史记录。您可能会看到双重振荡值:一个变好,另一个变坏,并且它们交换位置。
没注意。
Softmax 用于从多个可能的输出中选择一个。你做的是连续电平输出,而不是单热编码。
如果您在正确的密集层选择正确的激活函数,我认为您的第二个模型应该可以工作。
查看您的数据,您正在预测 (0->1) 的 sin 和 (0->1) 的 cos。从图表上看,这些都是正弦和余弦范围内的非常平坦的线。这是一个非常小的模型,可能任何或所有密集层上的 tanh 或 sigmoid 都可以完成这项工作。