convert keras input to numpy array - python

Tensor("flatten_3/Identity:0", shape=(None, 100), dtype=float32)
Hi I have tried to print tensor as numpy array as follows:
import tensorflow as tf
import numpy as np
from keras.layers import Input
print(tf.executing_eagerly())
x = Input(shape=(32,))
print(x.numpy())

To be honest I'm sure there is a cleaner way to visualize your input tensor, but here's a hacky one for what it's worth:
import tensorflow as tf
def tf_print(x):
tf.print("my tensor:")
tf.print(x)
return x
iput = tf.keras.layers.Input(shape=(1,), dtype='int32')
printt = tf.keras.layers.Lambda(tf_print)(iput) # branch that prints your tensor
oput = tf.keras.layers.Flatten()(iput) # branch that is the rest of your model
model = tf.keras.Model(inputs=[iput], outputs=[oput, printt])
model(4)

Related

Keras FFT layer has no effect

Hi i'm trying to implement an FFT in my model. I isolated the fft layer to better see the effect, but when I call my model on any data it returns the input, unaffected.
Here's my code with sample data:
import matplotlib.pyplot as plt
from keras.layers import Input, Lambda
from keras.models import Model
import tensorflow as tf
import numpy as np
def fftModel1D(input_shape):
x_input = Input(input_shape)
x = Lambda(lambda v: tf.cast(tf.spectral.fft(tf.cast(v,dtype=tf.complex64)),tf.float32))(x_input)
return Model(inputs=x_input, outputs=[x])
model = fftModel1D((1000, 1))
testData = np.asarray([np.expand_dims(np.sin(np.linspace(0, 100, 1000)), 1)])
pred = model.predict(testData)[0]
fig, axes = plt.subplots(1, 2)
axes[0].plot(np.squeeze(testData))
axes[1].plot(np.squeeze(pred))
plt.show()
This currently shows identical plots of sin(x) while I'm expecting the FFT on the second graph.
I'm using Python 3.6.8, Keras 2.2.4, Tensorflow 1.13.1
Since the input has 2 dimensions (shape is (1000, 1)), using tf.fft2D seems to work.

Keras functional API and TensorFlow Hub

I'm trying to use a Universal Sentence Encoder from TF Hub as a keras layer in a functional way. I would like to use hub.KerasLayer with Keras Functional API, but i'm not sure how to achieve that, so far I've only seen exmaples of hub.KerasLayer with the Sequential API
import tensorflow_hub as hub
import tensorflow as tf
from tensorflow.keras import layers
import tf_sentencepiece
use_url = 'https://tfhub.dev/google/universal-sentence-encoder-multilingual-large/1'
english_sentences = ["dog", "Puppies are nice.", "I enjoy taking long walks along the beach with my dog."]
english_sentences = np.array(english_sentences, dtype=object)[:, np.newaxis]
seq = layers.Input(shape=(None, ), name='sentence', dtype=tf.string)
module = hub.KerasLayer(hub.Module(use_url))(seq)
model = tf.keras.models.Model(inputs=[seq], outputs=[module])
model.summary()
x = model.predict(english_sentences)
print(x)
the code above runs into this error when passing the input layer to the embedding: TypeError: Can't convert 'inputs': Shape TensorShape([Dimension(None), Dimension(None)]) is incompatible with TensorShape([Dimension(None)])
Is it possible to use hub.KerasLayer with keras functional API in TensorFlow 1.x? if it can be done, how?
Try This
sentence_encoding_layer = hub.KerasLayer("https://tfhub.dev/google/universal-sentence-encoder/4",
trainable=False,
input_shape = [],
dtype = tf.string,
name = 'U.S.E')
inputs = tf.keras.layers.Input(shape = (), dtype = 'string',name = 'input_layer')
x = sentence_encoding_layer(inputs)
x = tf.keras.layers.Dense(64,activation = 'relu')(x)
outputs = tf.keras.layers.Dense(1,activation = 'sigmoid',name = 'output_layer')(x)
model = tf.keras.Model(inputs,outputs,name = 'Transfer_learning_USE')
model.summary()
model.predict([sentence])
If you use v3 of the same universal sentence encoder with tf 1.15, you can do such thing by replacing lines from
import tf_sentencepiece
use_url = 'https://tfhub.dev/google/universal-sentence-encoder-multilingual-large/1'
module = hub.KerasLayer(hub.Module(use_url))(seq)
to
import tensorflow_text
use_url = 'https://tfhub.dev/google/universal-sentence-encoder-multilingual-large/3'
module = hub.KerasLayer(use_url)(seq)
First shape is what you are passing into the model, Shape TensorShape([Dimension(None), Dimension(None)]). Second shape is what you are expecting, TensorShape([Dimension(None)]). So in this error, its telling you it expecting a shape of ()...
Or
If you are expecting to do batches of text, perhaps do TimeDistributed layer, like so...
module = tf.keras.layers.TimeDistributed(hub.KerasLayer(hub.Module(use_url)))(seq)
However you maybe forced to do specific size for text length...

