Code error using MNIST example of deeplearning4j - deep-learning

Help me please! I'm working on a project using deeplearning4j. The MNIST example works very well but I get an error with my dataset.
My data set has two outputs.
int height = 45;
int width = 800;
int channels = 1;
int rngseed = 123;
Random randNumGen = new Random(rngseed);
int batchSize = 128;
int outputNum = 2;
int numEpochs = 15;
File trainData = new File("C:/Users/JHP/Desktop/learningData/training");
File testData = new File("C:/Users/JHP/Desktop/learningData/testing");
FileSplit train = new FileSplit(trainData, NativeImageLoader.ALLOWED_FORMATS, randNumGen);
FileSplit test = new FileSplit(testData, NativeImageLoader.ALLOWED_FORMATS, randNumGen);
ParentPathLabelGenerator labelMaker = new ParentPathLabelGenerator();
ImageRecordReader recordReader = new ImageRecordReader(height, width, channels, labelMaker);
ImageRecordReader recordReader2 = new ImageRecordReader(height, width, channels, labelMaker);
recordReader.initialize(train);
recordReader2.initialize(test);
DataSetIterator dataIter = new RecordReaderDataSetIterator(recordReader, batchSize, 1, outputNum);
DataSetIterator testIter = new RecordReaderDataSetIterator(recordReader2, batchSize, 1, outputNum);
DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
scaler.fit(dataIter);
dataIter.setPreProcessor(scaler);
System.out.println("Build model....");
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(rngseed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.iterations(1)
.learningRate(0.006)
.updater(Updater.NESTEROVS).momentum(0.9)
.regularization(true).l2(1e-4)
.list()
.layer(0, new DenseLayer.Builder()
.nIn(height * width)
.nOut(1000)
.activation(Activation.RELU)
.weightInit(WeightInit.XAVIER)
.build()
)
.layer(1, newOutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD)
.nIn(1000)
.nOut(outputNum)
.activation(Activation.SOFTMAX)
.weightInit(WeightInit.XAVIER)
.build()
)
.pretrain(false).backprop(true)
.build();
MultiLayerNetwork model = new MultiLayerNetwork(conf);
model.init();
model.setListeners(new ScoreIterationListener(1));
System.out.println("Train model....");
for (int i = 0; i < numEpochs; i++) {
try {
model.fit(dataIter);
} catch (Exception e) {
System.out.println(e);
}
}
error is
org.deeplearning4j.exception.DL4JInvalidInputException: Input that is
not a matrix; expected matrix (rank 2), got rank 4 array with shape
[128, 1, 45, 800]

You're initializing the neural net wrong. If you look closer at every cnn example in the dl4j examples repo (hint: this is the canonical source of where you should be pulling code from, anything else will likely be invalid or out of date: https://github.com/deeplearning4j/dl4j-examples)
You'll notice in all of our examples we have an inputType config:
https://github.com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/convolution/LenetMnistExample.java#L114
There are various types you should be using you should never set nIn manually. Just nOut.
For mnist, we use convolutional flat and convert it in to a 4d dataset automaticall for you.
Mnist starts off as a flat vector, but a cnn only understands 3d data. We do that transition and reshape for you.

Related

How can one get t-statistic for each coefficient in Math.NET multiple regression

I want to perform a multiple regression using Math.NET. For each coefficient I need to get a t-statistic or at least a standard error. How can I do this with Math.NET? I couldn't find it in the docs.
x = new double[3][];
for (int i = 0; i < 3; i++) x[i] = new double[10];
y = new double[10];
...
double[] coefs = Fit.MultiDim(x, y, intercept: true);
MultiDim returns only coefficients without any statistics.

Trying to understand code in the PolygonSprite.java library file

I am trying to execute this piece of code in my game.
public void draw(Batch batch, float parentAlpha){
PolygonRegion polyReg = new PolygonRegion(connectorTextureRegion, getVertices(), getTriangles());
polygonSprite.setRegion(polyReg);
polygonSprite.draw((PolygonSpriteBatch)batch);
}
In general, it works well but sometimes I'm getting an ArrayIndexOutOfBounds exception caused by the setRegion line. If I dive into the methods code, it fails at the first line in the for loop.
public void setRegion (PolygonRegion region) {
this.region = region;
float[] regionVertices = region.vertices;
float[] textureCoords = region.textureCoords;
if (vertices == null || regionVertices.length != vertices.length) vertices = new float[(regionVertices.length / 2) * 5];
// Set the color and UVs in this sprite's vertices.
float floatColor = color.toFloatBits();
float[] vertices = this.vertices;
for (int i = 0, v = 2, n = regionVertices.length; i < n; i += 2, v += 5) {
vertices[v] = floatColor;
vertices[v + 1] = textureCoords[i];
vertices[v + 2] = textureCoords[i + 1];
}
dirty = true;
}
Now let me know if I'm wrong, but I feel like there might be an issue with the if condition. Why are we checking for this?
regionVertices.length != vertices.length
Whenever I get the exception, it's because the length of the region vertices array and the length of the sprite vertices array are equal.

