Is there any wrong with my code?

I downloaded the csv data of boston house price to practice tensorflow; the csv data have 13 columns and the number 13 column is the price;
I processed the data and send them into the model to tranining;
But the training result is that the loss is a negative number and the absolute value of loss is become bigger and bigger per epoch. And the accuracy is always 0 simutaneously.
So is there any wrong with my code when process the csv data or create the model?
please help me!

import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

f = open('bostonHouse.csv')

df = pd.read_csv(f)
data = np.array(df)
plt.figure()
plt.plot(data)
plt.show()

normalize_data = (data - np.mean(data)) / np.std(data)
normalize_data = normalize_data[:, np.newaxis]

train_x, train_y = [], []
for i in range(len(normalize_data)):
    x = normalize_data[i][0][:12]
    y = normalize_data[i][0][12]
    train_x.append(x.tolist())
    train_y.append(y.tolist())

print("train_x data:{}".format(train_x[:1]))
print("train_y data:{}".format(train_y[:1]))
print('train x len', len(train_x[0]))
model = tf.keras.Sequential([
    tf.keras.layers.Dense(128, activation='relu', input_shape=(12,)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(
    loss="binary_crossentropy",
    optimizer='adam',
    metrics=['accuracy'],
)

model.summary()
model.fit(x=train_x, y=train_y, epochs=20)

the loss is negative number and the accuracy is always 0

You should remove sigmoid activation from the last dense layer and define it with just the number of units, which is 1.
Loss could be “mse” or “mae”. Any crossentropy loss is suited only for classification tasks, and here you have regression.
The same applied to metrics: “accuracy” refers to classification accuracy. When dealing with regression you can skip defining metrics in compile() and then the training will display only the loss. Or you can define loss=“mse” and metrics=[“mae”] - then both of them will be displayed.
Also, usually you have to normalize the input data but not the target values. You can extract a target column from a pandas DataFrame with y = df.pop(“column_name”) method instead of iterating through all the rows and collecting values in a list one by one.

1 Like

Thank you very much! Your answer is really helpful.
And I have another question, why we must normalize the data to [0, 1]?

It is recommended to normalize the input data to make the model train faster and get more stable results.
I couldn’t find a tutorial on this subject on the TensorFlow site, but here is an article where the concepts of data normalization and standardization are explained and code examples are available: https://machinelearningmastery.com/how-to-improve-neural-network-stability-and-modeling-performance-with-data-scaling/

1 Like

This github page could answer your question, and give more information machine learning concepts.
https://github.com/rromanss23/Machine_Leaning_Engineer_Udacity_NanoDegree/blob/master/projects/boston_housing/boston_housing.ipynb

1 Like