I'm trying to train / use a convolutional neural network with neupy library for a project, but I'm getting errors in the training phase.
I have many images (rgb, shape=66, 160, 3) and I split them in the training and test sets. Then I'm trying to train one convolutional neural network (I'll try to optimize with different algorithm, layer number and size later). The target output for my project is a number [-1, 1], I'm solving a regression problem but I have issues before.
The error I'm getting right now is: ValueError: Cannot shuffle matrices. All matrices should have the same number of rows
The relevant code:
print numpy.array(y_train).shape
# outputs (84, 66, 160, 3)
print numpy.array(y_test).shape
# outputs (15, 66, 160, 3)
cgnet = algorithms.Adadelta(
[
layers.Input((6, 66, 160*3)),
layers.Convolution((8, 3, 3)),
layers.Relu(),
layers.Convolution((8, 3, 3)),
layers.Relu(),
layers.MaxPooling((2, 2)),
layers.Reshape(),
layers.Linear(1024),
layers.Softmax(10),
],
error='categorical_crossentropy',
step=1.0,
verbose=True,
shuffle_data=True,
#shuffle_data=False,
reduction_freq=8,
addons=[algorithms.StepDecay],
)
print cgnet.architecture()
cgnet.train(x_train, y_train, x_test, y_test, epochs=100)
Output:
Main information
[ALGORITHM] Adadelta
[OPTION] batch_size = 128
[OPTION] verbose = True
[OPTION] epoch_end_signal = None
[OPTION] show_epoch = 1
[OPTION] shuffle_data = True
[OPTION] step = 1.0
[OPTION] train_end_signal = None
[OPTION] error = categorical_crossentropy
[OPTION] addons = ['StepDecay']
[OPTION] decay = 0.95
[OPTION] epsilon = 1e-05
[OPTION] reduction_freq = 8
[THEANO] Initializing Theano variables and functions.
[THEANO] Initialization finished successfully. It took 7.01 seconds
Network's architecture
-------------------------------------------------
| # | Input shape | Layer Type | Output shape |
-------------------------------------------------
| 1 | (6, 66, 480) | Input | (6, 66, 480) |
| 2 | (6, 66, 480) | Convolution | (8, 64, 478) |
| 3 | (8, 64, 478) | Relu | (8, 64, 478) |
| 4 | (8, 64, 478) | Convolution | (8, 62, 476) |
| 5 | (8, 62, 476) | Relu | (8, 62, 476) |
| 6 | (8, 62, 476) | MaxPooling | (8, 31, 238) |
| 7 | (8, 31, 238) | Reshape | 59024 |
| 8 | 59024 | Linear | 1024 |
| 9 | 1024 | Softmax | 10 |
-------------------------------------------------
None
Start training
[TRAIN DATA] 84 samples, feature shape: (66, 160, 3)
[TEST DATA] 15 samples, feature shape: (66, 160, 3)
[TRAINING] Total epochs: 100
------------------------------------------------
| Epoch # | Train err | Valid err | Time |
------------------------------------------------
Traceback (most recent call last):
File "./ml_neupy.py", line 68, in <module>
cgnet.train(x_train, y_train, x_test, y_test, epochs=100)
File "/usr/local/lib/python2.7/dist-packages/neupy/algorithms/constructor.py", line 539, in train
*args, **kwargs
File "/usr/local/lib/python2.7/dist-packages/neupy/algorithms/learning.py", line 49, in train
summary=summary
File "/usr/local/lib/python2.7/dist-packages/neupy/algorithms/base.py", line 409, in train
target_train)
File "/usr/local/lib/python2.7/dist-packages/neupy/algorithms/utils.py", line 146, in shuffle
raise ValueError("Cannot shuffle matrices. All matrices should "
ValueError: Cannot shuffle matrices. All matrices should have the same number of rows
What is wrong with the input data or the network?
Thanks
There are a few things that you need to modify:
You've mentioned that you are trying to solve regression problem. Your network has a Softmax layer as the output, which means that your network can give you only outputs from [0, 1] range, instead of [-1, 1]. You can change it to Tanh layer. It will produce output from [-1, 1] range.
Cross entropy error suitable only for classification problems
error='categorical_crossentropy'
For regression you can use MSE or RMSE (more error functions you can find here)
error='mse'
I assume that in the (66, 160, 3) shape number 3 defines each of the RGB channels. NeuPy works with Theano library, which means that you need to define channel shape before the width and height of the image. The right order is: (n_samples, n_channels, height, width)
. In your case I assume that you have 84 samples, height of 66 pixels, width of 160 pixels and 3 channels (RGB). If that true then you need to transform your input as follows
# convert this shape (n_samples, height, width, n_channels)
# to (n_samples, n_channels, height, width)
x_train = x_train.transpose((0, 3, 1, 2))
print(x_train.shape) # (84, 3, 66, 160)
Output from the final layer should be 1 instead of 10. It means that you predict only one value per each sample, instead of vector with 10 values (use layers.Tanh(1)
instead of layers.Softmax(10)
)
The following code works without errors (doesn't train properly, because values are random):
import numpy
from neupy import algorithms, layers
x_train = numpy.random.random((84, 3, 66, 160))
x_test = numpy.random.random((15, 3, 66, 160))
y_train = numpy.random.random(84)
y_test = numpy.random.random(15)
cgnet = algorithms.Adadelta(
[
layers.Input((3, 66, 160)),
layers.Convolution((8, 3, 3)),
layers.Relu(),
layers.Convolution((8, 3, 3)),
layers.Relu(),
layers.MaxPooling((2, 2)),
layers.Reshape(),
layers.Linear(1024),
layers.Tanh(1),
],
error='mse',
step=1.0,
verbose=True,
shuffle_data=True,
reduction_freq=8,
addons=[algorithms.StepDecay],
)
cgnet.architecture()
cgnet.train(x_train, y_train, x_test, y_test, epochs=100)