I'm trying to implement a model for which the input should be a list of lists:
inputs = [ [np.array([...]), ..., np.array([...])], [np.array([...]), ..., np.array([...])] ]
I can not convert the inner lists in two np array since the shapes of them don't allow that.
When I pass the inputs to the model I receive the following error:
Please provide as model inputs either a single array or a list of arrays.
How can I feed my inputs to the model?
Thanks
You must have compatible shapes, that's unavoidable.
The only case that accepts list of lists if when you have model with "more than one input tensor".
The solutions for you are:
Padding the data: add a padding so every array has the same shape
Train separate arrays, one at a time, using train_on_batch instead of fit in a manual training loop. Each of the separate arrays must have a well defined shape.
Related
I am trying to convert an array of 3D tensors (images) to a single 4D one, so I can pass them as values to the model.fit which does not seem to accept Tensor3D arrays.
The idea would be
4dTensor = tf.tensor4d(batch)
I am actually using javascript, but either a python or js solution would probably work as the Tensorflow API is similar.
The error of this procedure is:
Argument of type 'Tensor4D' is not assignable to parameter of type 'Tensor3D[]'.
Type 'Tensor<Rank.R4>' is missing the following properties from type 'Tensor3D[]': length, pop, push, join, and 26 more.ts(2345)
You may want to use tf.stack():
4dTensor = tf.stack(batch)
I haven't used neural networks for many years, so excuse my ignorance.
I was wondering what is the most appropriate way to train a LSTM model based on my dataset.
I have 3 attributes as follows:
Attribute 1: small int e.g., [123, 321, ...]
Attribute 2: text sequence ['cgtaatta', 'ggcctaaat', ... ]
Attribute 3: text sequence ['ttga', 'gattcgtt', ... ]
Class label: binary [0, 1, ...]
The length of each sample's attributes (2 or 3) is arbitrary; therefore I do not want to use them as words rather as sequences (that's why I want to use RNN/LSTM models).
Is it possible to have more than one (sequence) inputs to the LSTM model (are there examples)? Or should I concatenate them into one e.g., input 1: ["123 cgtaatta ttga", 0]
You don't need to concatonate the inputs into one, that part is done using the tf.keras.layers.Flatten() layer, which takes multiple inputs and and flattens them without affecting the batch size.
Read more here: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Flatten
And here:
https://www.tensorflow.org/tutorials/structured_data/time_series#multi-step_dense
Not sure about most appropriate way since I wondered here looking for my own answers, but I do know you need to classify the data by providing some numerical identities to the text if applicable in your case.
Hope this helps
So the logistic regression from the sklearn library from Python has the .fit() function which takes x_train(features) and y_train(labels) as arguments to train the classifier.
It seems that x_train.shape = (number_of_samples, number_of_features)
For x_train I should use the extracted xvector.scp file, which I am reading like so:
b = kaldiio.load_scp('xvector.scp')
And I can print the content like so:
for file_id in b:
xvector = b[file_id]
print(xvector)
Right now the b variable is like a dictionary and you can get the x-vector value of the corresponding id. I want to use sklearn Logistic Regression to classify the x-vectors and in order to use the .fit() method I should pass an array as an argument.
My question is how can I make an array that contains only the xvector variables?
PS: the file_ids are like 1 million and each xvector has length of 512, which is too big for an array
It seems you are trying to store the dictionary into a numpy array. If the dictionary is small, you can directly store the values as:
import numpy as np
x = np.array(list(b.values()))
However, this will run into OOM issues if the dictionary is large. In this case, you would need to use np.memmap as explained here: https://ipython-books.github.io/48-processing-large-numpy-arrays-with-memory-mapping/
Essentially, you have to add rows to the array one at a time, and flush it when you have run out of memory. The array is stored directly on the disk, so it avoids OOM issues.
I'm actually trying to program a Keras Model. In my point of view, a keras Model needs a list of np.arrays as x (or a Numpy Array). In my case x is looking like this:
print(training.dtype)
object
print(training.shape)
(406,)
print(training[0].dtype)
float64
print(training[0].shape)
(5140, 5)
This is the size of my Train data (x). If I want to train the model I get this error:
return array(a, dtype, copy=False, order=order)
ValueError: setting an array element with a sequence.
That's why I think, I prepared the data wrong. If I want to convert them with .astype to float32, I get the same error.
Thanks for your help!
If the entries in train2 do not all have the same size, you will need to pad them. As this is something that needs to be done quite regularly, Keras offers a function for this: pad_sequences
Once they all are the same size, np.array(train2) will create one single numpy array that you can pass to model.fit().
Depending on your model, the extra data you are adding this way may or may not be an issue. A common way to deal with this is Masking. Use this to generate a mask that will automatically be passed down the model so that certain values (the values you added via padding) are ignored. Note however, that not all layers support masking, so maybe this is not an option for you.
The issue is not changing the type. The issue is in the batch samples not being of the same size, so no np array could be created. You can solve this by using padding as mentioned in the comments. Have a look at keras pad_sequences What does Keras.io.preprocessing.sequence.pad_sequences do?
Here's my current call to model.fit in Keras
history_callback = model.fit(x_train/255.,
validation_train_data,
validation_split=validation_split,
batch_size=batch_size,
callbacks=callbacks)
in this example x_train is a list of numpy arrays that contains all of my image data. The way validation_train_data is structured though is its a list of numpy arrays of totally different sizes that is equal in length to the list of numpy arrays that contains my image. The data for each image though is contained in validation_train_data such that x_train[i] would correspond to a set containing validation_train_data[0][i], validation_train_data[1][i], validation_train_data[2][i], etc. Is there any way I can reformat my validation_train_data such that it can properly be used as a y_true in a custom keras loss function.
I managed to solve my problem by writing a generator function which generated a batch of x and y data as lists and put them together as a tuple. I then called fit_generator with the argument where generator = my_generator and it worked just fine. If you have odd input data then you should consider writing a generator to take care of it.
This is the tutorial I used to do so:
https://stanford.edu/~shervine/blog/keras-how-to-generate-data-on-the-fly