4
$\begingroup$

I imported my data from Matlab in matrix form and tried to use it in a neural network as given below but I get the error that says the input is not an integer between 1 and 100 although it is.

trainingData = 
  Flatten@Table[
    classinp[[i, All]] -> classout[[i, All]], {i, 1, 1750}];
validationData = 
 Flatten@Table[
   classinp[[i, All]] -> classout[[i, All]], {i, 1751, 2175}]

 net = 
  NetChain[{ LinearLayer[40], BatchNormalizationLayer[], 
    ElementwiseLayer[Ramp], LinearLayer[100], ElementwiseLayer[Ramp], 
    DropoutLayer[0.2], LinearLayer[100], DropoutLayer[0.2], 
    ElementwiseLayer[Ramp], LinearLayer[100], SoftmaxLayer[]}]

results = 
 NetTrain[net, trainingData, ValidationSet -> validationData , 
  BatchSize -> 256]

First::nofirst: {} has zero length and no first element.

NetTrain::encgenfail1: Could not encode input number 462 for port "Output": input is not an integer between 1 and 100. Please check the example.

I checked my output vector but there is no such case all the values are between 1 and 100. Also when I specify input and output sizes I received a similar error of:

NetTrain::encgenfail1: Could not encode input number 462 for port "Output": <<868>>. Please check the example.

$\endgroup$
2
$\begingroup$

It should work if you explicitly define the LossFunction.

When a loss layer is chosen automatically for a port, the loss layer is based on the layer within the net whose output is connected to that port (in your case this is LinearLayer[100]). For a SoftmaxLayer[], CrossEntropyLossLayer["Index"] is used by default. Then the target should be an integer between $1$ and $c$, or an array of such integers (in your case $c=$100). This explains the meaning of the error you get.

You probably need "Probabilities" (or "Binary") instead of the default "Index" in CrossEntropyLayer, depending on the format of your training data. See for example the following code:

ClearAll["Global`*"]
npoints = 50;
x1 = RandomVariate[NormalDistribution[0, 0.5], {npoints, 2}];
x2 = RandomVariate[NormalDistribution[1, 0.5], {npoints, 2}];
ListPlot[{x1, x2}, AxesLabel -> {"x1", "x2"}, PlotRange -> All]

Some points belonging to two different classes

net = NetInitialize@
  NetChain[{LinearLayer[10, "Input" -> 2], Ramp, LinearLayer[10], Ramp,
    LinearLayer[2], SoftmaxLayer[]}]

If I omit the LossFunction, I get the same error as you:

trainedNet = 
  NetTrain[net, 
   Join[x1, x2] -> 
    Join[ConstantArray[{1, 0}, npoints], 
         ConstantArray[{0, 1}, npoints]]];

First::nofirst: {} has zero length and no first element.

NetTrain::encgenfail1: Could not encode input number 57 for port "Output": input is not an integer between 1 and 2. Please check the example.

But if I explicitly (and correctly) set my LossFunction, then it works fine:

trainedNet = 
  NetTrain[net, 
   Join[x1, x2] -> 
    Join[ConstantArray[{1, 0}, npoints], 
     ConstantArray[{0, 1}, npoints]], 
   LossFunction -> CrossEntropyLossLayer["Binary"]];

The network is able to predict the right class:

Table[trainedNet[x1[[k]]]*100, {k, 1, npoints}]
{{100., 0.}, {100., 5.6806*10^-6}, {100., 0.}, {100., 0.}, {100., 
  0.}, {100., 8.03765*10^-28}, (* ... *) }
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.