I have a simple model in keras. I tried making similar model in java using dl4j. But the accuracy is extremely low compared to the the one trained in keras. I am not sure why this is happening as model looks quite similar to me. Can some one please help me to figure out if i am doing something wrong in java here ?
Python model :
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(600, activation=‘relu’, input_shape=(512,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(300, activation=‘relu’),
keras.layers.Dropout(0.2),
keras.layers.Dense(1, activation=‘sigmoid’)
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
def get_data_from_csv():
my_data = np.genfromtxt('spam.csv', delimiter=',')
X = my_data[:, :512]
X = X.astype('float32')
Y = my_data[:, -1].astype('int')
print(type(X), X.dtype, type(Y), Y.dtype)
print(X.shape, Y.shape)
return train_test_split(X, Y, test_size=0.25)
model = create_model()
X_train, X_test, y_train, y_test = get_data_from_csv()
model.fit(X_train, y_train, epochs=20, batch_size=100)
_, accuracy = model.evaluate(X_test, y_test)
print('Accuracy: %.2f' % (accuracy * 100))
Python Output :
Epoch 1/20 1/1 [==============================] - 0s 313us/step - loss: 0.0299 - accuracy: 0.9938 Epoch 2/20 1/1 [==============================] - 0s 308us/step - loss: 0.0194 - accuracy: 0.9943 Epoch 3/20 1/1 [==============================] - 0s 318us/step - loss: 0.0146 - accuracy: 0.9959 Epoch 4/20 1/1 [==============================] - 0s 305us/step - loss: 0.0104 - accuracy: 0.9969 Epoch 5/20 1/1 [==============================] - 0s 312us/step - loss: 0.0067 - accuracy: 0.9982 Epoch 6/20 1/1 [==============================] - 0s 321us/step - loss: 0.0047 - accuracy: 0.9987 Epoch 7/20 1/1 [==============================] - 0s 301us/step - loss: 0.0031 - accuracy: 0.9992 Epoch 8/20 1/1 [==============================] - 0s 301us/step - loss: 0.0024 - accuracy: 0.9995 Epoch 9/20 1/1 [==============================] - 0s 303us/step - loss: 0.0021 - accuracy: 0.9997 Epoch 10/20 1/1 [==============================] - 0s 309us/step - loss: 0.0020 - accuracy: 0.9997 Epoch 11/20 1/1 [==============================] - 0s 296us/step - loss: 0.0015 - accuracy: 0.9997 Epoch 12/20 1/1 [==============================] - 0s 315us/step - loss: 0.0013 - accuracy: 1.0000 Epoch 13/20 1/1 [==============================] - 0s 332us/step - loss: 0.0013 - accuracy: 1.0000 Epoch 14/20 1/1 [==============================] - 0s 303us/step - loss: 0.0016 - accuracy: 1.0000 Epoch 15/20 1/1 [==============================] - 0s 308us/step - loss: 0.0012 - accuracy: 1.0000 Epoch 16/20 1/1 [==============================] - 0s 305us/step - loss: 0.0012 - accuracy: 1.0000 Epoch 17/20 1/1 [==============================] - 0s 306us/step - loss: 8.8349e-04 - accuracy: 1.0000 Epoch 18/20 1/1 [==============================] - 0s 299us/step - loss: 0.0012 - accuracy: 1.0000 Epoch 19/20 1/1 [==============================] - 0s 322us/step - loss: 0.0011 - accuracy: 1.0000 Epoch 20/20 1/1 [==============================] - 0s 305us/step - loss: 9.3288e-04 - accuracy: 1.0000 41/41 [==============================] - 0s 625us/step - loss: 0.0436 - accuracy: 0.9915 Accuracy: 99.15
Java code :
public class SpamClassifier {
private static MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(123)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(new Adam(0.0001))
.list()
.layer(0, new DenseLayer.Builder()
.nIn(512).nOut(600)
.weightInit(WeightInit.XAVIER)
.activation(Activation.RELU).build())
.layer(1, new DropoutLayer.Builder().dropOut(0.2).build())
.layer(2, new DenseLayer.Builder()
.nIn(600).nOut(300)
.weightInit(WeightInit.XAVIER)
.activation(Activation.RELU).build())
.layer(3, new DropoutLayer.Builder().dropOut(0.2).build())
.layer(4, new OutputLayer.Builder(LossFunctions.LossFunction.XENT)
.nIn(300).nOut(2)
.weightInit(WeightInit.XAVIER)
.activation(Activation.SIGMOID).build())
.build();
private static MultiLayerNetwork model = new MultiLayerNetwork(conf);
public static void run() throws IOException, InterruptedException {
RecordReader recordReader = new CSVRecordReader(0, ',');
recordReader.initialize(new FileSplit(new ClassPathResource("spam.csv").getFile()));
DataSetIterator iterator = new RecordReaderDataSetIterator(recordReader, 5171, 512, 2);
DataSet allData = iterator.next();
allData.shuffle(42);
SplitTestAndTrain testAndTrain = allData.splitTestAndTrain(0.70);
DataSet trainingData = testAndTrain.getTrain();
DataSet testData = testAndTrain.getTest();
model.init();
model.setListeners(new ScoreIterationListener(1));
model.setEpochCount(100);
model.fit(trainingData);
INDArray output = model.output(testData.getFeatures());
Evaluation eval = new Evaluation(2);
eval.eval(testData.getLabels(), output);
System.out.println(eval.stats());
}
public static void main(String[] args) throws IOException, InterruptedException {
run();
}
}
Dataset i am using is around of size 5000 and has 512 input features. The same dataset is used in python as well. Output class is the last column of csv and has only 1’s and 0’
Java output :
========================Evaluation Metrics========================
# of classes: 2
Accuracy: 0.7126
Precision: 0.7500
Recall: 0.0133
F1 Score: 0.0262
Precision, recall & F1: reported for positive class (class 1 - "1") only
=========================Confusion Matrix=========================
0 1
-----------
1100 2 | 0 = 0
444 6 | 1 = 1
Confusion matrix format: Actual (rowClass) predicted as (columnClass) N times
==================================================================
Process finished with exit code 0
A little difference in accuracy can be understood but here difference is too large.