学習共有-ディープラーニングに基づくNILM負荷分解(4)ディープラーニングの実装、コードの説明

QQグループ1070535031
は前の記事のアイデアに従います。この記事では、プロセス全体を実装します。

実験的ニーズ

この記事に従って学習および実験するには、前のブログ投稿の環境と抽出された英国のデータが必要です。学習と共有-ディープラーニングに基づくNILM負荷分解(2)電気機器データ抽出

この記事のコードのアイデアは前の記事にあり、この記事は関連するコードの実装に焦点を当てています。アイデアを見てみましょう(学習共有-深層学習に基づくNILM負荷分解(3)深層学習処理、基本的なアイデア

実験環境:
pycharm、python 3.6 +、kerasライブラリ、numpyライブラリ、matplotlibライブラリ
、UKData。

グローバルパラメータを定義する

最初に、必要なすべてのライブラリを次のように引用します。

import numpy as np
import os
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop
from keras.models import load_model

次に、いくつかのグローバルパラメータを定義します。

# 全局参数定义
dimension = 5 #电器的个数

#电器id定义
fridge_id = 0
tv_id = 1
kettle_id = 2
microwave_id = 3
washerdryer_id = 4

#电器开启状态阈值
fridge_threshold = 20
tv_threshold = 20
kettle_threshold = 20
microwave_threshold = 10
washerdryer_threshold = 0

#消噪音阈值
air_threshold = 5

上記のパラメータを1つずつ紹介します

次元:私たちが訓練する電気器具のカテゴリーの数です。現在の予備実験では5つが設定されています。

電化製品ID:選択した5つの電化製品の自己増加IDです。(ここでは、冷蔵庫、テレビ、ケトル、電子レンジオーブン、洗濯乾燥機を選択します)

電化製品のターンオン状態のしきい値:これの機能は、干渉をシールドすることです。つまり、値がこの値よりも低い場合、アプライアンスはオンになっていないと見なされます。

ノイズ除去しきい値:総作業量のノイズ除去変化より下の値はノイズと見なされ、無視されます。

アプライアンスデータの読み取り

fridge_data = np.load('UKData/Fridge freezer0.npy')
print(fridge_data.shape)
fridge_data = fridge_data[:1600000]
print(fridge_data.shape)
fridge_data = np.where(fridge_data > air_threshold,fridge_data,0)

television_data = np.load('UKData/Television0.npy')
print(television_data.shape)
television_data = television_data[:1600000]
print(television_data.shape)
television_data = np.where(television_data > air_threshold, television_data,0)

kettle_data = np.load('UKData/Kettle0.npy')
print(kettle_data.shape)
kettle_data = kettle_data[0:1600000]
print(kettle_data.mean)
kettle_data = np.where(kettle_data > air_threshold, kettle_data,0)

microwave_data = np.load('UKData/Microwave0.npy')
print(microwave_data.shape)
microwave_data = microwave_data[:1600000]
print(microwave_data.shape)
microwave_data = np.where(microwave_data > air_threshold, microwave_data,0)

washerdryer_data = np.load('UKData/Washer dryer0.npy')
print(washerdryer_data.shape)
washerdryer_data = washerdryer_data[:1600000]
print(washerdryer_data.shape)
washerdryer_data = np.where(washerdryer_data > air_threshold, washerdryer_data,0)

上記のコードは、以前に読んださまざまな電気機器からトレーニングに使用した電気機器を直接選択して読み取り、同じ長さ(1.600000)のデータ(有用な作業)を取り出します。同時に、air_thresholdのしきい値を下回る値は0と見なされます。目的は、乾燥を取り除くことです。

ラベルを作成する

def create_label(data, application_id, power_threshold, dimension):
    labels = np.zeros((len(data), dimension))
    for i, value in enumerate(data):
        if value[0] > power_threshold:
            labels[i,application_id] = 1
    return labels

上記の方法では、入力はデータ、アプライアンスID、オープン状態のしきい値、およびアプライアンスの数です。
出力は、アプライアンスの数の長さの1次元配列です。ある時点で、対応するアプライアンスの電源をオンにすると、対応するIDの位置は1になり、オフにすると、0になります。

データは各瞬間の負荷であり、ラベルは各瞬間の電気機器のオン状態です。

例:ラベルのデフォルトは、各時点で[0,0,0,0,0]です。ID1のアプライアンスが特定の時点でオンになっている場合、その時点でのラベルは[0,1,0,0,0]です。

次のコードは、5つのアプライアンスを生成するためのもので、各アプライアンスのラベルは

fridge_labels = create_label(fridge_data,fridge_id,fridge_threshold,dimension)
tv_labels = create_label(television_data,tv_id,tv_threshold,dimension)
kettle_labels = create_label(kettle_data,kettle_id,kettle_threshold,dimension)
microwave_labels = create_label(microwave_data,microwave_id,microwave_threshold,dimension)
washerdryer_labels = create_label(washerdryer_data,washerdryer_id,washerdryer_threshold,dimension)

データと標準化の組み合わせ

5つの電化製品のデータを統合し、有用な作業を直接加算して、あらゆる瞬間の有用な作業の合計にします。

上で生成されたラベルはアプライアンスごとに1つの列に対応しているため、ラベルラベルも一緒に結合され、直接追加できます。

sum_label = fridge_labels + tv_labels + kettle_labels + microwave_labels + washerdryer_labels
sum_data_num = fridge_data + television_data + kettle_data + microwave_data + washerdryer_data

それからあなたは見るために絵を描くことができます、私たちのラベル

#画图查看数据
epochs = range(1,len(sum_label[:,0])+1)
plt.plot(epochs,sum_label[:,0],label='fridge_labels')
plt.plot(epochs,sum_label[:,1],label='tv_labels')
plt.plot(epochs,sum_label[:,2],label='kettle_labels')
plt.plot(epochs,sum_label[:,3],label='microwave_labels')
plt.plot(epochs,sum_label[:,4],label='washerdryer_labels')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()

このように見えます、各色がオンになっています

ここに写真の説明を挿入

トレーニングの効率と効果を考慮して、データを次のように正規化します。

mean = sum_data_num[:1600000].mean(axis=0)
sum_data = sum_data_num - mean
std = sum_data[:1600000].std(axis=0)
sum_data /= std

イテレーター

1つの部屋で16wのデータしか使用しませんでしたが、後で大量のデータを検討するために、使用されるデータの量はまだ比較的多くなっています。メモリ使用量を削減するために、データ入力にイテレータを使用します。イテレーターがデータを取得してトレーニングイテレーションに入力するたび。

def generator(data, label, lookback, delay, min_index, max_index, shuffle=False, batch_size=128, step=1):
    if max_index is None:
        max_index = len(data) - delay - 1
    i = min_index + lookback
    while 1:
        if shuffle:
            rows = np.random.randint(min_index + lookback, max_index, size=batch_size)
        else:
            if i + batch_size >= max_index:
                i = min_index + lookback
            rows = np.arange(i, min(i + batch_size, max_index))
            i += len(rows)

        samples = np.zeros((len(rows),
                            lookback // step,
                            data.shape[-1]))
        targets = np.zeros((len(rows),dimension))
        for j, row in enumerate(rows):
            indices = range(rows[j] - lookback, rows[j], step)
            samples[j] = data[indices]
            targets[j] = label[rows[j] + delay]
        yield samples, targets

このロジックは少し複雑かもしれません。時間をかけてください。

パラメータ:
データ:データ。
ラベル:ラベル。
ルックバック:前のセクションで説明したウィンドウサイズ。これが振り返るウィンドウです。
delay:次の数フレームの結果を予測します(現在のフレームの分解を予測した結果であるため、ここではデフォルトで0に設定されているため、将来を調べる必要はありません)
min_index:データのどのフレームから開始して調べますか
max_index:データのどのフレームから開始して
シャッフルを終了します:ランダムかどうか
batch_size:反復
ステップの各バッチのデータを取得するたびに、数フレーム戻ります

このメソッドの意味は、合計データのmin_indexからmax_indexの範囲のデータを取得することであり、各バッチはbatch_sizeであり、ルックバックウィンドウサイズのデータ​​が取得されるたびに、1つのステップが取得されてから削除されます。一度。シャッフルは、ランダムに位置を開始するかどうかです。
遅延は無視できます。

本当にわからない場合は、グループ内で個人的にチャットするか、ライブ放送が開始されるのを待つことができます。

分割データイテレーター

まず、イテレーターのいくつかのハイパーパラメーターを定義します:
ウィンドウサイズ、ステップバック、現在のフレームの予測(delay = 0)、バッチサイズ

lookback = 20
step = 1
delay = 0
batch_size = 128

各パラメータの具体的なサイズ設定については、後の記事で各スーパーパラメータの機能と影響を分析するときに詳しく説明します。

次に、各イテレーターを定義します。

train_gen = generator(sum_data,
                      sum_label,
                      lookback=lookback,
                      delay=delay,
                      min_index=0,
                      max_index=800000,
                      shuffle=True,
                      step=step,
                      batch_size=batch_size)

val_gen = generator(sum_data,
                    sum_label,
                    lookback=lookback,
                    delay=delay,
                    min_index=800001,
                    max_index=1200000,
                    step=step,
                    batch_size=batch_size)
test_gen = generator(sum_data,
                    sum_label,
                    lookback=lookback,
                    delay=delay,
                    min_index=1200001,
                    max_index=None,
                    step=step,
                    batch_size=batch_size)

合計160wフレームのデータで、最初の80wをトレーニングとして、80-120wを検証として、120-160wをテストとして使用しました。

トレーニングセットデータはランダム処理を使用します。

次に、各反復のバッチ数を計算します

train_steps = 800000 // batch_size
val_steps = (1200000 - 800001 -lookback) // batch_size
test_steps = (len(sum_data) - 1200001 -lookback) // batch_size

テストする簡単なネットワークを構築する

#双向循环网络
model = Sequential()
model.add(layers.Bidirectional(
    layers.GRU(32,dropout=0.1), input_shape=(None,sum_data.shape[-1])))
model.add(layers.Dense(dimension,activation='sigmoid'))

model.compile(optimizer=RMSprop(), loss='binary_crossentropy',metrics=['acc'])
history = model.fit_generator(train_gen,
                              steps_per_epoch=train_steps,
                              epochs=2,
                              validation_data=val_gen,
                              validation_steps=val_steps)
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(loss)+1)

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and Validation loss')
# plt.legend()
plt.show()

