Skip to content

Instantly share code, notes, and snippets.

@JaeDukSeo
Created July 19, 2018 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JaeDukSeo/bbcaacb05fc5894bfbf26bbf2fc4d947 to your computer and use it in GitHub Desktop.
Save JaeDukSeo/bbcaacb05fc5894bfbf26bbf2fc4d947 to your computer and use it in GitHub Desktop.
class SOM_Layer():
def __init__(self,m,n,dim,num_epoch,learning_rate_som ,radius_factor ,gaussian_std):
self.m = m
self.n = n
self.dim = dim
self.gaussian_std = gaussian_std
self.num_epoch = num_epoch
self.map = tf.Variable(tf.random_normal(shape=[m*n,dim],stddev=0.05))
self.location_vects = tf.constant(np.array(list(self._neuron_locations(m, n))))
self.alpha = learning_rate_som
self.sigma = max(m,n)*radius_factor
def _neuron_locations(self, m, n):
"""
Yields one by one the 2-D locations of the individual neurons in the SOM.
"""
# Nested iterations over both dimensions to generate all 2-D locations in the map
for i in range(m):
for j in range(n):
yield np.array([i, j])
def getmap(self): return self.map
def getlocation(self): return self.bmu_locs
def feedforward(self,input):
self.input = input
self.grad_pass = tf.pow(tf.subtract(tf.expand_dims(self.map, axis=0),tf.expand_dims(self.input, axis=1)), 2)
self.squared_distance = tf.reduce_sum(self.grad_pass, 2)
self.bmu_indices = tf.argmin(self.squared_distance, axis=1)
self.bmu_locs = tf.reshape(tf.gather(self.location_vects, self.bmu_indices), [-1, 2])
def backprop(self,iter,num_epoch):
# Update the weigths
radius = tf.subtract(self.sigma,
tf.multiply(iter,
tf.divide(tf.cast(tf.subtract(self.alpha, 1),tf.float32),
tf.cast(tf.subtract(num_epoch, 1),tf.float32))))
alpha = tf.subtract(self.alpha,
tf.multiply(iter,
tf.divide(tf.cast(tf.subtract(self.alpha, 1),tf.float32),
tf.cast(tf.subtract(num_epoch, 1),tf.float32))))
self.bmu_distance_squares = tf.reduce_sum(
tf.pow(tf.subtract(
tf.expand_dims(self.location_vects, axis=0),
tf.expand_dims(self.bmu_locs, axis=1)), 2),
2)
self.neighbourhood_func = tf.exp(tf.divide(tf.negative(tf.cast(
self.bmu_distance_squares, "float32")), tf.multiply(
tf.square(tf.multiply(radius, self.gaussian_std)), 2)))
self.learning_rate_op = tf.multiply(self.neighbourhood_func, alpha)
self.numerator = tf.reduce_sum(
tf.multiply(tf.expand_dims(self.learning_rate_op, axis=-1),
tf.expand_dims(self.input, axis=1)), axis=0)
self.denominator = tf.expand_dims(
tf.reduce_sum(self.learning_rate_op,axis=0) + float(1e-20), axis=-1)
self.new_weights = tf.div(self.numerator, self.denominator)
self.update = [tf.assign(self.map, self.new_weights)]
return self.update,tf.reduce_mean(self.grad_pass,1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment