TensorFlow in NetLogo, Make Your Agent More Intelligent

0. Background

NetLogo is a very useful tools for ABM, and Python is also a handful language for building proof of concept.

In this post I will show you how to call python language in NetLogo. For more information please follow here.

1. NetLogo version

breed [data-points data-point]
breed [centroids centroid]

globals [
  any-centroids-moved?
]

to setup
  clear-all
  set-default-shape data-points "circle"
  set-default-shape centroids "x"
  generate-clusters
  reset-centroids
end

to generate-clusters
  let cluster-std-dev 20 - num-clusters
  let cluster-size num-data-points / num-clusters
  repeat num-clusters [
    let center-x random-xcor / 1.5
    let center-y random-ycor / 1.5
    create-data-points cluster-size [
      setxy center-x center-y
      set heading random 360
      fd abs random-normal 0 (cluster-std-dev / 2) ;; Divide by two because abs doubles the width
    ]
  ]
end

to reset-centroids
  set any-centroids-moved? true
  ask data-points [ set color grey ]

  let colors base-colors
  ask centroids [die]
  create-centroids num-centroids [
    move-to one-of data-points
    set size 5
    set color last colors + 1
    set colors butlast colors
  ]
  clear-all-plots
  reset-ticks
end

to go
  if not any-centroids-moved? [stop]
  set any-centroids-moved? false
  assign-clusters
  update-clusters
  tick
end

to assign-clusters
  ask data-points [set color [color] of closest-centroid - 2]
end

to update-clusters
  let movement-threshold 0.1
  ask centroids [
    let my-points data-points with [ shade-of? color [ color ] of myself ]
    if any? my-points [
      let new-xcor mean [ xcor ] of my-points
      let new-ycor mean [ ycor ] of my-points
      if distancexy new-xcor new-ycor > movement-threshold [
        set any-centroids-moved? true
      ]
      setxy new-xcor new-ycor
    ]
  ]
  update-plots
end

to-report closest-centroid
  report min-one-of centroids [ distance myself ]
end

to-report square-deviation
  report sum [ (distance myself) ^ 2 ] of data-points with [ closest-centroid = myself ]
end


; Copyright 2014 Uri Wilensky.
; See Info tab for full copyright and license.

 

2. TensorFlow version

TensorFlow version: 1.14

import numpy as np
import tensorflow as tf

num_points = 100
dimensions = 2
points = np.random.uniform(0, 1000, [num_points, dimensions])

def input_fn():
  return tf.compat.v1.train.limit_epochs(
      tf.convert_to_tensor(points, dtype=tf.float32), num_epochs=1)

num_clusters = 5
kmeans = tf.contrib.factorization.KMeansClustering(
    num_clusters=num_clusters, use_mini_batch=False)

# train
num_iterations = 10
previous_centers = None
for _ in xrange(num_iterations):
  kmeans.train(input_fn)
  cluster_centers = kmeans.cluster_centers()
  if previous_centers is not None:
    print 'delta:', cluster_centers - previous_centers
  previous_centers = cluster_centers
  print 'score:', kmeans.score(input_fn)
print 'cluster centers:', cluster_centers

# map the input points to their clusters
cluster_indices = list(kmeans.predict_cluster_index(input_fn))
for i, point in enumerate(points):
  cluster_index = cluster_indices[i]
  center = cluster_centers[cluster_index]
  print 'point:', point, 'is in cluster', cluster_index, 'centered at', center

 

3. NetLogo with Python Extension version

Here’s the snapshot.

And here’s the code.

extensions [ py ]

breed [data-points data-point]
breed [centroids centroid]

data-points-own [
  cluster-id
]

centroids-own [
  cluster-id
  centx
  centy
]

globals [
  testoutput
  centroid-list
]

to setup
  clear-all
  py:setup py:python
  (py:run
    "import tensorflow as tf"
    "import numpy as np"
  )
  set testoutput py:runresult "1"
  py:set "testoutput" testoutput
  set-default-shape data-points "circle"
  set-default-shape centroids "x"
  generate-clusters
  ; For python
  py:set "num_points" num-clusters
  py:set "points" [list xcor ycor] of data-points
  py:set "num_clusters" num-clusters
  py:set "num_round" num-round
  if debug = True
  [
    py:run "print('Points Cordinates:', points)" ;for debug
  ]
  ;reset-centroids
end

to generate-clusters
  set testoutput py:runresult "testoutput + 1"
  let cluster-std-dev cluster-range
  let cluster-size num-data-points / num-clusters
  repeat num-clusters [
    let center-x random-xcor / 1.5
    let center-y random-ycor / 1.5
    create-data-points cluster-size [
      setxy center-x center-y
      set heading random 360
      fd abs random-normal 0 (cluster-std-dev / 2)
    ]
  ]
end

to train
  ; Cluster center
  (py:run
    "points = np.asarray(points)"
    "def input_fn():"
    "    return tf.compat.v1.train.limit_epochs(tf.convert_to_tensor(points, dtype=tf.float32), num_epochs=1)"
    "kmeans = tf.contrib.factorization.KMeansClustering(num_clusters=num_clusters, use_mini_batch=False)"
    "num_iterations = num_round"
    "previous_centers = None"
    "for _ in range(num_iterations):"
    "    kmeans.train(input_fn)"
    "    cluster_centers = kmeans.cluster_centers()"
    "    if previous_centers is not None:"
    "        print(('delta:', cluster_centers - previous_centers))"
    "    previous_centers = cluster_centers"
    "    print(('score:', kmeans.score(input_fn)))"
    "print(('cluster centers:', cluster_centers))"
    "# map the input points to their clusters"
    "cluster_indices = list(kmeans.predict_cluster_index(input_fn))"
    "print('cluster indices: ', cluster_indices)"
    "for i, point in enumerate(points):"
    "    cluster_index = cluster_indices[i]"
    "    center = cluster_centers[cluster_index]"
    "    print(('point:', point, 'is in cluster', cluster_index, 'centered at', center))"
  )
end

to show-shape
  set centroid-list py:runresult "cluster_centers"
  foreach centroid-list [
    x -> create-centroids 1 [
      set xcor ( item 0 x )
      set ycor ( item 1 x )
      set size 3
      set color white
    ]
  ]
end

 

Ref:

[1] https://www.altoros.com/blog/using-k-means-clustering-in-tensorflow/

[2] https://www.tensorflow.org/api_docs/python/tf/contrib/factorization/KMeansClustering

发表评论

您的电子邮箱地址不会被公开。