使用Tensorflow训练多层感知器对-1、0或1进行分类的问题

我正在尝试创建一个多层感知器来根据一些指标对情感进行分类。情感可以是-1(坏)、0(中性)或1(好)。我能找到的所有分类器示例都是独热编码的,所以我认为我在将这个模型适应连续特征的过程中做错了什么。

# Data Prepnp.random.shuffle(raw_data)X_vals = raw_data[:-200,0:4]Y_vals = [(x,) for x in raw_data[:-200,4]]X_test = raw_data[-200:,0:4]Y_test = [(x,) for x in raw_data[-200:,4]]# Parameterslearning_rate = 0.001training_epochs = 10batch_size = 200display_step = 1# Network Parametersn_hidden_1 = 16 # 1st layer number of neuronsn_hidden_2 = 16 # 2nd layer number of neuronsn_input = 4n_classes = 1# tf Graph inputX = tf.placeholder("float", [None, n_input])Y = tf.placeholder("float", [None, n_classes])# Store layers weight & biasweights = {    'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),    'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))}biases = {    'b1': tf.Variable(tf.random_normal([n_hidden_1])),    'b2': tf.Variable(tf.random_normal([n_hidden_2])),    'out': tf.Variable(tf.random_normal([n_classes]))}# Create modeldef multilayer_perceptron(x):    # Hidden fully connected layer with 256 neurons    layer_1 = tf.nn.tanh(tf.add(tf.matmul(x, weights['h1']), biases['b1']))    # Hidden fully connected layer with 256 neurons    layer_2 = tf.nn.tanh(tf.add(tf.matmul(layer_1, weights['h2']), biases['b2']))    # Output fully connected layer with a neuron for each class    out_layer = tf.matmul(layer_2, weights['out']) + biases['out']    return out_layer# Construct modellogits = multilayer_perceptron(X)# Define loss and optimizerloss_op = tf.losses.mean_squared_error(labels=Y,                                        predictions=tf.nn.softmax(logits))optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)train_op = optimizer.minimize(loss_op)# Initializing the variablesinit = tf.global_variables_initializer()with tf.Session() as sess:    sess.run(init)    # Training cycle    for epoch in range(training_epochs):        avg_cost = 0.        total_batch = int(raw_data.shape[0]/batch_size)        # Loop over all batches        for i in range(total_batch):            batch_x = X_vals[epoch*batch_size:(epoch+1)*batch_size]            batch_y = Y_vals[epoch*batch_size:(epoch+1)*batch_size]            # Run optimization op (backprop) and cost op (to get loss value)            _, c = sess.run([train_op, loss_op], feed_dict={X: batch_x,                                                            Y: batch_y})            print("Optimization Finished!")# Test modelpred = tf.nn.softmax(logits)  # Apply softmax to logitscorrect_prediction = tf.equal(tf.round(pred), Y)# Calculate accuracyaccuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))print("Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))

我期望以上代码能够创建一个具有两个隐藏层(每层16个神经元)的tanh感知器,以及一个softmax输出层,使用除最后200个数据点之外的所有数据进行训练,然后在最后200个数据点上进行测试。它应该输出-1到1之间的值,然后我将其四舍五入以评估与正确标签-1、0或1的匹配情况。

我认为我一定是做错了什么,因为结果与随机机会一样好,即使输入和输出之间有30%的皮尔逊相关系数。这本来应该是很简单的任务。


回答:

我注意到你的模型有两个问题。首先,softmax层将所有数据限制在[0,1]范围内,所以你永远不会得到你想要的-1值。正如你所说,数据确实应该使用独热编码,因为即使你的模型能够输出-1,它在测试时也会非常偏差且不够准确。所以我建议你将n_classes改为3,并将索引0设为坏,索引1设为中性,索引2设为好。你的标签应该是3向量,其中正确类别的索引位置为1,其他位置为0。这代表了你希望模型学习的每个类别标签的概率分布。

最后,你使用了均方误差(MSE)。这对于欧几里得嵌入来说是一个好的误差度量(例如,如果你想学习YOLO那样定位边界框的位置),但对于你想要的概率分布嵌入来说效果不会很好,因为它测量的是标签与网络输出的欧几里得距离。你需要的是tf.losses.softmax_cross_entropy。它首先将数据通过softmax处理,然后计算交叉熵(两个概率分布之间的KL散度)。

所以你应该将

loss_op = tf.losses.mean_squared_error(labels=Y,predictions=tf.nn.softmax(logits))

改为

loss_op = tf.losses.softmax_cross_entropy(onehot_labels=Y,logits=logits)

确保在测试时仍然使用softmax。

最后,你使用了1比1的训练/测试分割。通常人们会使用类似3比1或3比2的比例,这样你就有更多的训练数据而不是测试数据,这通常会带来更好的结果。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注