You do the self.sess.run(tf.global_variables_initializer()) in the __init__ of your Model class, but only in the train() method do you set up the tf.train.AdamOptimizer(). The latter also creates some variables that need to be initialized. Move the
self.sess.run(tf.global_variables_initializer())
line right after
train = tf.train.AdamOptimizer(0.1).minimize(loss)
and it will work.
Full code (tested):
import tensorflow as tf
import numpy as np
class Model:
def __init__(self,input_neuron=2,hidden_neuron=10,output_neuron=2):
self.input_neuron = input_neuron
self.hidden_neuron = hidden_neuron
self.output_neuron = output_neuron
self.x = tf.placeholder(tf.float32,[None,self.input_neuron])
self.y = tf.placeholder(tf.float32,[None,self.output_neuron])
self.model = self.graph()
self.sess = tf.InteractiveSession()
@staticmethod
def one_hot_encode(y):
y_ = np.zeros((len(y),2))
for i in range(len(y)):
y_[i,y[i][0]]=1
return y_
def graph(self):
w1=tf.Variable(tf.random_normal([self.input_neuron,self.hidden_neuron]))
l1=tf.nn.relu(tf.matmul(self.x,w1))
w2=tf.Variable(tf.random_normal([self.hidden_neuron,self.output_neuron]))
l2=tf.matmul(l1,w2)
return l2
def train(self,xTrain,yTrain):
yTrain = self.one_hot_encode(yTrain)
loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(
logits=self.model,labels=self.y))
train = tf.train.AdamOptimizer(0.1).minimize(loss)
self.sess.run(tf.global_variables_initializer())
for epoch in range(100):
self.sess.run(train,feed_dict={self.x:xTrain,self.y:yTrain})
print("Training done!")
def predict(self,xTest):
prediction = tf.argmax(self.model)
return self.sess.run(prediction,feed_dict={x:xTest})
model = Model()
xTrain = np.array([[0,0],[0,1],[1,0],[1,1]])
yTrain = np.array([[0],[1],[1],[0]])
model.train(xTrain,yTrain)
Based on your comment, if you don't want to re-initialize the whole network at each call of the train() method, then you need to initialize the network at the __init__() method and use tf.report_uninitialized_variables() to get all the uninitialized ones an initialize only those in train(). I wrote the method initialize_uninitialized() to do that, based on this answer to a question by Salvador Dali.
Full code (tested):
import tensorflow as tf
import numpy as np
class Model:
def __init__(self,input_neuron=2,hidden_neuron=10,output_neuron=2):
self.input_neuron = input_neuron
self.hidden_neuron = hidden_neuron
self.output_neuron = output_neuron
self.x = tf.placeholder(tf.float32,[None,self.input_neuron])
self.y = tf.placeholder(tf.float32,[None,self.output_neuron])
self.model = self.graph()
self.sess = tf.InteractiveSession()
self.sess.run(tf.global_variables_initializer())
@staticmethod
def one_hot_encode(y):
y_ = np.zeros((len(y),2))
for i in range(len(y)):
y_[i,y[i][0]]=1
return y_
def graph(self):
w1=tf.Variable(tf.random_normal([self.input_neuron,self.hidden_neuron]))
l1=tf.nn.relu(tf.matmul(self.x,w1))
w2=tf.Variable(tf.random_normal([self.hidden_neuron,self.output_neuron]))
l2=tf.matmul(l1,w2)
return l2
def initialize_uninitialized( self ):
uninitialized_variables = [v for v in tf.global_variables()
if v.name.split(':')[0] in set(self.sess.run(tf.report_uninitialized_variables())) ]
self.sess.run( tf.variables_initializer( uninitialized_variables ) )
def train(self,xTrain,yTrain):
yTrain = self.one_hot_encode(yTrain)
loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits_v2(
logits=self.model,labels=self.y))
train = tf.train.AdamOptimizer(0.1).minimize(loss)
self.initialize_uninitialized()
for epoch in range(100):
self.sess.run(train,feed_dict={self.x:xTrain,self.y:yTrain})
print("Training done!")
def predict(self,xTest):
prediction = tf.argmax(self.model)
return self.sess.run(prediction,feed_dict={x:xTest})
model = Model()
xTrain = np.array([[0,0],[0,1],[1,0],[1,1]])
yTrain = np.array([[0],[1],[1],[0]])
model.train(xTrain,yTrain)