QQ群1070535031
跟随上一篇的思路,本篇我们来实现整个流程。

实验需求

跟随本文进行学习和实验,需要前面博文中的环境,以及提取出来的UK数据。(学习分享——基于深度学习的NILM负荷分解(二)电器数据提取)

本文的代码思路在上一篇,本文着重介绍代码实现相关。思路方面看一下(学习分享——基于深度学习的NILM负荷分解(三)深度学习处理,基础思路)

实验环境:
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

挨个介绍一下上面的参数

dimension :是我们训练的电器的类别个数。5个是当前初步试验所设。

电器id:是我们选择出的五种电器的自增长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)

上面的代码,直接从之前我们读取出来的各个电器中,选择我们训练用的电器,读取出来,并取出相同长度(1600000)的数据(有用功)。同时将低于阈值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] = 1return labels

上面的方法,输入为数据,电器id,开启状态阈值,电器个数。
输出为,电器个数长度的一维数组。某时刻,对应电器开启时,对应id的位置为1,关闭时为0.

data是每一个时刻的负荷,label是每一个时刻的电器开启状态。

举例:label默认每一时刻是 [0,0,0,0,0],假如某时刻id为1的电器开启,则该时刻的label为 [0,1,0,0,0]

下面的代码是分别生成五个电器,每个电器的label

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)

组合数据与标准化

我们将五个电器的数据进行整合,有用功直接加在一起,变成每一个时刻有用功的和。

label标签也组合在一起,因为上面生成的标签,每个电器对应一列,所以直接相加即可。

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

然后可以画个图看一下,我们的label

#画图查看数据
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

迭代器

我们只用了一个房间的160w的数据,但所用的数据量还是比较大的,为了之后更大量数据考虑。我们使用迭代器来进行数据输入,以减小内存的使用。每次迭代器来取数据输入训练迭代。

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 - 1i = min_index + lookbackwhile 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 + lookbackrows = 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

这一块逻辑可能有点复杂,慢慢看。

参数:
data:数据。
label:标签。
lookback:上一节提到的窗口大小,这里是往回看的窗口。
delay:预测后面几帧的结果(这里我们默认为0,因为是预测分解当前帧的结果,不需要往未来看)
min_index:从数据的哪一帧开始看
max_index:从数据的哪一帧结束
shuffle:是否随机
batch_size:迭代中每一个批量的个数
step:每取一次数据,向后跳几帧

这个方法的意思,就是取总的数据中的min_index到max_index这段范围中的数据,每个批量是batch_size,每次往回取lookback窗口大小的数据,取完一次向后跳step个再取下一次。shuffle为是否随机开始取的位置。
delay可以忽略。

实在看不懂的,可以群里面私聊我,或者等我开直播讲。

拆分数据迭代器

