For the past few days I’ve been revisiting some of my standard neural network problems. One of these is the Boston Area House Price problem. The data has 506 data items. Each data item represents a town or village near Boston. The goal is to predict the median house price in the town. There are 13 predictors variables such as crime rate in town, average number of rooms per house in town, density of Blacks in town, and so on. All of the predictors are numeric except one, which is a Boolean (0, 1) indicator if the town is adjacent to the Charles River or not.
The data is from a 1978 research paper. I fetched the raw data from lib.stat.cmu.edu/datasets/boston and normalized it by dividing each of the 12 predictor columns, and the house price column, by either 1, 10, 100, or 1000 so that all numeric values are between 0.0 and 1.0. I re-encoded the Charles River predictor variable as adjacent = 1 and not-adjacent = -1. I randomly split the 506 data items into a 400-item training set and a 106-item test set.
I set up a 13-(10-10)-1 neural network with tanh() hidden activation and no output activation. For training, I used the Adam optimizer with initial learning rate of 0.01, and a batch size of 10.
For a regression problem, you must define a custom accuracy() function that marks a predicted house price as correct if it’s within a specified percent of the true house price. My model achieved 73% accuracy (where the predicted house price is within 15% of the true price).
It was a fun experiment. Note: I did the same problem using PyTorch 1.10. See https://jamesmccaffreyblog.com/2022/05/09/the-boston-area-house-price-problem-using-pytorch-1-10-on-windows-10-11/.

Left: “Mars and Beyond” was an episode of the Disneyland TV show which aired on December 4, 1957. It speculated about house structures on Mars. I’ve seen this show and it’s amazing.
Center: “The Jetsons” was a TV show that aired for one season, 1962-1963. There were 24 episodes. I’ve seen a couple of episodes. I like the art, especially the house architecture, but the stories are too simple for my taste.
Right: “Colonel Bleep” was the first color cartoon animation series made for television. It ran in 1957. There were 100 episodes made where each episode was about 5 minutes long. Colonel Bleep was an alien policeman sent to Earth to stop crime. Bleep lived in a cool space age domed house.
Demo code. Replace “lt”, “gt”, “lte”, “gte” with Boolean operator symbols — my blog editor chokes on symbols.
For the data, see https://jamesmccaffreyblog.com/2022/05/09/the-boston-area-house-price-problem-using-pytorch-1-10-on-windows-10-11/
# boston_tfk.py
# Boston Area House Price regression
# Keras 2.8.0 in TensorFlow 2.8.0 ("_tfk")
# Anaconda3-2020.02 Python 3.7.6 Windows 10/11
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2' # suppress CPU warn
import numpy as np
import tensorflow as tf
from tensorflow import keras as K
# -----------------------------------------------------------
class MyLogger(K.callbacks.Callback):
def __init__(self, n):
self.n = n # print loss every n epochs
def on_epoch_end(self, epoch, logs={}):
if epoch % self.n == 0:
curr_loss = logs.get('loss') # loss on curr batch
print("epoch = %4d | curr loss = \
%0.6f " % (epoch, curr_loss))
# -----------------------------------------------------------
def accuracy(model, data_x, data_y, pct_close):
# item-by-item -- slow -- for debugging
n_correct = 0; n_wrong = 0
n = len(data_x)
for i in range(n):
x = np.array([data_x[i]]) # [[ x ]]
predicted = model.predict(x)
actual = data_y[i]
if np.abs(predicted[0][0] - actual) "lt" \
np.abs(pct_close * actual):
n_correct += 1
else:
n_wrong += 1
return (n_correct * 1.0) / (n_correct + n_wrong)
# -----------------------------------------------------------
def accuracy_x(model, data_x, data_y, pct_close):
n = len(data_x)
oupt = model(data_x)
oupt = tf.reshape(oupt, [-1]) # 1D
max_deltas = tf.abs(pct_close * data_y) # max allow deltas
abs_deltas = tf.abs(oupt - data_y) # actual differences
results = abs_deltas "lt" max_deltas # [True, False, . .]
n_correct = np.sum(results)
acc = n_correct / n
return acc
# -----------------------------------------------------------
def main():
# 0. prepare
print("\nBoston regression using PyTorch ")
np.random.random(9)
tf.random.set_seed(9)
# 1. load data
print("\nLoading Boston train and test data into memory ")
train_file = ".\\Data\\boston_train.txt"
all_xy = np.loadtxt(train_file, usecols=range(0,14),
delimiter="\t", comments="#", dtype=np.float32)
train_x = all_xy[:,0:13]
train_y = all_xy[:,13]
test_file = ".\\Data\\boston_test.txt"
all_xy = np.loadtxt(test_file, usecols=range(0,14),
delimiter="\t", comments="#", dtype=np.float32)
test_x = all_xy[:,0:13]
test_y = all_xy[:,13]
# -----------------------------------------------------------
# 2. create network
print("\nCreating 13-(10-10)-1 regression network ")
model = K.models.Sequential()
model.add(K.layers.Dense(units=10, input_dim=13,
activation='tanh', kernel_initializer='glorot_uniform',
bias_initializer='zeros')) # hid1
model.add(K.layers.Dense(units=10,
activation='tanh', kernel_initializer='glorot_uniform',
bias_initializer='zeros')) # hid2
model.add(K.layers.Dense(units=1,
activation=None, kernel_initializer='glorot_uniform',
bias_initializer='zeros')) # output layer
opt = K.optimizers.Adam(learning_rate=0.01)
model.compile(loss='mean_squared_error',
optimizer=opt, metrics=['mse'])
# -----------------------------------------------------------
# 3. train network
max_epochs = 1000
log_every = 100
my_logger = MyLogger(log_every)
print("\nbatch size = 10 ")
print("loss = mean_squared_error ")
print("optimizer = Adam ")
print("learn rate = 0.01 ")
print("max epochs = 1000 ")
print("\nStarting training ")
h = model.fit(train_x, train_y, batch_size=10,
epochs=max_epochs, verbose=0, callbacks=[my_logger])
print("Done ")
# -----------------------------------------------------------
# 4. evaluate network
acc_train = accuracy_x(model, train_x, train_y, 0.15)
print("\nAccuracy on train (within 0.15) = %0.4f " % acc_train)
acc_test = accuracy_x(model, test_x, test_y, 0.15)
print("Accuracy on test (within 0.15) = %0.4f " % acc_test)
# -----------------------------------------------------------
# 5. save model
# print("\nSaving trained model as boston_model.h5 ")
# model.save_weights(".\\Models\\boston_model_wts.h5")
# model.save(".\\Models\\boston_model.h5")
# -----------------------------------------------------------
# 6. use model
np.set_printoptions(formatter={'float': '{: 0.6f}'.format})
print("\nPredicting normalized price from first train item ")
print("Actual price = 0.2160 ")
x = np.array([[0.000273, 0.000, 0.0707, -1, 0.469,
0.6421, 0.789, 0.049671, 0.02, 0.242, 0.178,
0.39690, 0.0914]], dtype=np.float32)
# x = np.array([[0.000063, 0.180, 0.0231, -1, 0.538,
# 0.6575, 0.652, 0.040900, 0.01, 0.296, 0.153,
# 0.39690, 0.0498]], dtype=np.float32)
oupt = model.predict(x)
print("Predicted price = %0.4f " % oupt)
print("\nEnd demo ")
if __name__=="__main__":
main()

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2026 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2026 G2E Conference
2026 iSC West Conference
You must be logged in to post a comment.