In [1]:
from __future__ import print_function, division
import matplotlib
matplotlib.use('nbagg') # interactive plots in iPython. New in matplotlib v1.4
# %matplotlib inline

In [2]:
import matplotlib.pyplot as plt
from nilmtk import DataSet, MeterGroup
import pandas as pd
import numpy as np
from time import time


Couldn't import dot_parser, loading of dot files will not be possible.
/usr/local/lib/python2.7/dist-packages/bottleneck/__init__.py:13: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility
  from .func import (nansum, nanmax, nanmin, nanmean, nanstd, nanvar, median,
/usr/local/lib/python2.7/dist-packages/bottleneck/__init__.py:19: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility
  from .move import (move_sum, move_nansum,

In [3]:
from pybrain.supervised import RPropMinusTrainer
from pybrain.datasets import SequentialDataSet
from pybrain.structure import RecurrentNetwork, FullConnection
from pybrain.structure.modules import LSTMLayer, BiasUnit, LinearLayer, TanhLayer, SigmoidLayer

In [4]:
CONFIG = dict(
    EPOCHS_PER_CYCLE = 5,
    CYCLES = 2,
    HIDDEN_LAYERS = [15, 15],
    PEEPHOLES = True,
    TRAINERCLASS = RPropMinusTrainer,
    # instead, you may also try
    # TRAINERCLASS = BackpropTrainer(net, dataset=trndata, verbose=True, 
    #                                momentum=0.9, learningrate=0.00001)
    INPUTS = ['fridge'], #, 'hour of day (int)', 'outside temperature', 'is business day (-1, 1)'
    EXPERIMENT_NUMBER = 7
)

In [5]:
# Load dataset
dataset = DataSet('/data/mine/vadeec/merged/ukdale.h5')
dataset.set_window("2014-01-01", "2014-01-07")
elec = dataset.buildings[1].elec

In [6]:
# Select top-5 meters identified in UK-DALE paper
# APPLIANCES = ['kettle', 'dish washer', 'HTPC', 'washer dryer', 'fridge freezer']
APPLIANCES = ['fridge freezer']
selected_meters = [elec[appliance] for appliance in APPLIANCES]
selected_meters.append(elec.mains())
selected = MeterGroup(selected_meters)

In [7]:
df = selected.dataframe_of_meters()

In [8]:
# Use human-readable column names
df.columns = selected.get_labels(df.columns)

In [9]:
mains = df['Site meter'].diff().dropna()
appliances = df.iloc[:,:-1].fillna(0) # > 80
# appliances = appliances.astype(float)
del df

In [10]:
# standardise input
mains = (mains - mains.mean()) / mains.std()

# Constrain outputs to [0,1] because we're using Sigmoid
appliances /= appliances.max()

In [11]:
mains.plot()
plt.show()



In [12]:
appliances.plot()
plt.show()



In [13]:
# Build PyBrain dataset
N_OUTPUTS = appliances.shape[1]
N_INPUTS = 1
N = len(mains)
ds = SequentialDataSet(N_INPUTS, N_OUTPUTS)
ds.newSequence()
ds.setField('input', pd.DataFrame(mains).values)
ds.setField('target', appliances.values)

In [14]:
ds.getSequence(0)


/usr/local/lib/python2.7/dist-packages/PyBrain-0.3.3-py2.7.egg/pybrain/datasets/sequential.py:45: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
  return self.getField(field)[seq[index]:]
Out[14]:
[array([[ 0.04330504],
        [-0.00298955],
        [-0.0732154 ],
        ..., 
        [ 0.00119256],
        [ 0.00240348],
        [-0.00412004]]), array([[ 0.],
        [ 0.],
        [ 0.],
        ..., 
        [ 0.],
        [ 0.],
        [ 0.]])]

In [15]:
# Build network
net = RecurrentNetwork()

def lstm_layer_name(i):
    return 'LSTM{:d}'.format(i)

# Add modules
net.addInputModule(LinearLayer(ds.indim, name='in'))
net.addOutputModule(SigmoidLayer(dim=ds.outdim, name='out'))
for i, n_cells in enumerate(CONFIG['HIDDEN_LAYERS']):
    net.addModule(LSTMLayer(n_cells, name=lstm_layer_name(i+1), peepholes=CONFIG['PEEPHOLES']))   

# Bias
bias = BiasUnit()
net.addModule(bias)
net.addConnection(FullConnection(bias, net['out'], name='c_output_bias'))
    
# Add connections

n_hidden_layers = len(CONFIG['HIDDEN_LAYERS'])
prev_layer_name = 'in'
for i in range(n_hidden_layers):
    hidden_layer_i = i + 1
    layer_name = lstm_layer_name(hidden_layer_i)
    net.addRecurrentConnection(FullConnection(net[layer_name], net[layer_name], name='c_' + layer_name + '_to_' + layer_name))
    net.addConnection(FullConnection(bias, net[layer_name], name='c_' + layer_name + '_bias'))
    net.addConnection(FullConnection(net[prev_layer_name], net[layer_name], name='c_' + prev_layer_name + '_to_' + layer_name))
    prev_layer_name = layer_name
    
layer_name = lstm_layer_name(n_hidden_layers)
net.addConnection(FullConnection(net[layer_name], net['out'], name='c_' + layer_name + '_to_out'))

net.sortModules()
print(net)


RecurrentNetwork-6
   Modules:
    [<BiasUnit 'BiasUnit-5'>, <LinearLayer 'in'>, <LSTMLayer 'LSTM1'>, <LSTMLayer 'LSTM2'>, <SigmoidLayer 'out'>]
   Connections:
    [<FullConnection 'c_LSTM1_bias': 'BiasUnit-5' -> 'LSTM1'>, <FullConnection 'c_LSTM1_to_LSTM2': 'LSTM1' -> 'LSTM2'>, <FullConnection 'c_LSTM2_bias': 'BiasUnit-5' -> 'LSTM2'>, <FullConnection 'c_LSTM2_to_out': 'LSTM2' -> 'out'>, <FullConnection 'c_in_to_LSTM1': 'in' -> 'LSTM1'>, <FullConnection 'c_output_bias': 'BiasUnit-5' -> 'out'>]
   Recurrent Connections:
    [<FullConnection 'c_LSTM1_to_LSTM1': 'LSTM1' -> 'LSTM1'>, <FullConnection 'c_LSTM2_to_LSTM2': 'LSTM2' -> 'LSTM2'>]

In [16]:
# define a training method
net.randomize()
net._setParameters(np.random.uniform(-0.2, 0.2, size=net.paramdim))
trainer = CONFIG['TRAINERCLASS'](net, dataset=ds, verbose=True)

In [17]:
# carry out the training
net.reset()
# train_errors = []
t0 = time()
EPOCHS = CONFIG['EPOCHS_PER_CYCLE'] * CONFIG['CYCLES']
# trainer.trainUntilConvergence(maxEpochs=EPOCHS, verbose=True)
# start_time = time()
print("Starting training with", EPOCHS, "epochs...")
for i in xrange(CONFIG['CYCLES']):
    trainer.trainEpochs(CONFIG['EPOCHS_PER_CYCLE'])
#    train_errors.append(trainer.testOnData())
    # epoch = (i+1) * CONFIG['EPOCHS_PER_CYCLE']
    # seconds_elapsed = time() - start_time
    # seconds_per_epoch = seconds_elapsed / epoch
    # seconds_remaining = (EPOCHS - epoch) * seconds_per_epoch
    # td_elapsed = timedelta(seconds=seconds_elapsed)
    # td_elapsed_str = str(td_elapsed).split('.')[0]
    # eta = (datetime.now() + timedelta(seconds=seconds_remaining)).time()
    # eta = eta.strftime("%H:%M:%S")
    # print("\r epoch = {}/{}    error = {}  elapsed = {}   ETA = {}"
    #       .format(epoch, EPOCHS, train_errors[-1], td_elapsed_str, eta),
    #       end="")
    # stdout.flush()
print("Finished training.  total seconds =", time() - t0)


Starting training with 10 epochs...
epoch      0  total error       0.1138   avg weight       0.11485
epoch      1  total error     0.040269   avg weight       0.15122
epoch      2  total error    0.0016118   avg weight       0.18405
epoch      3  total error   0.00042859   avg weight       0.22698
epoch      4  total error    0.0005815   avg weight       0.28714
epoch      5  total error   0.00046882   avg weight        0.3593
epoch      6  total error   0.00046596   avg weight       0.43841
epoch      7  total error   0.00046869   avg weight       0.54311
epoch      8  total error   0.00042743   avg weight       0.67602
epoch      9  total error   0.00046859   avg weight       0.83871
Finished training.  total seconds = 698.453691959

In [18]:
# Disaggregate!
START = "2014-01-01"
END = "2014-01-03"
print("Starting disaggregation...")
net.reset()
estimates = pd.DataFrame(columns=appliances.columns, index=appliances[START:END].index)
for date, mains_value in mains[START:END].iteritems():
    estimates.loc[date] = net.activate(mains_value)


Starting disaggregation...

In [19]:
estimates.plot()
plt.show()



In [20]:
appliances[START:END].plot()
plt.show()



In [21]:
mains[START:END].plot()
plt.show()



In [22]:
estimates.to_hdf('neuronilm_estimates_{:03d}.hdf'.format(CONFIG['EXPERIMENT_NUMBER']), 'df')


/usr/local/lib/python2.7/dist-packages/pandas/io/pytables.py:2558: PerformanceWarning: 
your performance may suffer as PyTables will pickle object types that it cannot
map directly to c-types [inferred_type->floating,key->block0_values] [items->['Fridge freezer']]

  warnings.warn(ws, PerformanceWarning)

In [26]:



---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-26-6ac63d84d666> in <module>()
----> 1 f = FullConnection()

/usr/local/lib/python2.7/dist-packages/PyBrain-0.3.3-py2.7.egg/pybrain/structure/connections/full.pyc in __init__(self, *args, **kwargs)
     13 
     14     def __init__(self, *args, **kwargs):
---> 15         Connection.__init__(self, *args, **kwargs)
     16         ParameterContainer.__init__(self, self.indim*self.outdim)
     17 

TypeError: __init__() takes at least 3 arguments (1 given)

In [27]:
c = FullConnection(bias, net[layer_name], name='c_' + layer_name + '_bias')

In [28]:
c.params


Out[28]:
array([ 0.7171687 ,  0.34653091, -0.74233759, -0.8472035 ,  0.67101249,
       -0.40340295, -0.30980486, -1.27997928, -0.28319467, -0.45891081,
        1.0862046 , -0.51859555, -0.59913835,  0.96229359, -0.51537581,
        0.04180584, -0.61332986, -1.45811658, -0.22970571,  0.55752007,
        0.81949994,  0.1354517 ,  1.40267883, -1.77808329, -0.35309957,
       -0.37911981, -0.28196973, -1.25661571, -0.51716597, -0.80412547,
        0.63579198, -1.14807748,  0.61745927, -1.28101466, -1.71241552,
       -0.70278654,  1.97506839,  0.61420469, -0.20847649,  0.44763641,
        0.91489569, -0.57738182,  0.78272702, -0.83368065, -1.15233887,
        0.25436879, -0.58883432, -1.47554518,  0.44490647, -0.5675416 ,
       -0.53018189, -0.8020546 , -0.18574619,  1.53748802, -0.52732857,
        0.06707383, -0.52382281, -0.5541925 ,  0.73031294, -0.77335232])

In [32]:
c.randomize()

In [33]:
c.params


Out[33]:
array([ 2.09461608, -0.73116579, -1.56512842,  0.50756246, -1.00765885,
        0.13274574, -1.92232173,  0.62233591, -0.82564312, -0.40568278,
        1.49415123, -0.25531187, -0.4805642 ,  1.40654413, -0.77690489,
        0.54208079,  1.77613286,  1.06633303, -0.38231148,  0.75318948,
       -0.36706421, -0.52693886,  1.26941256,  1.21505526,  0.67366178,
       -0.29606276,  1.31870114,  1.63332819, -2.02777628,  1.95712895,
        0.2931989 ,  1.31990576, -1.80077444, -1.35636405, -0.53893877,
        0.19160234,  1.76623074,  1.80069753, -1.34652105,  0.56633703,
       -0.31073522, -0.95382293,  0.42026665,  0.79021343,  0.61508861,
       -0.20504969, -0.52251928, -0.28715166,  0.3360145 , -0.77585755,
       -0.99054701,  1.83779687,  0.4873919 , -0.63958714,  1.79263635,
       -0.11098918, -0.49323265,  0.10754002,  1.92381877,  1.17927939])

In [ ]: