Substitute model output to binary form - numpy

I've model output like this,
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([0.92, 0.2 , 0.77], dtype=float32)>> but I want to change max value in array to 1, and other values to 0. If there are two and more maximum value it should be changed to zero array.
For example:
[0.92, 0.2 , 0.77] -> [1.0,0.0,0.0],
[0.92, 0.92 , 0.77] -> [0.0,0.0,0.0]
I know how to make it by np.argmax, but I wanna do this by the keras.layers because summarize the outputs after that and want to do it in binary mode?
I've made custom layer like this, but unfortunately can't compile it
class Amplifier(tf.keras.layers.Layer):
def __init__(self):
super(Amplifier, self).__init__()
# pattern 2D matrix
self.f = tf.constant(
[[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]], dtype='float32')
def call(self, inputs, training=None, mask=None):
# return index of max value
x = tf.math.argmax(
inputs,
axis=None,
output_type=tf.dtypes.int32,
name=None)
# get factor from f constant as 1D matrix form
y = tf.reshape(tf.slice(self.f, [x, 0], [1, 3]), [3])
# multiply input on the pattern matrix
return tf.math.multiply(inputs, y)
I got this error:
ValueError: Tried to convert 'begin' to a tensor and failed. Error: Shapes must be equal rank, but are 1 and 0
From merging shape 0 with other shapes. for '{{node amplifier/Slice/packed}} = Pack[N=2, T=DT_INT32, axis=0](amplifier/ArgMax, amplifier/Slice/packed/1)' with input shapes: [3], [].
I don't know how to avoid this mistake

I think what you are asking is if you can have your output be in tf.one_hot format (correct?). If you just want to report on this output, then you can use a combination of argmax and one_hot. If you want this to be part of your gradient calculation in your network, you need a numerically stable one_hot. Try something like this:
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.layers import Dense
class OneHotLayer(layers.Layer):
def __init__(self, num_labels=3, do_numerical=False):
super().__init__()
# large constant used in masking softmax
self._inf = 1e9
# how many categories we have
self.num_labels = num_labels
# if we need our `one_hot` to be numerically stable
self.do_numerical = do_numerical
# dense layer; the last layer of our network
self.probs = Dense(self.num_labels, activation="softmax")
# this is a numerically stable `one_hot` method.
# it looks for the max across rows, subtracts that from
# the original tensor (across rows) and exponentiates.
# this will make the largest value 1.0. Then we create a
# mask and zero out all other values (again, across rows)
# leaving us with a binary matrix.
def _numerical_one_hot(self, x):
m = tf.math.reduce_max(x, axis=1, keepdims=True)
e = tf.math.exp(x - m)
mask = tf.cast(tf.math.not_equal(e, 1.0), tf.float32)
x = x - self._inf * mask
return tf.nn.softmax(x, axis=1)
def call(self, x):
# do forward pass through last layer
x = self.probs(x)
# do we need numerical stability? If we do use the
# op we created. If not, then take the argmax across
# rows and then use `tf.one_hot`; return both
ohx = self._numerical_one_hot(x) \
if self.do_numerical \
else tf.one_hot(tf.math.argmax(x, axis=1), self.num_labels)
return x, ohx
Data:
# fake data
X = tf.random.normal([8, 10])
y = tf.random.uniform(
shape=[8,],
minval=0,
maxval=3,
dtype=tf.int64)
y = tf.one_hot(y, 3)
Test numerical stability network:
# network with stable one_hot
x_in = tf.keras.Input((10,))
x = Dense(25)(x_in)
x_probs, x_indices = OneHotLayer(3, True)(x)
# ^
# ------------------------------------|
# model
model = tf.keras.Model(x_in, [x_probs, x_indices])
probs, idxs = model(X)
# ^^^ this can be used in loss calc if you need it
print(probs)
# tf.Tensor(
# [[0.12873407 0.83047885 0.04078702]
# [0.22919412 0.1288479 0.641958 ]
# [0.27402356 0.35891128 0.36706516]
# [0.1328154 0.3546107 0.51257384]
# [0.5309519 0.10788985 0.36115825]
# [0.35019153 0.272698 0.37711048]
# [0.35740596 0.23807809 0.4045159 ]
# [0.13749316 0.72042704 0.14207976]],
# shape=(8, 3), # dtype=float32)
print(idxs)
# tf.Tensor(
# [[0. 1. 0.]
# [0. 0. 1.]
# [0. 0. 1.]
# [0. 0. 1.]
# [1. 0. 0.]
# [0. 0. 1.]
# [0. 0. 1.]
# [0. 1. 0.]],
# shape=(8, 3), dtype=float32)
Test built-in one-hot network:
# network using argmax and built-in one_hot
x_in = tf.keras.Input((10,))
x = Dense(25)(x_in)
x_probs, x_indices = OneHotLayer(3, False)(x)
# ^
# ------------------------------------|
# model
model = tf.keras.Model(x_in, [x_probs, x_indices])
probs, idxs = model(X)
print(probs)
# tf.Tensor(
# [[0.28931475 0.33777648 0.3729088 ]
# [0.25985113 0.532114 0.20803489]
# [0.4226228 0.21078317 0.36659405]
# [0.460703 0.3534157 0.18588138]
# [0.6028035 0.26571727 0.13147917]
# [0.1994377 0.4208928 0.37966955]
# [0.39812535 0.33319235 0.26868224]
# [0.13242716 0.47491995 0.3926528 ]],
# shape=(8, 3), dtype=float32)
print(idxs)
# tf.Tensor(
# [[0. 0. 1.]
# [0. 1. 0.]
# [1. 0. 0.]
# [1. 0. 0.]
# [1. 0. 0.]
# [0. 1. 0.]
# [1. 0. 0.]
# [0. 1. 0.]],
# shape=(8, 3), dtype=float32)