How to apply dropout to the outputs of an RNN in TensorFlow Eager using the Keras API?

I would like to apply dropout to the outputs from an RNN. For example, in Tensorflow 1.8.0, I could do this:
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tfe.enable_eager_execution()
x = tf.random_uniform((10, 5, 3))
gru_cell1 = tf.contrib.rnn.GRUCell(2)
gru_cell1 = tf.contrib.rnn.DropoutWrapper(gru_cell1, output_keep_prob=0.5)
cell = tf.contrib.rnn.MultiRNNCell([gru_cell1])
init_state = cell.zero_state(10, tf.float32)
cell_output, _ = tf.nn.dynamic_rnn(cell, x,
initial_state=init_state, time_major=False)
cell_output
How can I achieve the same thing using the Keras API?
I have thought of the following two ways but they were unsuccessful:
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tfe.enable_eager_execution()
# Attempt 1
x = tf.random_uniform((10, 5, 3))
gru_layer = tf.keras.layers.GRU(2, return_sequences=True, input_shape=(10, 5, 3))
gru_layer = tf.keras.layers.Dropout(0.5)(gru_layer)
# Gives the following error:
# ValueError: Attempt to convert a value (<tensorflow.python.keras._impl.keras.layers.recurrent.GRU object
# at 0x000001C520681F60>) with an unsupported type (<class 'tensorflow.python.keras._impl.keras.layers.recurrent.GRU'>)
# to a Tensor.
# Attempt 2
x = tf.random_uniform((10, 5, 3))
gru_layer = tf.keras.layers.GRU(2, return_sequences=True, input_shape=(10, 5, 3))
gru_layer = tf.keras.layers.TimeDistributed(tf.keras.layers.Dropout(0.4))(gru_layer)
# Gives the following error:
# ValueError: as_list() is not defined on an unknown TensorShape.
To get the model output, without training, like you're doing in the TF code, the following code should work. Indeed, you need an Input layer, and to hook each layer to the previous one, and a Model as well:
import numpy as np
from keras.models import Model
from keras.layers import Dropout, GRU, Input
x = np.random.randn(10, 5, 3)
inputs = Input(shape=(5, 3))
gru_layer = GRU(2, return_sequences=True)(inputs)
gru_layer = Dropout(0.5)(gru_layer)
model = Model(inputs=inputs, outputs=gru_layer)
output = model.predict(x)

Wrap tensorflow function in keras layer

i'm trying to use the tensorflow unique function (https://www.tensorflow.org/api_docs/python/tf/unique) in a keras lambda layer.
Code below:
def unique_idx(x):
output = tf.unique(x)
return output[1]
then
inp1 = Input(batch_shape(None, 1))
idx = Lambda(unique_idx)(inp1)
model = Model(inputs=inp1, outputs=idx)
when I now use **model.compile(optimizer='Adam', loss='mean_squared_error')**
I get the error:
ValueError: Tensor conversion requested dtype int32 for Tensor with
dtype float32: 'Tensor("lambda_9_sample_weights_1:0", shape=(?,),
dtype=float32)'
Does anybody know whats the error here or a different way of using the tensorflow function?
A keras model expects a float32 as output, but the indices returned from tf.unique is a int32. A casting fixes your problem.
Another issue is that unique expects a flatten array. reshape fixes this one.
import tensorflow as tf
from keras import Input
from keras.layers import Lambda
from keras.engine import Model
def unique_idx(x):
x = tf.reshape(x, [-1])
u, indices = tf.unique(x)
return tf.cast(indices, tf.float32)
x = Input(shape=(1,))
y = Lambda(unique_idx)(x)
model = Model(inputs=x, outputs=y)
model.compile(optimizer='adam', loss='mse')

Resizing an input image in a Keras Lambda layer

I would like my keras model to resize the input image using OpenCV or similar.
I have seen the use of ImageGenerator, but I would prefer to write my own generator and simply resize the image in the first layer with keras.layers.core.Lambda.
How would I do this?
If you are using tensorflow backend then you can use tf.image.resize_images() function to resize the images in Lambda layer.
Here is a small example to demonstrate the same:
import numpy as np
import scipy.ndimage
import matplotlib.pyplot as plt
from keras.layers import Lambda, Input
from keras.models import Model
from keras.backend import tf as ktf
# 3 channel images of arbitrary shape
inp = Input(shape=(None, None, 3))
try:
out = Lambda(lambda image: ktf.image.resize_images(image, (128, 128)))(inp)
except :
# if you have older version of tensorflow
out = Lambda(lambda image: ktf.image.resize_images(image, 128, 128))(inp)
model = Model(input=inp, output=out)
model.summary()
X = scipy.ndimage.imread('test.jpg')
out = model.predict(X[np.newaxis, ...])
fig, Axes = plt.subplots(nrows=1, ncols=2)
Axes[0].imshow(X)
Axes[1].imshow(np.int8(out[0,...]))
plt.show()

Categories

Resources