首先定义一些迭代器的超参
分别是窗口大小,向后跳的步伐,预测当前帧(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,链接一层全连接输出。

然后设置一下参数,优化器,以及输出,迭代2次。

训练结束我并没有存模型,因为上面这个网络只是测试一下,并不是我们既定的完整网络结构。

可以跑一下,看看上面的流程有没有问题。

跑完会绘制出两个图,一个是loss,一个是acc。

运行过程中如下:

静静等待2次迭代。
可以看到两次迭代,loss在下降收敛,准确率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()

我上述这个模型:一维卷积作用为提炼数据,LSTM(或双向LSTM)来学习变化规律,全连接层输出结果。

超参(例如每层的大小,卷积核,窗口大小等等等)和层数(可以两层lstm,可以最后两层全连接等地的的) 各种组合,需要尝试,欢迎大家来群里共同探讨实验结果。

测试集

最后跑测试集,进行在未参与训练的数据中进行预测。

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

有不懂的,或者想法问题,可以留言我。
或者QQ群1070535031

对于代码中的很多参数和用法,没有详细描述。后面我单独在写一篇来详说吧。

学习分享——基于深度学习的NILM负荷分解(四)深度学习实现,代码讲解相关推荐

  1. 学习分享——基于深度学习的NILM负荷分解(三)深度学习处理,基础思路

    我来继续填坑了~~ 给大家两周时间自习深度学习(磨蹭了两周) 不知道同学们的基础打得如何了哈 QQ群1070535031 我分两篇写网络训练的相关,本文介绍整个思路流程,下一篇提供实操代码和相关注释讲 ...

  2. 学习分享——基于深度学习的NILM负荷分解(二)电器数据提取

    前一阵参加比赛,NILM就放了放,开始填坑... GOGOGO~ 数据准备 根据上一篇中提到的,我这里使用的是UK-DALE 没有下载的同学可以回到上一篇看一下(学习分享--基于深度学习的NILM负荷 ...

  3. 基于SSM的物流仓储管理系统(包远程安装配置和代码讲解)

          博主介绍:✌在职Java研发工程师.专注于程序设计.源码分享.技术交流.专注于Java技术领域和毕业设计✌ 项目名称 基于SSM的物流仓储管理系统 演示视频 基于SSM的物流仓储管理系统( ...

  4. 学习分享——基于深度学习的NILM负荷分解(一)对DL的看法准备工作

    好啦,我来填坑啦哈哈 经过了几个月的对深度学习的学习.了解和实践, 对于用深度学习来做NILM的经验也是积累了不少. 在此,做以小结. 在此,感谢~柳柳,小张,小田,小刘的支持和鼓励. 话不多说,下面 ...

  5. 【深度学习】基于web端和C++的两种深度学习模型部署方式

    深度学习 Author:louwill Machine Learning Lab 本文对深度学习两种模型部署方式进行总结和梳理.一种是基于web服务端的模型部署,一种是基于C++软件集成的方式进行部署 ...

  6. 基于SpringBoot视频学习系统|视频点播系统的设计与实现【Java毕业设计·安装调试·代码讲解·文档报告】

  7. [光速QA][linux学习篇]基于韦东山I.MX6ULL pro开发板的学习笔记

    #前言: CSDN上已经有了太多的教程,我决定使用一种很新的方式记录自己的学习过程,如果对你有帮助就点个赞吧!一篇博文但是会长期更新(争取). 光速QA,希望面试官和面试者都可以给我这里找到灵感,如果 ...

  8. 基于Pytorch的MNIST手写数字识别实现(含代码+讲解)

    说明:本人也是一个萌新,也在学习中,有代码里也有不完善的地方.如果有错误/讲解不清的地方请多多指出 本文代码链接: GitHub - Michael-OvO/mnist: mnist_trained_ ...

  9. 基于信息内容的词林词语相似度计算 - 论文及代码讲解

    文章目录 论文 同义词林简介 特点 代码 获取词的编码 求IC值 求相似度 选取相似度最大值 论文:<基于信息内容的词林词语相似度计算 >-2018-彭琦,朱新华等 查看 代码:https ...

最新文章

  1. 聊聊高并发(十六)实现一个简单的可重入锁
  2. SQLite剖析之临时文件、内存数据库
  3. js对html进行转义和反转义的操作
  4. go语言goroutine的取消
  5. python字典更改元素_python – 返回带有一个已更改元素的字典
  6. 二维高斯曲面拟合法求取光斑中心及算法的C++实现
  7. explorer.exe中发生未处理的win32异常
  8. 少编码多思考:代码越多 问题越多
  9. Linux必会原理之软连接文件和硬链接文件的区别
  10. ps去水印教程_图片如何用PS去水印?ps去水印教程,让你1秒学会!
  11. 微信公众号里面使用定位
  12. 菜鸟站长之家教各位菜鸟站长用WordPress如何给文章生成推广二维码
  13. 【奥斯卡理财星体系 第五章】丨手把手教你从零开始搭建资产配置
  14. 一种技能的形成有哪些阶段?
  15. 上号神器,穿越火线扫码登录教程
  16. 爱说分手 吹了9个男朋友
  17. 等维递推GM(1,1)模型、无偏灰色模型
  18. 软考A计划-试题模拟含答案解析-卷十七
  19. ubuntu 如何分屏(双屏显示)
  20. 2005年上半年(第21次)全国计算机等级考试(NCRE)广东考区报考简章

热门文章

  1. 曲柄手柄行业调研报告 - 市场现状分析与发展前景预测
  2. 【Android开发日志】Kotlin 面向对象编程 - 类与对象(11)
  3. 东芝面向消费设备和工业设备推出基于Arm(R) Cortex(R)-M3且具备先进功能的低功耗微控制器
  4. JavaSE基础项目:拼图小游戏
  5. win10 定时重启脚本
  6. 我的世界服务器文件翻译,【我的世界】options.txt文件翻译(无限夜视就是这个)...
  7. 【ChatGPT情商大考验】ChatGPT教我谈恋爱
  8. Unable to initialize GTK: could not open display
  9. 教你在CAD中快速测量异形面积
  10. Android:从简历到offer直通车,跳槽大厂必备宝典,kotlinandroid开发教程