[ ] (Self-orginizing map) TensorFlow |
import numpy as np
import tensorflow as tf
class SOMNetwork():
def __init__(self, input_dim, dim=10, sigma=None, learning_rate=0.1, tay2=1000, dtype=tf.float32):
#
if not sigma:
sigma = dim / 2
self.dtype = dtype
#
self.dim = tf.constant(dim, dtype=tf.int64)
self.learning_rate = tf.constant(learning_rate, dtype=dtype, name='learning_rate')
self.sigma = tf.constant(sigma, dtype=dtype, name='sigma')
# 1 ( 6)
self.tay1 = tf.constant(1000/np.log(sigma), dtype=dtype, name='tay1')
# 1000 ( 3)
self.minsigma = tf.constant(sigma * np.exp(-1000/(1000/np.log(sigma))), dtype=dtype, name='min_sigma')
self.tay2 = tf.constant(tay2, dtype=dtype, name='tay2')
#input vector
self.x = tf.placeholder(shape=[input_dim], dtype=dtype, name='input')
#iteration number
self.n = tf.placeholder(dtype=dtype, name='iteration')
#
self.w = tf.Variable(tf.random_uniform([dim*dim, input_dim], minval=-1, maxval=1, dtype=dtype),
dtype=dtype, name='weights')
# ,
self.positions = tf.where(tf.fill([dim, dim], True))
def __competition(self, info=''):
with tf.name_scope(info+'competition') as scope:
#
distance = tf.sqrt(tf.reduce_sum(tf.square(self.x - self.w), axis=1))
# ( 1)
return tf.argmin(distance, axis=0)
def training_op(self):
#
win_index = self.__competition('train_')
with tf.name_scope('cooperation') as scope:
# d
# 1d 2d
coop_dist = tf.sqrt(tf.reduce_sum(tf.square(tf.cast(self.positions -
[win_index//self.dim, win_index-win_index//self.dim*self.dim],
dtype=self.dtype)), axis=1))
# ( 3)
sigma = tf.cond(self.n > 1000, lambda: self.minsigma, lambda: self.sigma * tf.exp(-self.n/self.tay1))
# ( 2)
tnh = tf.exp(-tf.square(coop_dist) / (2 * tf.square(sigma)))
with tf.name_scope('adaptation') as scope:
# ( 5)
lr = self.learning_rate * tf.exp(-self.n/self.tay2)
minlr = tf.constant(0.01, dtype=self.dtype, name='min_learning_rate')
lr = tf.cond(lr <= minlr, lambda: minlr, lambda: lr)
# ( 4)
delta = tf.transpose(lr * tnh * tf.transpose(self.x - self.w))
training_op = tf.assign(self.w, self.w + delta)
return training_op
# 2020
som = SOMNetwork(input_dim=3, dim=20, dtype=tf.float64, sigma=3)
test_data = np.random.uniform(0, 1, (250000, 3))
training_op = som.training_op()
init = tf.global_variables_initializer()
with tf.Session() as sess:
init.run()
for i, color_data in enumerate(test_data):
if i % 1000 == 0:
print('iter:', i)
sess.run(training_op, feed_dict={som.x: color_data, som.n:i})