Related

AttributeError: 'Tensor' object has no attribute 'numpy' in zReLU [duplicate]

This question already has answers here:
AttributeError: 'Tensor' object has no attribute 'numpy'
(9 answers)
Closed 4 months ago.
Here is the code which I want to use in my code but I am getting error ( AttributeError: Exception encountered when calling layer "zReLU1" (type zReLU).
) which I attached in a picture!!! Can anyone help?
def get_angle(self, x):
real = self.get_realpart(x)
imag = self.get_imagpart(x)
comp = tf.complex(real, imag)
ang = tf.math.angle(comp).numpy()
return ang
# T.angle(comp_num)
def call(self, x):
real = self.get_realpart(x)
imag = self.get_imagpart(x)
# mag = self.get_abs(x)
ang = self.get_angle(x) + 0.0001
indices1 = T.nonzero(T.ge(ang, pi / 2))
indices2 = T.nonzero(T.le(ang, 0))
real = T.set_subtensor(real[indices1], 0)
imag = T.set_subtensor(imag[indices1], 0)
real = T.set_subtensor(real[indices2], 0)
imag = T.set_subtensor(imag[indices2], 0)
act = K.concatenate([real, imag], axis=1)
return act
def compute_output_shape(self, input_shape):
return input_shape
enter image description here
You can convert conjugate numbers to radius degrees and extract magnitude and imagination for longitude references.
Sample : The glob is round shape, peeling orange in the same way you locate the pieces of juices without a renewable all process.
import tensorflow as tf
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
None
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
physical_devices = tf.config.experimental.list_physical_devices('GPU')
assert len(physical_devices) > 0, "Not enough GPU hardware devices available"
config = tf.config.experimental.set_memory_growth(physical_devices[0], True)
print(physical_devices)
print(config)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Variables
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
global real
real = tf.linspace([0., 5.], [10., 40.], 5, axis=-1)
imag = tf.linspace([0., 5.], [10., 40.], 5, axis=-1)
### Create complex number matrix ###
complex_number = tf.dtypes.complex(
real, imag, name="Complex number"
)
print( "complex_number: " )
print( complex_number )
### Convert conjugate into degree radious ###
ang = tf.math.angle( complex_number ).numpy()
print( "ang: " )
print( ang )
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
def get_angle( matrix ):
### -------------------------------------------- ###
### -X------------------------------------------ ###
### --X----------------------------------------- ###
### ---X---------------------------------------- ###
### ----X--------------------------------------- ###
### -------------------------------------------- ###
real_matrix = tf.linspace([0., 0.], [0., 0.], 5, axis=-1)
imag_matrix = tf.linspace([-1., -1.], [-1., -1.], 5, axis=-1)
reverse_conjugate = tf.dtypes.complex(
real_matrix, imag_matrix, name="Reverse_conjugate"
)
print( "reverse_conjugate: " )
print( reverse_conjugate )
angle_matrix = tf.math.multiply(
reverse_conjugate, matrix , name="magnitude matrix"
)
print( "angle_matrix: " )
print( angle_matrix )
print( "magnitude_matrix: " )
print( tf.math.add( angle_matrix, matrix ) )
return
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Working
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
get_angle( complex_number )
Output:
tf.Tensor(
[[ 0. +0.j 2.5 +2.5j 5. +5.j 7.5 +7.5j 10. +10.j ]
[ 5. +5.j 13.75+13.75j 22.5 +22.5j 31.25+31.25j 40. +40.j ]], shape=(2, 5), dtype=complex64)
ang:
[[0. 0.7853982 0.7853982 0.7853982 0.7853982]
[0.7853982 0.7853982 0.7853982 0.7853982 0.7853982]]
reverse_conjugate:
tf.Tensor(
[[0.-1.j 0.-1.j 0.-1.j 0.-1.j 0.-1.j]
[0.-1.j 0.-1.j 0.-1.j 0.-1.j 0.-1.j]], shape=(2, 5), dtype=complex64)
angle_matrix:
tf.Tensor(
[[ 0. +0.j 2.5 -2.5j 5. -5.j 7.5 -7.5j 10. -10.j ]
[ 5. -5.j 13.75-13.75j 22.5 -22.5j 31.25-31.25j 40. -40.j ]], shape=(2, 5), dtype=complex64)
magnitude_matrix:
tf.Tensor(
[[ 0. +0.j 5. +0.j 10. +0.j 15. +0.j 20. +0.j]
[10. +0.j 27.5+0.j 45. +0.j 62.5+0.j 80. +0.j]], shape=(2, 5), dtype=complex64)

