Keras-分叉架构的预处理和缩放

时间:2018-08-13 14:09:03

标签: python neural-network keras

我有一个数据集,该数据集具有两个输入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_Lleft部分只是二进制值,而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)如何衡量损失?我想在调整期间创建损失值图表。

1 个答案:

答案 0 :(得分:1)

1)您定义模型的方式似乎是正确的,并且没有“更清洁”的方式(我认为Keras的功能性API就像它获得的一样干净)

2)要可视化训练损失,请将训练历史记录存储在变量中:

history = model.fit(...)

history对象将包含每个时期的训练损失和验证损失,您可以使用它来进行绘图。

3)在分类输出(layer1)中,您想使用sigmoid激活而不是tanh。 sigmoid函数返回0到1之间的值,tanh返回-1到1之间的值。您的binary_crossentropy损失函数期望前者。