plt.clf() #清空图表

acc_values = history.history['acc']
val_acc_values  = history.history['val_acc']

plt.plot(epochs,acc_values,'bo',label='Training acc') #bo是蓝色圆点
plt.plot(epochs,val_acc_values,'b',label='Validation acc') #b是蓝色实线
plt.title('Training and validation accuracy')
plt.legend()
plt.show()

ここで使用するのは、テストを実行するためのkerasメソッド、双方向GRU、完全に接続された出力の1つのレイヤーをリンクする方法です。

次に、パラメータ、オプティマイザ、および出力を設定し、2回繰り返します。

上記のネットワークは単なるテストであり、確立された完全なネットワーク構造ではないため、トレーニング後、モデルを保存しませんでした。

上記のプロセスに問題があるかどうかを確認するために実行できます。

実行後、2つのグラフが描画されます。1つは損失で、もう1つはaccです。

操作プロセスは次のとおりです。
ここに写真の説明を挿入

2回の繰り返しを静かに待ちます。
2回の繰り返しで、損失が減少して収束し、精度accが増加していることがわかります。検証accを見ると、トレーニングにおけるモデルの堅牢性が反映されます。
ここに写真の説明を挿入

ここに写真の説明を挿入

トレーニング用のネットワークを構築する

以下に、参考のために、一連の検証後の比較的高品質のネットワーク構造を示します。

