我正在尝试创建一个多层感知器,以基于一些指标对情绪进行分类。情绪可以是-1(差),0(中性)或1(好)。我能找到的所有分类器示例都是热门的,所以我认为我在将其用于连续特征的方式上做错了。
# Data Prep
np.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]]
# Parameters
learning_rate = 0.001
training_epochs = 10
batch_size = 200
display_step = 1
# Network Parameters
n_hidden_1 = 16 # 1st layer number of neurons
n_hidden_2 = 16 # 2nd layer number of neurons
n_input = 4
n_classes = 1
# tf Graph input
X = tf.placeholder("float", [None, n_input])
Y = tf.placeholder("float", [None, n_classes])
# Store layers weight & bias
weights = {
'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 model
def 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 model
logits = multilayer_perceptron(X)
# Define loss and optimizer
loss_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 variables
init = 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 model
pred = tf.nn.softmax(logits) # Apply softmax to logits
correct_prediction = tf.equal(tf.round(pred), Y)
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print("Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))
所以我希望所有这些都是创建一个tanh感知器,该感知器具有2个隐藏层,每个隐藏层16个神经元和一个softmax输出层,对除200个数据点外的所有数据点进行训练,然后在最后200个数据点上对其进行测试。它应该吐出介于-1和1之间的值,然后我将其舍入以针对正确的-1、0或1标签进行评估。
我认为我一定做错了,因为即使输入和输出之间的皮尔逊相关性达到30%,结果也比随机机会更好。这本来应该很简单。
答案 0 :(得分:2)
我注意到您的模型有两点错误。首先,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之类的东西,以便您拥有比测试数据更多的训练数据,这通常会带来更好的结果。