batch axis in keras custom layer

I want to make a custom layer that does the following, given a batch of input vectors.
For each vector a in the batch:
get the first element a[0].
multiply the vector a by a[0] elementwise.
So if the batch is
[[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]]
This should be a batch of 4 vectors, each with dimension 3 (or am I wrong here?).
Then my layer should transform the batch to the following:
[[ 1., 2., 3.],
[ 16., 20., 24.],
[ 49., 56., 63.],
[100., 110., 120.]]
Here is my implementation for the layer:
class MyLayer(keras.layers.Layer):
def __init__(self, activation=None, **kwargs):
super().__init__(**kwargs)
self.activation = keras.activations.get(activation)
def call(self, a):
scale = a[0]
return self.activation(a * scale)
def get_config(self):
base_config = super().get_config()
return {**base_config,
"activation": keras.activations.serialize(self.activation)}
But the output is different from what I expected:
batch = tf.Variable([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]], dtype=tf.float32)
layer = MyLayer()
print(layer(batch))
Output:
tf.Tensor(
[[ 1. 4. 9.]
[ 4. 10. 18.]
[ 7. 16. 27.]
[10. 22. 36.]], shape=(4, 3), dtype=float32)
It looks like the implementation actually treats each column as a vector, which is strange to me because other pre-written models, such as the sequential model, specify the input shape to be (batch_size, ...), which means each row, instead of column, is a vector.
How should I modify my code so that it behaves the way I want?
Actually, your input shape is (4,3). So when you slice this tensor by a[0] it gets the first row which is [1,2,3]. To get what you want you should instead get the first column and then transpose your matrix to give you the desired matrix like this:
def call(self, a):
scale = a[:,0]
return tf.transpose(self.activation(tf.transpose(a) * scale))

How does a process of optimization go with tensorflow?

