Skip to main content
 首页 » 编程设计

python之Tensorflow:仅基于第一个输入进行分类

2025年01月19日30myhome

开始了解 Tensorflow,我构建了一个用于分类的玩具网络。它由 15 个输入节点组成,其特征与相应类标签的单热编码相同(索引从 1 开始)——因此从输入 CSV 加载的数据可能如下所示:

1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2 
... 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,15 

网络只有一个隐藏层和一个输出层,后者包含给定类别的概率。 这是我的问题:在训练过程中,网络会评估作为第一个输入输入的任何内容的可能性越来越大。

相关代码行如下(部分省略):

# number_of_p : number of samples 
# number_of_a : number of attributes (features) -> 15 
# number_of_s : number of styles (labels) -> 15 
 
# function for generating hidden layers 
# nodes is a list of nodes in each layer (len(nodes) = number of hidden layers) 
 
def hidden_generation(nodes): 
 
    hidden_nodes = [number_of_a] + nodes + [number_of_s] 
    number_of_layers = len(hidden_nodes) - 1 
 
    print(hidden_nodes) 
    hidden_layer = list() 
    for i in range (0,number_of_layers): 
        hidden_layer.append(tf.zeros([hidden_nodes[i],batch_size])) 
 
    hidden_weights = list() 
    for i in range (0,number_of_layers): 
        hidden_weights.append(tf.Variable(tf.random_normal([hidden_nodes[i+1], hidden_nodes[i]]))) 
 
    hidden_biases = list() 
    for i in range (0,number_of_layers): 
        hidden_biases.append(tf.Variable(tf.zeros([hidden_nodes[i+1],batch_size]))) 
 
    return hidden_layer, hidden_weights, hidden_biases 
 
#loss function 
def loss(labels, logits): 
    cross_entropy = tf.losses.softmax_cross_entropy( 
        onehot_labels = labels, logits = logits) 
    return tf.reduce_mean(cross_entropy, name = 'xentropy_mean') 
 
hidden_layer, hidden_weights, hidden_biases = hidden_generation(hidden_layers) 
 
with tf.Session() as training_sess: 
 
    training_sess.run(tf.global_variables_initializer()) 
    training_sess.run(a_iterator.initializer, feed_dict = {a_placeholder_feed: training_set.data}) 
    current_a = training_sess.run(next_a)    
    training_sess.run(s_iterator.initializer, feed_dict = {s_placeholder_feed: training_set.target}) 
    current_s = training_sess.run(next_s)  
 
    s_one_hot = training_sess.run(tf.one_hot((current_s - 1), number_of_s)) 
 
    for i in range (1,len(hidden_layers)+1): 
        hidden_layer[i] = tf.tanh(tf.matmul(hidden_weights[i-1], (hidden_layer[i-1])) + hidden_biases[i-1]) 
 
    output = tf.nn.softmax(tf.transpose(tf.matmul(hidden_weights[-1],hidden_layer[-1]) + hidden_biases[-1])) 
 
    optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1) 
    # using the AdamOptimizer does not help, nor does choosing a much bigger and smaller learning rate 
    train = optimizer.minimize(loss(s_one_hot, output)) 
 
    training_sess.run(train) 
 
    for i in range (0, (number_of_p)): 
 
        current_a = training_sess.run(next_a) 
        current_s = training_sess.run(next_s) 
        s_one_hot = training_sess.run(tf.transpose(tf.one_hot((current_s - 1), number_of_s))) 
        # (no idea why I have to declare those twice for the datastream to move) 
 
        training_sess.run(train) 

我假设损失函数是在错误的地方声明的,并且总是引用相同的向量。但是,替换损失函数现在对我没有帮助。 如果有人愿意帮助我,我很乐意提供其余代码。

编辑:我已经发现并修复了一个主要(也是愚蠢的)错误:权重在 tf.matmul 中位于值节点值之前。

请您参考如下方法:

您不想一遍又一遍地声明训练操作。那是不必要的,就像您指出的那样速度较慢。您没有将 current_a 馈入神经网络。所以你不会得到新的输出,而且你使用迭代器的方式也不正确,这也可能是问题的原因。

with tf.Session() as training_sess: 
 
    training_sess.run(tf.global_variables_initializer()) 
    training_sess.run(a_iterator.initializer, feed_dict = {a_placeholder_feed: training_set.data}) 
    current_a = training_sess.run(next_a)    
    training_sess.run(s_iterator.initializer, feed_dict = {s_placeholder_feed: training_set.target}) 
    current_s = training_sess.run(next_s)  
 
    s_one_hot = training_sess.run(tf.one_hot((current_s - 1), number_of_s)) 
 
    for i in range (1,len(hidden_layers)+1): 
        hidden_layer[i] = tf.tanh(tf.matmul(hidden_weights[i-1], (hidden_layer[i-1])) + hidden_biases[i-1]) 
 
    output = tf.nn.softmax(tf.transpose(tf.matmul(hidden_weights[-1],hidden_layer[-1]) + hidden_biases[-1])) 
 
    optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1) 
    # using the AdamOptimizer does not help, nor does choosing a much bigger and smaller learning rate 
    train = optimizer.minimize(loss(s_one_hot, output)) 
 
    training_sess.run(train) 
 
    for i in range (0, (number_of_p)): 
 
        current_a = training_sess.run(next_a) 
        current_s = training_sess.run(next_s) 
        s_one_hot = training_sess.run(tf.transpose(tf.one_hot((current_s - 1), number_of_s))) 
        # (no idea why I have to declare those twice for the datastream to move) 
 
        training_sess.run(train) 

这里有一些伪代码可以帮助您获得正确的数据流。我会在此之前进行一次热编码,只是为了在训练期间更容易加载数据。

train_dataset = tf.data.Dataset.from_tensor_slices((inputs, targets)) 
 
train_dataset = train_dataset.batch(batch_size) 
train_dataset = train_dataset.repeat(num_epochs) 
iterator = train_dataset.make_one_shot_iterator() 
 
next_inputs, next_targets = iterator.get_next() 
 
# Define Training procedure 
global_step = tf.Variable(0, name="global_step", trainable=False) 
loss = Neural_net_function(next_inputs, next_targets) 
optimizer = tf.train.AdamOptimizer(learning_rate) 
grads_and_vars = optimizer.compute_gradients(loss) 
train_op = optimizer.apply_gradients(grads_and_vars, global_step=global_step) 
 
 
 
with tf.Session() as training_sess: 
    for i in range(number_of_training_samples * num_epochs): 
            taining_sess.run(train_op)