How can I get the value of pin A0 from the second sketch into the JSON array in the first sketch?

Can anyone help me figure out how to piece these two pieces of code together so I get the result I need? My eyes are crossing from looking at this. I know this is a breeze for probably everyone other than myself, but I am not a programmer and this is just for one small personal project.
So far, after hours and hours of reading and watching any videos I could find relating to Arduino, Pubnub and sensors, I have sensor reading publishing to Pubnub. I created a Freeboard account for visualization and that's all working. The problem is, the data being published is wrong.
Basically, I'm wanting to read a battery voltage and publish it to PubNub. I can get the Arduino (Uno R3) to read the voltage and I can adjust the values in the code to match the actual voltage. The problem I run into is taking that bit of code that works and stuffing it into the JSON array that gets published to PubNub.
If anyone would be willing to help me and maybe explain a little (or not - I'm okay if I just get it working), I would SO appreciate the time, help and effort.
Thanks!
//Each sketch works indepently. I need to merge them to get the correct reading published.
//VoltagePubNub.ino
(This is the one that publishes, which is what I want. I just want the published value to be the value of the second sketch.)
#include <SPI.h>
#include <Ethernet.h>
#include <PubNub.h>
#include <aJSON.h>
// Some Ethernet shields have a MAC address printed on a sticker on the shield;
// fill in that address here, or choose your own at random:
const static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Memory saving tip: remove myI and dnsI from your sketch if you
// are content to rely on DHCP autoconfiguration.
IPAddress myI(192, 168, 2, 114);
IPAddress dnsI(8, 8, 8, 8);
const static char pubkey[] = "publish_key";
const static char subkey[] = "subscribe_key";
const static char channel[] = "channel_name";
char uuid[] = "UUID";
#define NUM_CHANNELS 1 // How many analog channels do you want to read?
const static uint8_t analog_pins[] = {A0}; // which pins are you reading?
void setup()
{
Serial.begin(9600);
Serial.println("Serial set up");
Ethernet.begin((byte*) mac, myI, dnsI);
Serial.println("Ethernet set up");
delay(1000);
Serial.println("Ethernet set up");
PubNub.begin(pubkey, subkey);
Serial.println("PubNub set up");
delay(5000);
}
void loop()
{
Ethernet.maintain();
EthernetClient *client;
// create JSON objects
aJsonObject *msg, *analogReadings;
msg = aJson.createObject();
aJson.addItemToObject(msg, "analogReadings", analogReadings = aJson.createObject());
// get latest sensor values then add to JSON message
for (int i = 0; i < NUM_CHANNELS; i++) {
String analogChannel = String(analog_pins[i]);
char charBuf[analogChannel.length()+1];
analogChannel.toCharArray(charBuf, analogChannel.length()+1);
int analogValues = analogRead(analog_pins[i]);
aJson.addNumberToObject(analogReadings, charBuf, analogValues);
}
// convert JSON object into char array, then delete JSON object
char *json_String = aJson.print(msg);
aJson.deleteItem(msg);
// publish JSON formatted char array to PubNub
Serial.print("publishing a message: ");
Serial.println(json_String);
client = PubNub.publish(channel, json_String);
if (!client) {
Serial.println("publishing error");
} else
free(json_String);
client->stop();
delay(5000);
}
//VoltageSensor.ino
(This is the one with the correct value, but no publish feature.)
int analogInput = A0;
float vout = 0.0;
float vin = 0.0;
float R1 = 31000.0; //
float R2 = 8700.0; //
int value = 0;
int volt = 0;
void setup(){
pinMode(analogInput, INPUT);
Serial.begin(9600);
Serial.print("DC VOLTMETER");
Serial.println("");
}
void loop(){
// read the value at analog input
value = analogRead(analogInput);
vout = (value * 4.092) / 1024.0;
vin = vout / (R2/(R1+R2));
Serial.print("INPUT V= ");
Serial.println(vin,2);
delay(2000);
}
It may not be the most glamorous or the proper way of doing it, but I got this to do what I need. I edited the first sketch with the following code:
// create JSON objects
aJsonObject *msg, *analogReadings;
msg = aJson.createObject();
aJson.addItemToObject(msg, "analogReadings", analogReadings = aJson.createObject());
// get latest sensor values then add to JSON message
for (int i = 0; i < NUM_CHANNELS; i++) {
float vout = 0.0;
float vin = 0.0;
float R1 = 33060.0; //
float R2 = 7600.0; //
int value = 0;
int volt = 0;
//Serial.print("INPUT V= ");
//Serial.println(vin,2);
String analogChannel = String(analog_pins[i]);
value = analogRead(analog_pins[i]);
vout = (value * 4.092) / 1024.0;
vin = vout / (R2/(R1+R2));
char charBuf[analogChannel.length()+1];
analogChannel.toCharArray(charBuf, analogChannel.length()+1);
float theVoltage = (vin);
int analogValues = analogRead(analog_pins[i]);
aJson.addNumberToObject(analogReadings, charBuf, theVoltage);
}
// convert JSON object into char array, then delete JSON object
char *json_String = aJson.print(msg);
aJson.deleteItem(msg);
Now the value is published to PubNub and is graphed on Freeboard.io at this link .

DeepLearning4J: Shapes do not match on FeedForward Auto Encoder

I'm implementing an auto-encoder for anomaly detection of IoT sensor data. My data set comes from a simulation, but basically it is accelerometer data - three dimensions, one for each axis.
I'm reading it from a CSV file, column 2-4 contain the data - sorry for the code quality, it is quick and dirty:
private static DataSetIterator getTrainingData(int batchSize, Random rand) {
double[] ix = new double[nSamples];
double[] iy = new double[nSamples];
double[] iz = new double[nSamples];
double[] ox = new double[nSamples];
double[] oy = new double[nSamples];
double[] oz = new double[nSamples];
Reader in;
try {
in = new FileReader("/Users/romeokienzler/Downloads/lorenz_healthy.csv");
Iterable<CSVRecord> records;
records = CSVFormat.DEFAULT.parse(in);
int index = 0;
for (CSVRecord record : records) {
String[] recordArray = record.get(0).split(";");
ix[index] = Double.parseDouble(recordArray[1]);
iy[index] = Double.parseDouble(recordArray[2]);
iz[index] = Double.parseDouble(recordArray[3]);
ox[index] = Double.parseDouble(recordArray[1]);
oy[index] = Double.parseDouble(recordArray[2]);
oz[index] = Double.parseDouble(recordArray[3]);
index++;
}
INDArray ixNd = Nd4j.create(ix);
INDArray iyNd = Nd4j.create(iy);
INDArray izNd = Nd4j.create(iz);
INDArray oxNd = Nd4j.create(ox);
INDArray oyNd = Nd4j.create(oy);
INDArray ozNd = Nd4j.create(oz);
INDArray iNd = Nd4j.hstack(ixNd, iyNd, izNd);
INDArray oNd = Nd4j.hstack(oxNd, oyNd, ozNd);
DataSet dataSet = new DataSet(iNd, oNd);
List<DataSet> listDs = dataSet.asList();
Collections.shuffle(listDs, rng);
return new ListDataSetIterator(listDs, batchSize);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(-1);
return null;
}
}
This is the net:
public static void main(String[] args) {
// Generate the training data
DataSetIterator iterator = getTrainingData(batchSize, rng);
// Create the network
int numInput = 3;
int numOutputs = 3;
int nHidden = 1;
int listenerFreq = batchSize / 5;
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(seed)
.gradientNormalization(GradientNormalization.ClipElementWiseAbsoluteValue)
.gradientNormalizationThreshold(1.0).iterations(iterations).momentum(0.5)
.momentumAfter(Collections.singletonMap(3, 0.9))
.optimizationAlgo(OptimizationAlgorithm.CONJUGATE_GRADIENT).list(2)
.layer(0,
new AutoEncoder.Builder().nIn(numInput).nOut(nHidden).weightInit(WeightInit.XAVIER)
.lossFunction(LossFunction.RMSE_XENT).corruptionLevel(0.3).build())
.layer(1, new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD).activation("softmax").nIn(nHidden)
.nOut(numOutputs).build())
.pretrain(true).backprop(false).build();
MultiLayerNetwork model = new MultiLayerNetwork(conf);
model.init();
model.setListeners(Collections.singletonList((IterationListener) new ScoreIterationListener(listenerFreq)));
for (int i = 0; i < nEpochs; i++) {
iterator.reset();
model.fit(iterator);
}
}
I'm getting the following error:
Shapes do not match: x.shape=[1, 9000], y.shape=[1, 3]
Exception in thread "main" java.lang.IllegalArgumentException: Shapes do not match: x.shape=[1, 9000], y.shape=[1, 3]
at org.nd4j.linalg.api.parallel.tasks.cpu.CPUTaskFactory.getTransformAction(CPUTaskFactory.java:92)
at org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner.doTransformOp(DefaultOpExecutioner.java:409)
at org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner.exec(DefaultOpExecutioner.java:62)
at org.nd4j.linalg.api.ndarray.BaseNDArray.subi(BaseNDArray.java:2660)
at org.nd4j.linalg.api.ndarray.BaseNDArray.subi(BaseNDArray.java:2641)
at org.nd4j.linalg.api.ndarray.BaseNDArray.sub(BaseNDArray.java:2419)
at org.deeplearning4j.nn.layers.feedforward.autoencoder.AutoEncoder.computeGradientAndScore(AutoEncoder.java:123)
at org.deeplearning4j.optimize.solvers.BaseOptimizer.gradientAndScore(BaseOptimizer.java:132)
at org.deeplearning4j.optimize.solvers.BaseOptimizer.optimize(BaseOptimizer.java:151)
at org.deeplearning4j.optimize.Solver.optimize(Solver.java:52)
at org.deeplearning4j.nn.layers.BaseLayer.fit(BaseLayer.java:486)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.pretrain(MultiLayerNetwork.java:170)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:1134)
at org.deeplearning4j
.examples.feedforward.autoencoder.AnomalyDetector.main(AnomalyDetector.java:136)
But I'm not defining dimension anywhere and IMHO the dimensions of input and output should be (3,3000) and (3,3000). Where is my mistake?
Thanks a lot in advance...
EDIT: UPDATE to latest release 13.9.16
I'm getting the same error (semantically), here is what I'm doing now:
private static DataSetIterator getTrainingData(int batchSize, Random rand) {
double[] ix = new double[nSamples];
double[] iy = new double[nSamples];
double[] iz = new double[nSamples];
double[] ox = new double[nSamples];
double[] oy = new double[nSamples];
double[] oz = new double[nSamples];
try {
RandomAccessFile in = new RandomAccessFile(new File("/Users/romeokienzler/Downloads/lorenz_healthy.csv"),
"r");
int index = 0;
String record;
while ((record = in.readLine()) != null) {
String[] recordArray = record.split(";");
ix[index] = Double.parseDouble(recordArray[1]);
iy[index] = Double.parseDouble(recordArray[2]);
iz[index] = Double.parseDouble(recordArray[3]);
ox[index] = Double.parseDouble(recordArray[1]);
oy[index] = Double.parseDouble(recordArray[2]);
oz[index] = Double.parseDouble(recordArray[3]);
index++;
}
INDArray ixNd = Nd4j.create(ix);
INDArray iyNd = Nd4j.create(iy);
INDArray izNd = Nd4j.create(iz);
INDArray oxNd = Nd4j.create(ox);
INDArray oyNd = Nd4j.create(oy);
INDArray ozNd = Nd4j.create(oz);
INDArray iNd = Nd4j.hstack(ixNd, iyNd, izNd);
INDArray oNd = Nd4j.hstack(oxNd, oyNd, ozNd);
DataSet dataSet = new DataSet(iNd, oNd);
List<DataSet> listDs = dataSet.asList();
Collections.shuffle(listDs, rng);
return new ListDataSetIterator(listDs, batchSize);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(-1);
return null;
}
}
And here the net:
// Set up network. 784 in/out (as MNIST images are 28x28).
// 784 -> 250 -> 10 -> 250 -> 784
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(12345).iterations(1)
.weightInit(WeightInit.XAVIER).updater(Updater.ADAGRAD).activation("relu")
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).learningRate(learningRate)
.regularization(true).l2(0.0001).list().layer(0, new DenseLayer.Builder().nIn(3).nOut(1).build())
.layer(1, new OutputLayer.Builder().nIn(1).nOut(3).lossFunction(LossFunctions.LossFunction.MSE).build())
.pretrain(false).backprop(true).build();
MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.setListeners(Collections.singletonList((IterationListener) new ScoreIterationListener(1)));
// Load data and split into training and testing sets. 40000 train,
// 10000 test
DataSetIterator iter = getTrainingData(batchSize, rng);
// Train model:
int nEpochs = 30;
while (iter.hasNext()) {
DataSet ds = iter.next();
for (int epoch = 0; epoch < nEpochs; epoch++) {
net.fit(ds.getFeatures(), ds.getLabels());
System.out.println("Epoch " + epoch + " complete");
}
}
My error is:
Exception in thread "main" java.lang.IllegalStateException: Mis matched lengths: [9000] != [3]
at org.nd4j.linalg.util.LinAlgExceptions.assertSameLength(LinAlgExceptions.java:39)
at org.nd4j.linalg.api.ndarray.BaseNDArray.subi(BaseNDArray.java:2786)
at org.nd4j.linalg.api.ndarray.BaseNDArray.subi(BaseNDArray.java:2767)
at org.nd4j.linalg.api.ndarray.BaseNDArray.sub(BaseNDArray.java:2547)
at org.deeplearning4j.nn.layers.BaseOutputLayer.getGradientsAndDelta(BaseOutputLayer.java:182)
at org.deeplearning4j.nn.layers.BaseOutputLayer.backpropGradient(BaseOutputLayer.java:161)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.calcBackpropGradients(MultiLayerNetwork.java:1125)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.backprop(MultiLayerNetwork.java:1077)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.computeGradientAndScore(MultiLayerNetwork.java:1817)
at org.deeplearning4j.optimize.solvers.BaseOptimizer.gradientAndScore(BaseOptimizer.java:152)
at org.deeplearning4j.optimize.solvers.StochasticGradientDescent.optimize(StochasticGradientDescent.java:54)
at org.deeplearning4j.optimize.Solver.optimize(Solver.java:51)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:1445)
at org.deeplearning4j.examples.feedforward.anomalydetection.IoTAnomalyExample.main(IoTAnomalyExample.java:110)
I'm pretty sure I'm messing up with the training data - the shape of the training data is 3000 rows, 3 columns - same for the target (the very same data because I want to build an autoencoder) - test data can be found here:
https://pmqsimulator-romeokienzler-2310.mybluemix.net/data
Any ideas?
Thanks to Alex Black of Skymind, this is the solution (got the shape wrong)
INDArray ixNd = Nd4j.create(ix, new int[]{3000,1});
INDArray iyNd = Nd4j.create(iy, new int[]{3000,1});
INDArray izNd = Nd4j.create(iz, new int[]{3000,1});
INDArray oxNd = Nd4j.create(ox, new int[]{3000,1});
INDArray oyNd = Nd4j.create(oy, new int[]{3000,1});
INDArray ozNd = Nd4j.create(oz, new int[]{3000,1});