I have simple graph in tensorflow
(1) X = tf.Variable(dtype=tf.float32, shape=(1, 3), name="X", initial_value=np.array([[1,2,3]]))
(2) y = tf.reduce_sum(tf.square(X)) - 2 * tf.reduce_sum(tf.sin(tf.square(X)))
(3) training_op = tf.train.GradientDescentOptimizer(0.3).minimize(y)
Here's the code for 5 steps of gradient descent:
with tf.Session() as sess:
sess.run(init)
for i in range(5):
(4) *res, _ = sess.run(fetches=[X, y, training_op])
print(res)
[array([[1., 2., 3.]], dtype=float32), 13.006426]
[array([[ 1.0483627 , -0.76874477, -2.080069 ]], dtype=float32), 4.9738936]
[array([[ 0.9910337 , -1.0735381 , 0.10702228]], dtype=float32), -1.3677568]
[array([[ 1.0567244 , -0.95272505, 0.17122723]], dtype=float32), -1.3784065]
[array([[ 0.978967 , -1.0848547 , 0.27387527]], dtype=float32), -1.4229481]
I'm trying to figure out how its optimization process goes. Could you please explain it step by step?
I thought it should be like this:
Evaluate X (1)
Evaluate y (2)
Calculate gradient and make a step (3) (as here it says "Calling minimize() takes care of both computing the gradients and applying them to the variables."
Then yield all requested in fetches variables (4)
But the output shows that at first run yields initial values, so I'm confused...
tf version == '1.15.0'
Thank you in advance!
upd1. If I change the order in fetches list, the output is still the same.
with tf.Session() as sess:
sess.run(init)
for i in range(5):
_, *res = sess.run(fetches=[training_op, X, y])
print(res)
[array([[1., 2., 3.]], dtype=float32), 13.006426]
[array([[ 1.0483627 , -0.76874477, -2.080069 ]], dtype=float32), 4.9738936]
[array([[ 0.9910337 , -1.0735381 , 0.10702228]], dtype=float32), -1.3677568]
[array([[ 1.0567244 , -0.95272505, 0.17122723]], dtype=float32), -1.3784065]
[array([[ 0.978967 , -1.0848547 , 0.27387527]], dtype=float32), -1.4229481]
upd2. A slight modification of the answer by #thushv89 does what I initially expected to see:
with tf.Session() as sess:
sess.run(init)
for i in range(2):
res = sess.run(fetches=[X, y])
print('Variables before the step', res)
sess.run(training_op)
res = sess.run(fetches=[X, y])
print('Variables after the step', res)
print()
Variables before the step [array([[1., 2., 3.]], dtype=float32), 13.006426]
Variables after the step [array([[ 1.0483627 , -0.76874477, -2.080069 ]], dtype=float32), 4.9738936]
Variables before the step [array([[ 1.0483627 , -0.76874477, -2.080069 ]], dtype=float32), 4.9738936]
Variables after the step [array([[ 0.9910337 , -1.0735381 , 0.10702228]], dtype=float32), -1.3677568]
You have fetches=[X, y, training_op]. These don't respect the order (At least you shouldn't expect sess.run() to respect the order). Which means, all of the,
Evaluates X (so the training_op hasn't happened yet)
Evaluate y (still the training_op hasn't happened yet)
Executes training_op (now, X and y have changed).
gets executed and then the results are fetched. If you want the variable X to change first,
Option 1: Breaking the sess.run() function
r1 = sess.run(X)
_, r2 = sess.run(fetches=[training_op, y])
print(r1,r2)
Option 2: Using a separate tf.Variable with tf.control_dependencies
X = tf.Variable(dtype=tf.float32, shape=(1, 3), name="X", initial_value=np.array([[1,2,3]]))
prevX = tf.Variable(dtype=tf.float32, shape=(1, 3), name="prevX", initial_value=np.array([[1,2,3]]))
y = tf.reduce_sum(tf.square(X)) - 2 * tf.reduce_sum(tf.sin(tf.square(X)))
assign_op = tf.assign(prevX, X)
with tf.control_dependencies([assign_op]):
training_op = tf.train.GradientDescentOptimizer(0.3).minimize(y)
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
for i in range(5):
*res, _ = sess.run(fetches=[prevX, y, training_op])
print(res)

How to align shape of a tensor returned by an iterator with a tensorflow variable

This is probably a very simple question, however I am fairly new to tensorflow and have been stuck at this issue. I use tensorflow 1.12 and python 3.
My question is, what is the proper way to set the shape of a tensor object that is returned by the iterator?
With placeholders I can make make something like this code work, but I would like to make this work without a placeholder and using tensorflow datasets.
I cannot figure out how to align the shape of a tensor with a matrix in order to use tf.matmul.
The error I receive is: ValueError: Shape must be rank 2 but is rank 1 for 'MatMul_19' (op: 'MatMul') with input shapes: [2], [2,1].
The dataset of the iterator is specified as: TensorSliceDataset shapes: (2,), types: tf.float32>.
Thanks in advance!
import tensorflow as tf
import numpy as np
batch_size = 200
# this simulates a dataset read from a csv.....
x=np.array([[0., 0.], [1., 0.], [0., 1.], [1., 1.]],dtype="float32")
y=np.array([0, 0, 0, 1],dtype="float32")
dataset = tf.data.Dataset.from_tensor_slices((x))
print(dataset) # <TensorSliceDataset shapes: (2,), types: tf.float32>
dataset = dataset.repeat(10000)
print('repeat ds ', dataset) # repeat ds <RepeatDataset shapes: (2,), types: tf.float32>
iter = dataset.make_initializable_iterator()
print('iterator ', iter) # iterator <tensorflow.python.data.ops.iterator_ops.Iterator object at 0x0000028589C62550>
sess = tf.Session()
sess.run(iter.initializer)
next_elt= iter.get_next()
print('shape of dataset ', dataset , '[iterator] elt ', next_elt) # shape of dataset <RepeatDataset shapes: (2,), types: tf.float32> [iterator] elt Tensor("IteratorGetNext_105:0", shape=(2,), dtype=float32)
print('shape of it ', next_elt.shape) #s hape of it (2,)
for i in range(4):
print(sess.run(next_elt))
''' outputs:
[0. 0.]
[1. 0.]
[0. 1.]
[1. 1.]
'''
w = tf.Variable(tf.random_uniform([2,1], -1, 1, seed = 1234),name="weights_layer_1")
# this is where the error is because of shape mismatch of iterator and w variable.
# How od I make the shape of the iterator (2,1) so that matmul can be used?
# What is the proper way of aligning a tensor shape with inut data
# The output of the error:
# ValueError: Shape must be rank 2 but is rank 1 for 'MatMul_19' (op: 'MatMul') with input shapes: [2], [2,1].
H = tf.matmul( sess.run(next_elt) , w)
You can use tf.reshape. Just add tf.reshape(next_elt, [1,2]) prior to matmul op
More on reshape https://www.tensorflow.org/api_docs/python/tf/reshape

tensorflow simple estimator input function problems

I am trying to create a simple input function with the feature data being the numbers 1-10 and the labels being 0 when x < 5; 5 when x = 5 and 10 when x > 5.
example:
# data
nmbrs = [10., 1., 2., 3., 4., 5., 6. , 7., 8., 9.]
labels = [10., 0., 0., 0., 0., 5., 10., 10., 10., 10.]
# input function
input_fn = tf.estimator.inputs.numpy_input_fn(
x={'numbers': np.array(nmbrs)}, y=np.array(labels),
batch_size=batch_size, num_epochs=None, shuffle=True)
The problem i am having is that the nmbrs and labels array doesnt seem to be in the right form, i tried making it into a 2d array but that didnt work either im sure im doing something really easy wrong here...
EDIT: model and neural net functions
def neural_net(x_dict):
# TF Estimator input is a dict, in case of multiple inputs
x = x_dict['numbers']
# Hidden fully connected layer with 128 neurons
layer_1 = tf.layers.dense(x, n_hidden_1)
# Hidden fully connected layer with 128 neurons
layer_2 = tf.layers.dense(layer_1, n_hidden_2)
# Output fully connected layer with a neuron for each class
out_layer = tf.layers.dense(layer_2, num_classes)
return out_layer
# Define the model function (following TF Estimator Template)
def model_fn(features, labels, mode):
# Build the neural network
logits = neural_net(features)
# Predictions
pred_classes = tf.argmax(logits, axis=1)
pred_probas = tf.nn.softmax(logits)
# If prediction mode, early return
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode, predictions=pred_classes)
# Define loss and optimizer
loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
logits=logits, labels=tf.cast(labels, dtype=tf.int32)))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
train_op = optimizer.minimize(loss_op, global_step=tf.train.get_global_step())