我有一个数据集,该数据集具有两个输入x1,x2
,并且输出具有1个二进制值(0,1)和45个实数(总的来说,输出向量有46个字符)。我想对此1个二进制值和45个实数使用不同的损失函数,即二进制交叉熵和均方误差。
我对Keras的了解非常有限,所以我甚至不确定这是否是我想要的体系结构。这是正确的方法吗?
首先,预处理
# load dataset
dataframe = pandas.read_csv("inputs.csv", delim_whitespace=True,header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:2]
Y = dataset[:,3:]
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2,
random_state=123)
y_train_L, y_train_R = y_train[:,0], y_train[:,1:]
y_train_L = y_train_L.reshape(-1,1)
scalarX, scalarY_L, scalarY_R = MinMaxScaler(), MinMaxScaler(), MinMaxScaler()
scalarX.fit(x_train)
scalarY_L.fit(y_train_L)
scalarY_R.fit(y_train_R)
x_train = scalarX.transform(x_train)
y_train_L = scalarY_L.transform(y_train_L)
y_train_R = scalarY_R.transform(y_train_R)
其中y_train_L
是left
部分只是二进制值,而y_train_R
是实数。我必须拆分它们,因为在定义体系结构时:
# define and fit the final model
inputs = Input(shape=(x_train.shape[1],))
first =Dense(46, activation='relu')(inputs)
#last
layer45 = Dense(45, activation='linear')(first)
layer1 = Dense(1, activation='tanh')(first)
out = [layer1,layer45]
#end last
model = Model(inputs=inputs,outputs=out)
model.compile(loss=['binary_crossentropy','mean_squared_error'], optimizer='adam')
model.fit(x_train, [y_train_L,y_train_R], epochs=1000, verbose=1)
Xnew = scalarX.transform(x_test)
y_test_L, y_test_R = y_test[:,0], y_test[:,1:]
y_test_L = y_test_L.reshape(-1,1)
y_test_L=scalarY_L.transform(y_test_L)
y_test_R=scalarY_R.transform(y_test_R)
# make a prediction
ynew = model.predict(Xnew)
loss=['binary_crossentropy','mean_squared_error']
在model.fit(x_train, [y_train_L,y_train_R])
中期望两个不同的数组
然后,我必须做所有的“有趣”技巧才能获得预测值并将它们彼此比较,因为ynew = model.predict(Xnew)
返回list
中的两个lists
,一个用于二进制值,一个用于实数。
ynew = model.predict(Xnew)
# show the inputs and predicted outputs
print("SCALED VALUES")
for i in range(len(Xnew)):
print("X=%s\n P=%s,%s\n A=%s,%s" % (Xnew[i], ynew[0][i], ynew[1][i], y_test_L[i], y_test_R[i]))
inversed_X_test = scalarX.inverse_transform(Xnew)
inversed_Y_test_L = scalarY_L.inverse_transform(y_test_L)
inversed_Y_test_R = scalarY_R.inverse_transform(y_test_R)
inversed_y_predicted_L = scalarY_L.inverse_transform(ynew[0])
inversed_y_predicted_R = scalarY_R.inverse_transform(ynew[1])
print("REAL VALUES")
for i in range(len(inversed_X_test)):
print("X=%s\n P=%s,%s\n A=%s,%s" % (inversed_X_test[i], inversed_y_predicted_L[i],inversed_y_predicted_R[i], inversed_Y_test_L[i],inversed_Y_test_R[i]))
问题:
1)我可以以更简洁的方式实现这一目标吗?
2)如何衡量损失?我想在调整期间创建损失值图表。
答案 0 :(得分:1)
1)您定义模型的方式似乎是正确的,并且没有“更清洁”的方式(我认为Keras的功能性API就像它获得的一样干净)
2)要可视化训练损失,请将训练历史记录存储在变量中:
history = model.fit(...)
此history
对象将包含每个时期的训练损失和验证损失,您可以使用它来进行绘图。
3)在分类输出(layer1
)中,您想使用sigmoid
激活而不是tanh
。 sigmoid函数返回0到1之间的值,tanh
返回-1到1之间的值。您的binary_crossentropy
损失函数期望前者。