An example of using Tensorflow to solve geometric problems

There is a question on Zhihu . The content is to know the coordinates of three points in the space. Find the coordinates of the center of the circle formed by the three points (programming implementation)?

According to the definition of a circle, the core of this problem is to find a point with equal distances to the three known points. Using mathematical knowledge, it can be solved as follows:

For example: given a(x1, y1) b(x2, y2) c(x3, y3), find the coordinates of the circumscribed circle center O(x, y)
1. First, the circumscribed circle center is the intersection of the vertical bisectors of the three sides of the triangle , we can list the following equation according to the distance from the center of the circle to the vertex:       
(x1-x)*(x1-x)+(y1-y)*(y1-y)=(x2-x)*(x2-x )+(y2-y)*(y2-y);       
(x2-x)*(x2-x)+(y2-y)*(y2-y)=(x3-x)*(x3-x)+ (y3-y)*(y3-y);
2. Simplify to get:        
2*(x2-x1)*x+2*(y2-y1)y=x2^2+y2^2-x1^2-y1 ^2;        
2*(x3-x2)*x+2*(y3-y2)y=x3^2+y3^2-x2^2-y2^2;        
let: A1=2*(x2-x1);            
B1=2*(y2-y1);            
C1=x2^2+y2^2-x1^2-y1^2;            
A2=2*(x3-x2);            
B2=2*(y3-y2);            
C2= x3^2+y3^2-x2^2-y2^2;        
namely: A1*x+B1y=C1;            
A2*x+B2y=C2;
3. Finally, according to Cramer's rule:          
x=((C1*B2) -(C2*B1))/((A1*B2)-(A2*B1));          
y=((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1));

Of course, we are not here to learn mathematical formulas and mathematical derivation today. Tensorflow is a deep learning tool open sourced by google. In fact, we can use the powerful mathematical computing power provided by Tensorflow to solve similar mathematical problems.

For this problem, we can use the gradient descent algorithm , because the center of the circle is an optimal solution, and any other point is not satisfied with the condition. (The premise is that these three points are not on a straight line, otherwise there is no solution)

Well, let's look at the code first, and then explain.

import tensorflow as tf
import numpy

# Parameters
learning_rate = 0.1
training_epochs = 3000
display_step = 50

# Training Data, 3 points that form a triangel
train_X = numpy.asarray([3.0,6.0,9.0])
train_Y = numpy.asarray([7.0,9.0,7.0])

# tf Graph Input
X = tf.placeholder("float")
Y = tf.placeholder("float")

# Set vaibale for center
cx = tf.Variable(3, name="cx",dtype=tf.float32)
cy = tf.Variable(3, name="cy",dtype=tf.float32)

# Caculate the distance to the center and make them as equal as possible
distance = tf.pow(tf.add(tf.pow((X-cx),2),tf.pow((Y-cy),2)),0.5)
mean = tf.reduce_mean(distance)
cost = tf.reduce_sum(tf.pow((distance-mean),2)/3)
# Gradient descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# Initialize the variables (i.e. assign their default value)
init = tf.global_variables_initializer()

# Start training
with tf.Session() as sess:
    sess.run(init)

    # Fit all training data
    for epoch in range(training_epochs):
        sess.run(optimizer, feed_dict={X: train_X, Y: train_Y})
        c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})
        if (c - 0) < 0.0000000001:
            break
        #Display logs per epoch step
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})
            m = sess.run(mean, feed_dict={X: train_X, Y:train_Y})
            print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \
                "CX=", sess.run(cx), "CY=", sess.run(cy), "Mean=", "{:.9f}".format(m)

    print "Optimization Finished!"
    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
    print "Training cost=", training_cost, "CX=", round(sess.run(cx),2), "CY=", round(sess.run(cy),2), "R=", round(m,2), '\n'

Running the above python code, the result is as follows:

