0

I have to build a classifier that takes the input of shape: [batch, frames, height, width, channel]. Here number of frames will vary and rest all the dimensions are fixed.

Here's my network:

height = 90
width = 120
channel = 3
num_classes = 20
batch = 2

def my_model(frames, data, label):
    XR = tf.reshape(data, [batch, frames, height*width*channel])
    h = rnn_layer(XR)
    print("h: ", h)
    prediction = Dense(output_dim=num_classes, activation='softmax', kernel_regularizer=l2(alpha))(h)
    print("logits: ", prediction)
    with tf.name_scope('Loss'):
        cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=label))
        print("cost: ", cost)
    with tf.name_scope('Optimizer'):
        optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)
        train_op = optimizer.minimize(cost)
        print("train_op: ", train_op)
    with tf.name_scope('Accuracy'):
        # Test model
        correct_prediction = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
        # Calculate accuracy
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))
    return accuracy

You can just ignore rnn_layer(), Dense() and its arguments because they are implementation of RNN and fully connected layers and works fine.

with tf.Session() as sess:  
    with tf.variable_scope("frames_1") as scope:
        tf.global_variables_initializer().run()
        frames = 2
        X = tf.placeholder('float', [None, frames, height, width, channel], name='InputData')
        Y = tf.placeholder('float', [None, num_classes], name='LabelData')
        input_data, label_data = video_frames_5d_train[0:batch, 0:frames], category_label_train_one_not[0:batch]
        result = my_model(frames, X, Y)
        print("result frames_1: ", result)
        scope.reuse_variables()
        acc = sess.run(result, feed_dict={X: input_data, Y: label_data})
        print("Accuracy: ", acc)

    with tf.variable_scope("frames_2", reuse=tf.AUTO_REUSE):
        frames = 5
        X = tf.placeholder(tf.float32, [None, frames, height, width, channel], name='InputData')
        Y = tf.placeholder(tf.float32, [None, num_classes], name='LabelData')
        input_data, label_data = video_frames_5d_train[0:batch, 0:frames], category_label_train_one_not[0:batch]
        result = my_model(frames, X, Y)
        print("result frames_2: ", result)
        acc = sess.run(result, feed_dict={X: input_data, Y: label_data})
        print("Accuracy: ", acc)

In the above code, value of frames vary and rest is same. I want to optimize both frames and calculate accuracy separately for them, so I am using variable score. Here video_frames_5d_train contains the data.

Here's what is printed, when I execute it:

h:  Tensor("frames_1/tt_lstm_1/TensorArrayReadV3:0", shape=(2, 625), dtype=float32)
logits:  Tensor("frames_1/dense_1/Softmax:0", shape=(2, 20), dtype=float32)
cost:  Tensor("frames_1/Loss/Mean:0", shape=(), dtype=float32)
c:\anaconda2\envs\py3\lib\site-packages\ipykernel_launcher.py:26: UserWarning: Update your `Dense` call to the Keras 2 API: `Dense(units=20, activation="softmax", kernel_regularizer=<keras.reg...)`
train_op:  name: "frames_1/Optimizer/Adam"
op: "NoOp"
input: "^frames_1/Optimizer/Adam/update_frames_1/tt_lstm_1/kernel/ApplyAdam"
input: "^frames_1/Optimizer/Adam/update_frames_1/tt_lstm_1/bias/ApplyAdam"
input: "^frames_1/Optimizer/Adam/update_frames_1/tt_lstm_1/recurrent_kernel/ApplyAdam"
input: "^frames_1/Optimizer/Adam/update_frames_1/dense_1/kernel/ApplyAdam"
input: "^frames_1/Optimizer/Adam/update_frames_1/dense_1/bias/ApplyAdam"
input: "^frames_1/Optimizer/Adam/Assign"
input: "^frames_1/Optimizer/Adam/Assign_1"

result frames_1:  Tensor("frames_1/Accuracy/Mean:0", shape=(), dtype=float32)

So, it execute till print("result frames_1: ", result) successfully, but then I get error:

FailedPreconditionError: Attempting to use uninitialized value frames_1/dense_1/kernel
     [[Node: frames_1/dense_1/kernel/read = Identity[T=DT_FLOAT, _class=["loc:@frames_1/dense_1/kernel"], _device="/job:localhost/replica:0/task:0/device:GPU:0"](frames_1/dense_1/kernel)]]
     [[Node: frames_1/Accuracy/Mean/_13 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_317_frames_1/Accuracy/Mean", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

In the end, I want to create one model for different input sizes and optimize them and keep track of accuracy separately. Is there a way to do it?

Thanks

Beginner
  • 1,202
  • 2
  • 20
  • 29
  • 1
    2 Things: 1. It seems like you're using initialized variables. it might happen because you didn't run the variables initializer in the right place. 2. Different input size - please see the following question and let us know if that's what you meant: https://stackoverflow.com/questions/47479587/how-to-feed-input-with-changing-size-in-tensorflow/47896185#47896185 – Matan Hugi Feb 14 '18 at 20:17
  • Related question - https://stackoverflow.com/q/48230031/712995 – Maxim Feb 14 '18 at 20:31
  • @MatanHugi, I am able to define the model for variable size in `my_model` function under separate variable scope. But, when I pass the values of input and label in the model: `acc = sess.run(result, feed_dict={X: input_data, Y: label_data})`, I got that error. Where should I initialize the variable? I just want to be able to return value of `accuracy` from the model. – Beginner Feb 15 '18 at 04:01
  • 1
    You should initialize your variables after you finished declaring all of them. In your code, I'd suggest initializing them twice - before every call to sess.run() – Matan Hugi Feb 15 '18 at 07:05

0 Answers0