python - 基本 tensorflow 分类示例

标签 python tensorflow

我很难理解 tensorflow,而且我找不到不依赖于 MNIST 数据集的好的基本示例。我试图为一些公共(public)数据集创建一个分类 nn,它们提供了许多(未知的)特征,并为每个样本提供了一个标签。他们提供了大约 90 种音频分析功能,并以出版年份作为标签。 ( https://archive.ics.uci.edu/ml/datasets/yearpredictionmsd )

不用说,我没有设法训练网络,而且我对理解所提供的功能也无能为力。

我现在正在尝试生成人工数据,并尝试围绕它训练网络。数据是一对数字(位置),如果该位置在任意点(5,5)周围半径为 r 的圆内,则标签为 1。

numrows=10000
circlex=5
circley=5
circler=3

data = np.random.rand(numrows,2)*10
labels = [ math.sqrt( math.pow(x-circlex, 2) + math.pow(y-circley, 2) ) for x,y in data ]
labels = list( map(lambda x: x<circler, labels) )

如果尝试了网络形状、参数、优化器、学习率等的多种组合(我承认这方面的数学不强),但要么没有收敛,要么很糟糕(上次测试的准确率为 70%)。

当前版本(标签转换为 one_hot 编码 [1,0] 和 [0,1](外部,内部)。

# model creation

graph=tf.Graph()
with graph.as_default():
    X = tf.placeholder(tf.float32, [None, 2] )
    layer1 = tf.layers.dense(X, 2)
    layer2 = tf.layers.dense(layer1, 2)
    Y = tf.nn.softmax(layer2)
    y_true = tf.placeholder(tf.float32, [None, 2] )

    loss=tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits_v2(logits=Y, labels=y_true) )
    optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

def accuracy(predictions, labels):
    return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) 
      / predictions.shape[0])

# training
with tf.Session(graph=graph) as session:
    tf.global_variables_initializer().run()
    for step in range(1000):
        _, l, predictions = session.run([optimizer,loss,Y], feed_dict={X:data, y_true:labels})
        if step % 100 == 0:
            print("Loss at step %d: %f" % (step, l)
            print("Accuracy %f" % accuracy(predictions, labels))

此示例中的准确性约为 70%(损失约为 0.6)。

问题是……我做错了什么?

更新

我将按照最初提出的问题离开。我学到的主要经验教训:

标准化您的输入数据。平均值应该在 0 左右,范围在 -1 和 1 之间。

Normalized vs not normalized

蓝色:归一化数据,红色:上面创建的原始输入数据

批量输入数据。如果使用的子集足够随机,它会减少所需的迭代次数,而不会对准确性造成太大影响。

不要忘记层与层之间的激活函数 :)

最佳答案

输入:

用两个类绘制合成数据。

enter image description here

上述代码的输出:

所有输出都被归类为单一类别,由于类别不平衡,准确率高达 70%。

enter image description here


代码问题

  1. 尽管定义了两层,但两者之间没有定义激活函数。所以 tf.softmax( ((x*w1)+b1) * w2 + b2) 压缩到一个层。只有一个超平面试图分离这个输入,而超平面位于输入空间之外,这就是为什么你将所有输入分类为一个类。
  2. 错误:Softmax 应用了两次:在 logits 上以及在 entropy_loss 期间。
  3. 整个输入作为单个批处理给出,而不是小批量
  4. 输入需要标准化。

修复上述问题,输出变为:

enter image description here

上面的输出是有道理的,因为模型有两个隐藏层,所以我们有两个超平面试图分离数据。最后一层然后以最小化误差的方式组合这两个超平面。


将隐藏层从 2 层增加到 3 层:

enter image description here

有了 3 个隐藏层,我们得到了 3 个超平面,我们可以看到最后一层调整这些超平面以很好地分离数据。


代码:

# Normalize data
data = (data - np.mean(data)) /np.sqrt(np.var(data))
n_hidden = 3
batch_size = 128

# Feed batch data
def get_batch(inputX, inputY, batch_size):
   duration = len(inputX)
   for i in range(0,duration//batch_size):
     idx = i*batch_size
     yield inputX[idx:idx+batch_size], inputY[idx:idx+batch_size]

# Create the graph    
tf.reset_default_graph()
graph=tf.Graph()
with graph.as_default():
   X = tf.placeholder(tf.float32, [None, 2] )
   layer1 = tf.layers.dense(X, n_hidden, activation=tf.nn.sigmoid)
   layer2 = tf.layers.dense(layer1, 2)
   Y = tf.nn.softmax(layer2)
   y_true = tf.placeholder(tf.int32, [None] )
   loss = tf.losses.sparse_softmax_cross_entropy(logits=layer2, labels=y_true)
   optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

   accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Y, 1),tf.argmax(tf.one_hot(y_true,2), 1)), tf.float32)) 

   # training
   with tf.Session(graph=graph) as session:
      session.run(tf.global_variables_initializer())
      for epoch in range(10):
        acc_avg = 0.
        loss_avg = 0.
        for step in range(10000//batch_size):
           for inputX, inputY in get_batch(data, labels, batch_size):
               _, l, acc = session.run([optimizer,loss,accuracy], feed_dict={X:inputX, y_true:inputY})
           acc_avg += acc
           loss_avg += l
        print("Loss at step %d: %f" % (step, loss_avg*batch_size/10000))
        print("Accuracy %f" % (acc_avg*batch_size/10000))        
   #Get prediction  
   pred = session.run(Y, feed_dict={X:data})

  # Plotting function
  import matplotlib.pylab as plt
  plt.scatter(data[:,0], data[:,1], s=20, c=np.argmax(pred,1),  cmap='jet', vmin=0, vmax=1)
  plt.show()

关于python - 基本 tensorflow 分类示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50485506/

相关文章:

python - 在 Python 中模拟套接字连接

python - 如何使用汇总统计注释seaborn PairGrid 对角线

python - 使用 "long"(包装)在 jupyter notebook 中显示 "foldover"pandas 数据框?

python - 为什么python multiprocessing pickle对象在进程之间传递对象?

python - 类型错误 : __call__() takes from 1 to 2 positional arguments but 3 were given

Python TensorFlow

Tensorflow 获取范围内的所有变量

python - 'ToPILImage' 对象没有属性 'show'

python - TensorFlow Keras 指南 : custom layer get_config method not updating the layer's configuration?

python - TensorFlow 中特定的线性分类器 : input element as vector