Epoch: 0050 cost= 0.290830940 CX= 5.5859795 CY= 2.6425467 Mean= 5.657848835
Epoch: 0100 cost= 0.217094064 CX= 5.963002 CY= 3.0613017 Mean= 5.280393124
Epoch: 0150 cost= 0.173767462 CX= 5.997781 CY= 3.5245996 Mean= 4.885882378
Epoch: 0200 cost= 0.126330480 CX= 5.9999194 CY= 4.011508 Mean= 4.485837936
Epoch: 0250 cost= 0.078660280 CX= 5.9999976 CY= 4.4997787 Mean= 4.103584766
Epoch: 0300 cost= 0.038911112 CX= 5.9999976 CY= 4.945466 Mean= 3.775567770
Epoch: 0350 cost= 0.014412695 CX= 5.999998 CY= 5.2943544 Mean= 3.535865068
Epoch: 0400 cost= 0.004034557 CX= 5.999998 CY= 5.5200934 Mean= 3.390078306
Epoch: 0450 cost= 0.000921754 CX= 5.999998 CY= 5.6429324 Mean= 3.314131498
Epoch: 0500 cost= 0.000187423 CX= 5.999998 CY= 5.7023263 Mean= 3.278312683
Epoch: 0550 cost= 0.000035973 CX= 5.999998 CY= 5.7292333 Mean= 3.262284517
Epoch: 0600 cost= 0.000006724 CX= 5.999998 CY= 5.7410445 Mean= 3.255288363
Epoch: 0650 cost= 0.000001243 CX= 5.999998 CY= 5.746154 Mean= 3.252269506
Epoch: 0700 cost= 0.000000229 CX= 5.999998 CY= 5.7483506 Mean= 3.250972748
Epoch: 0750 cost= 0.000000042 CX= 5.999998 CY= 5.749294 Mean= 3.250416517
Epoch: 0800 cost= 0.000000008 CX= 5.999998 CY= 5.749697 Mean= 3.250178576
Epoch: 0850 cost= 0.000000001 CX= 5.999998 CY= 5.749871 Mean= 3.250076294
Epoch: 0900 cost= 0.000000000 CX= 5.999998 CY= 5.7499437 Mean= 3.250033140
Optimization Finished!
Training cost= 9.8869656e-11 CX= 6.0 CY= 5.75 R= 3.25 

After more than 900 iterations, the center position is (6.0, 5.75) and the radius is 3.25.

# Parameters
learning_rate = 0.1
training_epochs = 3000
display_step = 50
  • learning_rate is the rate of gradient descent. The larger the value, the faster the convergence, but it may also miss the optimal solution
  • training_epochs is the number of learning iterations
  • display_step is how many iterations to display the current calculation result
# Training Data, 3 points that form a triangel
train_X = numpy.asarray([3.0,6.0,9.0])
train_Y = numpy.asarray([7.0,9.0,7.0])

# tf Graph Input
X = tf.placeholder("float")
Y = tf.placeholder("float")

# Set vaibale for center
cx = tf.Variable(3, name="cx",dtype=tf.float32)
cy = tf.Variable(3, name="cy",dtype=tf.float32)
  • train_X, train_Y are the x, y coordinates of the three points, here we have selected (3, 7) (6, 9) (9, 7) three points
  • X, Y is the input of the calculation, during the calculation we will use the training data to input X, Y
  • cx, cy is the center point we want to find, the initial value is set to (3, 3), the general learning algorithm will use a random initial value, here I choose a point in the triangle, this will generally reduce iterations frequency.
# Caculate the distance to the center and make them as equal as possible
distance = tf.pow(tf.add(tf.pow((X-cx),2),tf.pow((Y-cy),2)),0.5)
mean = tf.reduce_mean(distance)
cost = tf.reduce_sum(tf.pow((distance-mean),2)/3)
# Gradient descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

These few lines of code are the heart of the algorithm.

  • distance is to use the distance formula of two points to calculate the distance from three points to the center of the circle
  • mean is the mean of the three distances
  • cost is the variance of the three distances. Our goal is to make the distances from the three points to the center of the circle the same, that is, the variance is the smallest (when cx/cy is the center of the circle, the variance is zero)
  • The optimizer is the training function of gradient descent, and the goal is to minimize the cost (variance)

Here is the training process:

# Start training
with tf.Session() as sess:
    sess.run(init)

    # Fit all training data
    for epoch in range(training_epochs):
        sess.run(optimizer, feed_dict={X: train_X, Y: train_Y})
        c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})
        if (c - 0) < 0.0000000001:
            break
        #Display logs per epoch step
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})
            m = sess.run(mean, feed_dict={X: train_X, Y:train_Y})
            print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \
                "CX=", sess.run(cx), "CY=", sess.run(cy), "Mean=", "{:.9f}".format(m)

    print "Optimization Finished!"
    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
    print "Training cost=", training_cost, "CX=", round(sess.run(cx),2), "CY=", round(sess.run(cy),2), "R=", round(m,2), '\n'
  • Initialize the session of tf
  • start iterating
  • Calculate the cost value. When the cost is less than a certain value, the iteration is launched, indicating that we have found the center of the circle.
  • Finally print out the training results

The original title is a point in space, and my example is a point in a plane, but there is no essential difference. You can add a Z-axis data. This question, three-dimensional is actually redundant, can be solved by projecting three points in space onto a plane.

I have implemented another algorithm in JS , but it doesn't always converge. You can take a look at:

Among them, the green three point condition points, the red circle is the final learning result, and the yellow center point is the learning trajectory.

Using this example, what I'm trying to say is:

  • Tensorflow is not just a deep learning tool, it provides powerful data computing capabilities and can be used to solve many mathematical problems
  • The essence of machine learning is to find the answer through a set of data, which is also the role of mathematics, so many mathematical problems can be solved with the idea of ​​machine learning.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324392324&siteId=291194637