Libgdx Screenshot method not working

A couple of weeks ago I implemented this method https://github.com/libgdx/libgdx/wiki/Take-a-Screenshot
And it worked great with libgdx 1.3.1 . Now though I upgraded to 1.6.0 and it have stopped working.
When the method is executed it freezes. I have it implemented on a button, and it gets stuck in "downclick" and nothing more happens.
private void saveScreenshot() {
try{
FileHandle fh;
do{
fh = new FileHandle(files.getLocalStoragePath() + "screenshot" + ".png");
}while(fh.exists());
Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - 130, true);
PixmapIO.writePNG(fh, pixmap);
pixmap.dispose();
System.out.println("Path:" + fh.toString());
}catch(Exception e) {
}
}
private Pixmap getScreenshot(int x, int y, int w, int h, boolean yDown){
final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
w = pixmap.getWidth();
h = pixmap.getHeight();
if(yDown) {
ByteBuffer pixels = pixmap.getPixels();
int numBytes = w * h * 4;
byte[] lines = new byte[numBytes];
int numBytesPerLine = w * 4;
for (int i = 0; i < h; i++) {
pixels.position((h - i - 1) * numBytesPerLine);
pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
}
pixels.clear();
pixels.put(lines);
}
return pixmap;
}
btnArrow.addListener(new ChangeListener() {
//photoshop "save" and "back" on arrow/back image to clarify.
#Override
public void changed(ChangeEvent event, Actor actor) {
saveScreenshot();
sharePhoto();
}
});
I share the image to facebook aswell. And this method is in AndroidLauncher of course and is passed through an interface. And here I fetch the screenshot:
public void sharePhoto() {
Matrix matrix = new Matrix();
String filePath = (files.getLocalStoragePath() + "screenshot" + ".png");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
Bitmap rotateBit = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//Starts sharing process
SharePhoto photo = new SharePhoto.Builder()
.setBitmap(rotateBit)
.build();
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(photo)
.build();
share.show(content);
}
So what I believe may be the issue is libgdx have done changes on Pixmap class or Bitmap class of some sort. Since sharing a link through facebook on that button works fine.
I also printed the path as you can see in saveScreenshot() and it returns this
selinux_android_setcategory: no category for userid: 0, path: /data/data/com.sparc.tormt.android/lib
Is it stuck because this is an infinite loop if the file already exists:
do {
fh = new FileHandle(files.getLocalStoragePath() + "screenshot" + ".png");
} while(fh.exists());