Predicting House Prices on Kaggle

http://d2l.ai/chapter_multilayer-perceptrons/kaggle-house-price.html

I see that instead of log_rmse, L2loss is used during the training, is there a particular reason for that.

I am having trouble with the line that deals with plotting inside the k_fold function.

That seems to be throwing some errors. Full trace below. Does anyone know what’s wrong?


AttributeError Traceback (most recent call last)
C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\units.py in get_converter(self, x)
144 # get_converter
–> 145 if not np.all(xravel.mask):
146 # some elements are not masked

AttributeError: ‘numpy.ndarray’ object has no attribute ‘mask’

During handling of the above exception, another exception occurred:

TypeError Traceback (most recent call last)
in ()
1 k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.5, 0, 64
2 train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,
----> 3 weight_decay, batch_size)
4 print(’%d-fold validation: avg train rmse: %f, avg valid rmse: %f’
5 % (k, train_l, valid_l))

in k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size)
12 d2l.plot(list(range(1, num_epochs+1)), [train_ls, valid_ls],
13 xlabel=‘epoch’, ylabel=‘rmse’,
—> 14 legend=[‘train’, ‘valid’], yscale=‘log’)
15 print(‘fold %d, train rmse: %f, valid rmse: %f’ % (
16 i, train_ls[-1], valid_ls[-1]))

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\d2l\d2l.py in plot(X, Y, xlabel, ylabel, legend, xlim, ylim, xscale, yscale, fmts, figsize, axes)
87 for x, y, fmt in zip(X, Y, fmts):
88 if len(x):
—> 89 axes.plot(x, y, fmt)
90 else:
91 axes.plot(y, fmt)

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib_init_.py in inner(ax, *args, **kwargs)
1890 warnings.warn(msg % (label_namer, func.name),
1891 RuntimeWarning, stacklevel=2)
-> 1892 return func(ax, *args, **kwargs)
1893 pre_doc = inner.doc
1894 if pre_doc is None:

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\axes_axes.py in plot(self, *args, **kwargs)
1404 kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
1405
-> 1406 for line in self._get_lines(*args, **kwargs):
1407 self.add_line(line)
1408 lines.append(line)

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\axes_base.py in _grab_next_args(self, *args, **kwargs)
405 return
406 if len(remaining) <= 3:
–> 407 for seg in self._plot_args(remaining, kwargs):
408 yield seg
409 return

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\axes_base.py in _plot_args(self, tup, kwargs)
383 x, y = index_of(tup[-1])
384
–> 385 x, y = self._xy_from_xy(x, y)
386
387 if self.command == ‘plot’:

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\axes_base.py in _xy_from_xy(self, x, y)
216 if self.axes.xaxis is not None and self.axes.yaxis is not None:
217 bx = self.axes.xaxis.update_units(x)
–> 218 by = self.axes.yaxis.update_units(y)
219
220 if self.command != ‘plot’:

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\axis.py in update_units(self, data)
1411 “”"
1412
-> 1413 converter = munits.registry.get_converter(data)
1414 if converter is None:
1415 return False

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\units.py in get_converter(self, x)
156 if (not isinstance(next_item, np.ndarray) or
157 next_item.shape != x.shape):
–> 158 converter = self.get_converter(next_item)
159 return converter
160

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\matplotlib\units.py in get_converter(self, x)
159 return converter
160
–> 161 if converter is None and iterable(x) and (len(x) > 0):
162 thisx = safe_first_element(x)
163 if classx and classx != getattr(thisx, ‘class’, None):

C:\Users\Yong Keong\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\mxnet\numpy\multiarray.py in len(self)
804 shape = self.shape # pylint: disable=redefined-outer-name
805 if len(shape) == 0:
–> 806 raise TypeError(‘len() of unsized object’)
807 return self.shape[0]
808

TypeError: len() of unsized object

1 Like

never mind. here’s how i worked around the problem

  1. I returned train_ls, valid_ls out of the k_fold(),
  2. converted the 2 lists of numpy values into numpy arrays, then back into lists
  3. plotted separately outside of k_fold

+1
Please what is the reason we use log_rmse only for qualifying the epoch results but not for training calculations it self?

Hi @hypp-erseter, as we explained the reason of log_rmse when we use the function:

Thus we tend to care more about the relative error \frac{y - \hat{y}}{y} than about the absolute error 𝑦−𝑦̂ . For instance, if our prediction is off by USD 100,000 when estimating the price of a house in Rural Ohio, where the value of a typical house is 125,000 USD, then we are probably doing a horrible job. On the other hand, if we err by this amount in Los Altos Hills, California, this might represent a stunningly accurate prediction (there, the median house price exceeds 4 million USD).

One way to address this problem is to measure the discrepancy in the logarithm of the price estimates.

Let me know if this is not clear enough?!

Yes the purpose for log_rmse is pretty clear. But why don’t we use it for loss calculation while training the model it self. I.e.

for epoch in range(num_epochs):
    for X, y in train_iter:
        with autograd.record():
            l = log_rmse(net, X, y)
        l.backward()

Thx @gold_piggy

Hi @hypp-erseter, the gradients of log_rmse and rmse are different, and the former will optimize towards the relative error rather than the absolute error.

2 Likes

Hello! I am also a bit confused about this part as well.
I would appreciate any help/confirmation!

Q1: If we are optimizing using the L2Loss, what was the point of introducing the \texttt{log_rmse}? Is it only for presenting the relative loss instead of the absolute loss at the very end? In this example, the \texttt{log_rmse} does not contribute to the optimization process at all, does it?

Q2: What would the issue be if we optimized using \texttt{log_rmse}?

Thank you & hope my questions make sense!