ただし、さまざまなスーパーパラメータの調整など、さまざまなネットワーク構造の組み合わせを学習して実践できることを願っています。

たとえば、完全に接続されたネットワーク、畳み込みネットワーク、リカレントネットワークなどです。そして、上記のネットワークのさまざまな組み合わせ。

絶えず経験を積み重ねることによってのみ、より良いモデルを設計し、訓練することができます。

循环网络+一维卷积 
model = Sequential()
model.add(layers.Conv1D(32, 5, activation='relu', input_shape=(None,sum_data.shape[-1])))
model.add(layers.MaxPooling1D(3))
model.add(layers.Conv1D(32, 5, activation='relu'))
model.add(layers.LSTM(32, dropout=0.1))
# model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(dimension,activation='sigmoid'))

model.compile(optimizer=RMSprop(), loss='binary_crossentropy',metrics=['acc'])
history = model.fit_generator(train_gen,
                              steps_per_epoch=train_steps,
                              epochs=20,
                              validation_data=val_gen,
                              validation_steps=val_steps)

# model.save('model.h5') 

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(loss)+1)

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and Validation loss')
# plt.legend()
plt.show()

plt.clf() #清空图表

acc_values = history.history['acc']
val_acc_values  = history.history['val_acc']

plt.plot(epochs,acc_values,'bo',label='Training acc') #bo是蓝色圆点
plt.plot(epochs,val_acc_values,'b',label='Validation acc') #b是蓝色实线
plt.title('Training and validation accuracy')
plt.legend()
plt.show()

上記のモデル:1次元の畳み込みを使用してデータを調整し、LSTM(または双方向LSTM)が変化の法則を学習し、完全に接続されたレイヤーが結果を出力します。

ハイパーパラメータ(各レイヤーのサイズ、コンボリューションカーネル、ウィンドウサイズなど)とレイヤーの数(lstmの2つのレイヤーを使用できる、最後の2つのレイヤーを完全に接続できるなど)さまざまな組み合わせ、試してみる必要があります。グループに全員を歓迎します。実験結果について一緒に話し合います。

テストセット

最後に、テストセットを実行して、トレーニングに関係のないデータを予測します。

测试集测试
test_loss, test_acc = model.evaluate_generator(test_gen,steps=test_steps)
print('test acc : ', test_acc)

わからない場合やアイデアについて質問がある場合は、私にメッセージを残してください。
またはQQグループ1070535031

コード内の多くのパラメーターと使用法については、詳細な説明はありません。後で詳しく説明するために別の記事を書きます。

ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/wwb1990/article/details/109436914