├── environment.yml
├── data
├── REFIT
│ ├── after_align
│ │ └── .gitkeep
│ ├── after_culling
│ │ └── .gitkeep
│ ├── appliance_data
│ │ └── .gitkeep
│ ├── original_data
│ │ └── .gitkeep
│ └── description.txt
└── UK_DALE
│ ├── house_1
│ └── .gitkeep
│ ├── house_2
│ └── .gitkeep
│ ├── house_3
│ └── .gitkeep
│ ├── house_4
│ └── .gitkeep
│ ├── house_5
│ └── .gitkeep
│ └── description.txt
├── image
└── ukdale_washingmachine.png
├── .idea
├── misc.xml
├── vcs.xml
├── modules.xml
└── seq2subseq.iml
├── preprocess
├── uk_dale_cfg.py
├── refit_cfg.py
├── uk_dale_process.py
└── refit_process.py
├── README.md
└── model
├── ukdale_u.py
└── refit_u.py
/environment.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DLZRMR/seq2subseq/HEAD/environment.yml
--------------------------------------------------------------------------------
/data/REFIT/after_align/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/UK_DALE/house_1/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/UK_DALE/house_2/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/UK_DALE/house_3/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/UK_DALE/house_4/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/UK_DALE/house_5/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/REFIT/after_culling/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/REFIT/appliance_data/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/data/REFIT/original_data/.gitkeep:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file !.gitkeep
--------------------------------------------------------------------------------
/image/ukdale_washingmachine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DLZRMR/seq2subseq/HEAD/image/ukdale_washingmachine.png
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/data/REFIT/description.txt:
--------------------------------------------------------------------------------
1 | The original data should be put in folder 'original_data'. In the pre-process stage, a lot of intermediate data will generate, you can delete it manually or modify the code that we provided.
--------------------------------------------------------------------------------
/data/UK_DALE/description.txt:
--------------------------------------------------------------------------------
1 | The house and appliance information that we used for training and test can be found in folder 'preprocess/uk_dale.cfg'. You should put the corresponding appliance data files in the correct house.
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/seq2subseq.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/preprocess/uk_dale_cfg.py:
--------------------------------------------------------------------------------
1 | # House_id : Channel_id
2 | Kettle = {
3 | 1: 10, 2: 8, 3: 2, 5: 18
4 | }
5 | Microwave = {
6 | 1: 13, 2: 15, 5: 23
7 | }
8 | Fridge = {
9 | 1: 12, 2: 14, 4: 5, 5: 19
10 | }
11 | Dishwasher = {
12 | 1: 6, 2: 13, 5: 22
13 | }
14 | WashingMachine = {
15 | 1: 5, 2: 12, 5: 24
16 | }
17 |
18 | train = {
19 | 'WashingMachine': {
20 | 1: 5, 5: 24
21 | },
22 | 'Kettle': {
23 | 1: 10, 3: 2, 5: 18
24 | },
25 | 'Fridge': {
26 | 1: 12, 4: 5, 5: 19
27 | },
28 | 'Dishwasher': {
29 | 1: 6, 5: 22
30 | },
31 | 'Microwave': {
32 | 1: 13, 5: 23
33 | }
34 | }
35 |
36 | test = {
37 | 'WashingMachine': {
38 | 2: 12
39 | },
40 | 'Kettle': {
41 | 2: 8
42 | },
43 | 'Fridge': {
44 | 2: 14
45 | },
46 | 'Dishwasher': {
47 | 2: 13
48 | },
49 | 'Microwave': {
50 | 2: 15
51 | }
52 | }
53 |
54 | window_width = {
55 | 'WashingMachine': 1024,
56 | 'Kettle': 1024,
57 | 'Fridge': 1024,
58 | 'Dishwasher': 1024,
59 | 'Microwave': 1024
60 | }
61 | negative_ratio = {
62 | 'WashingMachine': 1,
63 | 'Kettle': 1,
64 | 'Fridge': 1,
65 | 'Dishwasher': 1,
66 | 'Microwave': 1
67 | }
68 |
69 | outlier_threshold = {
70 | 'WashingMachine': 3,
71 | 'Kettle': 3,
72 | 'Fridge': 3,
73 | 'Dishwasher': 3,
74 | 'Microwave': 3
75 | }
76 |
77 | positive_negative_threshold = {
78 | 'WashingMachine': 1500,
79 | 'Kettle': 1500,
80 | 'Fridge': 1500,
81 | 'Dishwasher': 1500,
82 | 'Microwave': 1500
83 | }
84 | on_power_threshold = {
85 | 'WashingMachine': 20,
86 | 'Kettle': 1000,
87 | 'Fridge': 50,
88 | 'Dishwasher': 10,
89 | 'Microwave': 200
90 | }
91 | random_clip = {
92 | 'WashingMachine': 5000,
93 | 'Kettle': 5000,
94 | 'Fridge': 5000,
95 | 'Dishwasher': 5000,
96 | 'Microwave': 5000
97 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # SEQUENCE-TO-SUBSEQUENCE LEARNING WITH CONDITIONAL GAN FOR POWER DISAGGREGATION
3 | This code implements the seqence-to-subseqence (seq2subseq) learning model. This model makes a trade-off between sequence-to-sequence (seq2seq) and sequence-to-point (seq2point) method, thus, balancing the convergence difficulty in deep neural networks and the amount of computation during the inference period. In addition, we apply U-Net [1] and Instance Normalization [2] techniques to our model. We build our model based on pix2pix [3] under Tensorflow framework [4]. Thanks a lot!
4 |
5 |
6 | References:
7 |
8 | [1] Olaf Ronneberger, Philipp Fischer, and Thomas Brox, “U-net: Convolutional networks for biomedical image segmentation,” in International Conference on Medical Image Computing & Computer-assisted Intervention, 2015.
9 |
10 | [2] Dmitry Ulyanov, Andrea Vedaldi, and Victor S. Lempitsky, “Instance normalization: The missing ingredient for fast stylization,” CoRR, vol. abs/1607.08022, 2016.
11 |
12 | [3] https://phillipi.github.io/pix2pix/
13 |
14 | [4] https://github.com/affinelayer/pix2pix-tensorflow
15 |
16 | ## Setup
17 | - Create your own virtual environment with Python > 3.5
18 | - Configure deep learning environment with Tensorflow (GPU edition) > 1.4.1 + cuDNN
19 | - Install other necessary softwares, such as Matplotlib, Scikit-learn etc.
20 | - Clone this repository
21 |
22 | The environments we used are listed in the file `environment.yml`. If you use `conda`, you can use `conda env create -f environment.yml` to set up the environment.
23 |
24 |
25 | ## Datasets and preprocessing
26 |
27 | ### REFIT
28 | Download the REFIT raw data from the original website (https://pureportal.strath.ac.uk/en/datasets/refit-electrical-load-measurements-cleaned).
29 |
30 |
31 | ### UK-DALE
32 | Download the UK-DALE raw data from the original website (https://ukerc.rl.ac.uk/DC/cgi-bin/edc_search.pl?GoButton=Detail&WantComp=41).
33 |
34 |
35 | ## Training & Test
36 | We recommend importing the project into Pycharm (https://www.jetbrains.com/pycharm/) for your future research.
37 |
38 | ### Tips
39 | You can look at the loss and computation graph using tensorboard:
40 | ```sh
41 | tensorboard --logdir= 'the output path'
42 | ```
43 |
44 |
45 | ## Code validation and experiment results
46 | We evaluate our model on a Linux machine with a Nvidia RTX 2080 GPU and Core i7 9700K CPU.
47 |
48 | Example outputs of Washing Machine on ”unseen” house 2 from UK-DALE (We enlarge the right part of the figure to make it more clear):
49 | 
50 |
51 |
52 | ## Acknowledgments
53 | This research is sponsored by National Key R&D Program of China(2017YFB0902600); State Grid Corporation of China Project (SGJS0000DKJS1700840) Research and Application of Key Technology for Intelligent Dispatching and Security Early-warning of Large Power Grid.
54 |
--------------------------------------------------------------------------------
/preprocess/refit_cfg.py:
--------------------------------------------------------------------------------
1 |
2 | missing_house = [13, 14]
3 |
4 | kettle = {
5 | 2: 8, 3: 9, 4: 9, 5: 8, 6: 7, 7: 9, 8: 9, 9: 7, 11: 7, 17: 8, 19: 5, 20: 9
6 | }
7 | kettle_train = {
8 | 2: 8, 3: 9, 4: 9, 5: 8, 6: 7, 8: 9, 9: 7, 17: 8, 19: 5
9 | }
10 | kettle_validation = {
11 | 7: 9
12 | }
13 | kettle_tv = {
14 | 11: 7, 20: 9, 3: 9, 4: 9, 5: 8, 6: 7, 8: 9, 9: 7, 17: 8, 19: 5, 7: 9
15 | }
16 | kettle_test = {
17 | 2: 8
18 | }
19 |
20 |
21 | microwave = {
22 | 2: 5, 3: 8, 4: 8, 5: 7, 6: 6, 10: 8, 11: 6, 12: 5, 17: 7, 19: 4, 20: 8
23 | }
24 | microwave_train = {
25 | 2: 5, 3: 8, 4: 8, 6: 6, 11: 6, 12: 5, 17: 7, 20: 8
26 | }
27 | microwave_validation = {
28 | 10: 8
29 | }
30 | microwave_tv = {
31 | 2: 5, 3: 8, 6: 6, 11: 6, 12: 5,4: 8 , 20: 8, 10: 8, 5: 7, 19: 4
32 | }
33 | microwave_test = {
34 | 17: 7
35 | }
36 |
37 |
38 | fridge = {
39 | 2: 1, 5: 1, 9: 1, 12: 1, 15: 1, 19: 1
40 | }
41 | fridge_train = {
42 | 5: 1, 9: 1, 2: 1, 19: 1
43 | }
44 | fridge_validation = {
45 | 15: 1
46 | }
47 | fridge_tv = {
48 | 5: 1, 9: 1, 2: 1, 19: 1, 15: 1
49 | }
50 | fridge_test = {
51 | 12: 1
52 | }
53 |
54 |
55 | dishwasher = {
56 | 1: 6, 2: 3, 3: 5, 5: 4, 7: 6, 9: 4, 10: 6, 16: 6, 18: 6, 20: 5
57 | }
58 | dishwasher_train = {
59 | 1: 6, 3: 5, 5: 4, 7: 6, 10: 6, 16: 6, 20: 5
60 | }
61 | dishwasher_validation = {
62 | 18: 6
63 | }
64 | dishwasher_tv = {
65 | 1: 6, 3: 5, 5: 4, 7: 6, 10: 6, 16: 6, 20: 5, 18: 6
66 | }
67 | dishwasher_test = {
68 | 2: 3, 9: 4
69 | }
70 |
71 |
72 | washingmachine = {
73 | 1: 5, 2: 2, 3: 6, 5: 3, 7: 5, 8: 4, 9: 3, 10: 5, 15: 3, 16: 5, 17: 4, 18: 5, 19: 2, 20: 4
74 | }
75 | washingmachine_train = {
76 | 1: 5, 2: 2, 3: 6, 7: 5, 8: 4, 9: 3, 10: 5, 15: 3, 17: 4, 18: 5, 20: 4
77 | }
78 | washingmachine_validation = {
79 | 19: 2
80 | }
81 | washingmachine_tv = {
82 | 1: 5, 2: 2, 3: 6, 7: 5, 8: 4, 9: 3, 10: 5, 15: 3, 17: 4, 18: 5, 20: 4, 19: 2
83 | }
84 | washingmachine_test = {
85 | 5: 3, 16: 5
86 | }
87 |
88 | separation_threshold = 400
89 |
90 | window_width = {
91 | 'WashingMachine': 1024,
92 | 'Kettle': 256,
93 | 'Microwave': 256,
94 | 'Fridge': 1024,
95 | 'Dishwasher': 1024
96 | }
97 |
98 | random_clip = {
99 | 'WashingMachine': 10000,
100 | 'Kettle': 10000,
101 | 'Microwave': 10000,
102 | 'Fridge': 10000,
103 | 'Dishwasher': 10000
104 | }
105 |
106 | negative_ratio = {
107 | 'WashingMachine': 1,
108 | 'Kettle': 0.2,
109 | 'Microwave': 0.2,
110 | 'Fridge': 1,
111 | 'Dishwasher': 1
112 | }
113 |
114 | train_validation = {
115 | 'WashingMachine': {
116 | 1: 5, 2: 2, 3: 6, 7: 5, 9: 3, 10: 5, 15: 3, 17: 4, 18: 5, 20: 4, 19: 2, 5: 3, 16: 5
117 | },
118 | 'Kettle': {
119 | 3: 9, 4: 9, 5: 8, 6: 7, 8: 9, 9: 7, 17: 8, 19: 5, 7: 9, 11: 7, 20: 9
120 | },
121 | 'Microwave': {
122 | 2: 5, 3: 8, 6: 6, 11: 6, 12: 5, 17: 7, 20: 8, 10: 8, 5: 7, 19: 4
123 | },
124 | 'Fridge': {
125 | 5: 1, 9: 1, 2: 1, 19: 1, 15: 1
126 | },
127 | 'Dishwasher': {
128 | 1: 6, 3: 5, 5: 4, 7: 6, 10: 6, 16: 6, 18: 6, 2: 3, 9: 4
129 | }
130 | }
131 | test = {
132 | 'WashingMachine': {
133 | 8: 4
134 | },
135 | 'Kettle': {
136 | 2: 8
137 | },
138 | 'Microwave': {
139 | 4: 8
140 | },
141 | 'Fridge': {
142 | 15: 1
143 | },
144 | 'Dishwasher': {
145 | 20: 5
146 | }
147 | }
148 |
149 | cull_dict = {
150 | 'WashingMachine': {
151 | 1: [[0, 130000], [1120000, 1240000], [1800000, 1920000], [4970000, 5110000], [5750000, 5900000]],
152 | 2: [[2300000, 2400000], [4100000, 4180000]],
153 | 3: [[50000, 250000]],
154 | 10: [[770000, 1070000], [4250000, 4550000]],
155 | 18: [[1450000, 1750000], [3400000, 3600000]],
156 | 20: [[3550000, 3850000]]
157 | },
158 | 'Kettle': {
159 | 3: [[50000, 260000]],
160 | 4: [[1180000, 1360000]],
161 | 5: [[2910000, 3080000], [5020000, 5110000]],
162 | 9: [[480000, 680000], [1920000, 2050000]],
163 | 20: [[3670000, 3810000]]
164 | },
165 | 'Microwave': {
166 | 4: [[1180000, 1360000], [2880000, 3400000]],
167 | 10: [[770000, 1080000]],
168 | 20: [[3700000, 3800000]]
169 | },
170 | 'Fridge': {
171 | 9: [[21000, 73100], [478000, 678400]]
172 | },
173 | 'Dishwasher': {
174 | 10: [[757500, 1091000], [4250000, 4550000]],
175 | 18: [[650000, 840000], [1450000, 1780000], [3400000, 3630000]],
176 | 20: [[460000, 750000], [3530000, 3870000]]
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/preprocess/uk_dale_process.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.append('preprocess')
3 | import matplotlib
4 | matplotlib.use("TkAgg")
5 | import matplotlib.pyplot as plt
6 | import matplotlib.gridspec as gridspec
7 | from matplotlib.pyplot import savefig
8 | import numpy as np
9 | import uk_dale_cfg
10 | import os
11 | import random
12 | from os.path import join
13 |
14 | name = ['WashingMachine', 'Kettle', 'Microwave', 'Fridge', 'Dishwasher']
15 | appliance_dict = {
16 | 'WashingMachine': uk_dale_cfg.WashingMachine,
17 | 'Kettle': uk_dale_cfg.Kettle,
18 | 'Microwave': uk_dale_cfg.Microwave,
19 | 'Fridge': uk_dale_cfg.Fridge,
20 | 'Dishwasher': uk_dale_cfg.Dishwasher
21 | }
22 | base_path = 'data/UK_DALE'
23 |
24 |
25 | # step1: convert .dat to .npy
26 | def convertnpy():
27 | for house_id in range(1, 6):
28 | aggregate_path = join(base_path, 'house_%d/channel_%d.dat' % (house_id, 1))
29 | aggregate_data = []
30 | with open(aggregate_path, 'r') as f:
31 | lines = f.readlines()
32 | for line in lines:
33 | s = line.split()
34 | aggregate_data.append([int(s[0]), int(s[1])])
35 | np.save(join(base_path, 'house_%s\\main.npy' % house_id), aggregate_data)
36 | print('House: %d finished!' % house_id)
37 |
38 | for appliance_name in name:
39 | for house_id, channel_id in appliance_dict[appliance_name].items():
40 | appliance_path = join(base_path, 'house_%d/channel_%d.dat' % (house_id, channel_id))
41 | print('Appliance: %s in house %s Load!' % (appliance_name, house_id))
42 | appliance_data = []
43 |
44 | with open(appliance_path, 'r') as f:
45 | lines = f.readlines()
46 | for line in lines:
47 | s = line.split()
48 | appliance_data.append([int(s[0]), int(s[1])])
49 | np.save(join(base_path, 'house_%d\\%s_appliance.npy' % (house_id, appliance_name)), appliance_data)
50 | print('Appliance: %s House: %d finished!' % (appliance_name, house_id))
51 |
52 |
53 | # step2: align according to timestamp
54 | def align():
55 | for appliance_name in name:
56 | aggregate_new = []
57 | appliance_new = []
58 | for house_id, c in uk_dale_cfg.train[appliance_name].items():
59 | aggregate_data = np.load(join(base_path, 'house_%d\\main.npy' % house_id))
60 | appliance_data = np.load(join(base_path, 'house_%d\\%s_appliance.npy' % (house_id, appliance_name)))
61 |
62 | aggregate_index = 0
63 | appliance_index = 0
64 | if appliance_data[0][0] < aggregate_data[0][0]:
65 | print('Appliance time is ahead of aggregate time!')
66 | for i in range(0, len(appliance_data)):
67 | if appliance_data[i][0] > aggregate_data[0][0]:
68 | appliance_index = i
69 |
70 | for i in range(appliance_index, len(appliance_data)):
71 | appliance_time = appliance_data[i][0]
72 | front = aggregate_index
73 | behind = -1
74 | for j in range(aggregate_index, len(aggregate_data)):
75 | if aggregate_data[j][0] <= appliance_time:
76 | front = j
77 | else:
78 | behind = j
79 | d_1 = abs(appliance_time - aggregate_data[front][0])
80 | d_2 = abs(appliance_time - aggregate_data[behind][0])
81 | if d_1 <= d_2:
82 | aggregate_new.append(aggregate_data[front][1])
83 | appliance_new.append(appliance_data[i][1])
84 | else:
85 | aggregate_new.append(aggregate_data[behind][1])
86 | appliance_new.append(appliance_data[i][1])
87 | aggregate_index = front
88 | break
89 | if i % 10000 == 0:
90 | print('Appliance: %s, House: %s, processing: %f' % (appliance_name, house_id, i/len(appliance_data)))
91 | print('Appliance: %s, House: %s finished!' % (appliance_name, house_id))
92 | np.save(join(base_path, '%s_main_train.npy' % appliance_name), aggregate_new)
93 | np.save(join(base_path, '%s_appliance_train.npy' % appliance_name), appliance_new)
94 | print('Appliance - train : %s finished!' % appliance_name)
95 |
96 | aggregate_new = []
97 | appliance_new = []
98 | house_id = 2
99 | aggregate_data = np.load(join(base_path, 'house_%d\\main.npy' % house_id))
100 | appliance_data = np.load(join(base_path, 'house_%d\\%s_appliance.npy' % (house_id, appliance_name)))
101 |
102 | aggregate_index = 0
103 | appliance_index = 0
104 | if appliance_data[0][0] < aggregate_data[0][0]:
105 | print('Appliance time is ahead of aggregate time!')
106 | for i in range(0, len(appliance_data)):
107 | if appliance_data[i][0] < aggregate_data[0][0]:
108 | appliance_index = i
109 |
110 | for i in range(appliance_index, len(appliance_data)):
111 | appliance_time = appliance_data[i][0]
112 | front = aggregate_index
113 | behind = -1
114 | for j in range(aggregate_index, len(aggregate_data)):
115 | if aggregate_data[j][0] <= appliance_time:
116 | front = j
117 | else:
118 | behind = j
119 | d_1 = abs(appliance_time - aggregate_data[front][0])
120 | d_2 = abs(appliance_time - aggregate_data[behind][0])
121 | if d_1 <= d_2:
122 | aggregate_new.append(aggregate_data[front][1])
123 | appliance_new.append(appliance_data[i][1])
124 | else:
125 | aggregate_new.append(aggregate_data[behind][1])
126 | appliance_new.append(appliance_data[i][1])
127 | aggregate_index = front
128 | break
129 | if i % 10000 == 0:
130 | print('Appliance: %s, House: %s, processing: %f' % (
131 | appliance_name, house_id, i / len(appliance_data)))
132 | print('Appliance: %s, House: %s finished!' % (appliance_name, house_id))
133 | np.save(join(base_path, '%s_main_test.npy' % appliance_name), aggregate_new)
134 | np.save(join(base_path, '%s_appliance_test.npy' % appliance_name), appliance_new)
135 | print('Appliance - test : %s finished!' % appliance_name)
136 |
137 |
138 | # step3: observe the total sequence
139 | def view_total():
140 | if not os.path.exists(join(base_path, 'total_view')):
141 | os.mkdir(join(base_path, 'total_view'))
142 | for appliance_name in name:
143 | aggregate_data = np.load(join(base_path, '%s_main.npy' % appliance_name))
144 | appliance_data = np.load(join(base_path, '%s_appliance.npy' % appliance_name))
145 |
146 | plt.figure(('Appliance: %s' % appliance_name), figsize=(30, 20), dpi=200)
147 | plt.subplot(211)
148 | plt.plot(aggregate_data)
149 | plt.subplot(212)
150 | plt.plot(appliance_data)
151 | savefig('data\\UK_DALE\\total_view\\%s' % appliance_name)
152 |
153 |
154 | def separate():
155 | for appliance_name in name:
156 | window_width = uk_dale_cfg.window_width[appliance_name]
157 | scale_up = int(1024 / window_width)
158 | print('Scale up %d' % scale_up)
159 | data_path = 'data\\UK_DALE'
160 | count = 0
161 | negative_ratio = uk_dale_cfg.negative_ratio[appliance_name]
162 | positive_negative_threshold = uk_dale_cfg.positive_negative_threshold[appliance_name]
163 | outlier_length = uk_dale_cfg.outlier_threshold[appliance_name]
164 | on_power_threshold = uk_dale_cfg.on_power_threshold[appliance_name]
165 |
166 | appliance_new = []
167 | main_new = []
168 |
169 | def exception_process(d):
170 | one = 0
171 | current_length = 0
172 | clip_index = 0
173 | negative = 1
174 | for i in range(len(d)):
175 | current_number = d[i]
176 | if current_number > on_power_threshold:
177 | negative = 0
178 | if one == 0:
179 | if current_number > 0:
180 | one = 1
181 | current_length += 1
182 | clip_index = i
183 | else:
184 | if current_number > 0:
185 | current_length += 1
186 | else:
187 | if current_length <= outlier_length:
188 | for j in range(clip_index, i):
189 | d[j] = 0
190 | one = 0
191 | current_length = 0
192 | if negative == 1:
193 | for j in range(len(d)):
194 | d[j] = 0
195 | return d
196 |
197 | appliance_data = np.load(join(base_path, '%s_appliance_train.npy' % appliance_name))
198 | appliance_data_test = np.load(join(base_path, '%s_appliance_test.npy' % appliance_name))
199 | main_data = np.load(join(data_path, '%s_main_train.npy' % appliance_name))
200 | main_data_test = np.load(join(data_path, '%s_main_test.npy' % appliance_name))
201 | print('Appliance: %s data load complete!' % appliance_name)
202 |
203 | # train process
204 | current_head = 1
205 | data_length = len(appliance_data)
206 | end = data_length - window_width - 1
207 | while current_head < end:
208 | temp_main = []
209 | temp_appliance = []
210 | t_a = []
211 | data_ = exception_process(appliance_data[current_head:current_head + window_width])
212 | for i in range(current_head, current_head+window_width):
213 | for k in range(scale_up):
214 | temp_main.append(main_data[i])
215 | temp_appliance.append(data_[i-current_head])
216 | t_a.append(data_[i-current_head])
217 | current_head += int(window_width/2)
218 | sum_ = np.sum(t_a)
219 | if sum_ < positive_negative_threshold:
220 | r = random.random()
221 | if r > negative_ratio:
222 | continue
223 | appliance_new.append(temp_appliance)
224 | main_new.append(temp_main)
225 | count += 1
226 | if count % 1000 == 0:
227 | print('Train - Type 1, Appliance: %s processing: %f' % (appliance_name, (current_head / data_length)))
228 |
229 | data_length = len(appliance_data) - window_width-1
230 | random_clip = uk_dale_cfg.random_clip[appliance_name]
231 | for j in range(random_clip):
232 | r = random.random()
233 | start = int(r * data_length)
234 | temp_main = []
235 | temp_appliance = []
236 | t_a = []
237 | data_ = exception_process(appliance_data[start:start + window_width])
238 | for i in range(start, start+window_width):
239 | for k in range(scale_up):
240 | temp_main.append(main_data[i])
241 | temp_appliance.append(data_[i-start])
242 | t_a.append(data_[i-start])
243 | sum_ = np.sum(t_a)
244 | if sum_ < positive_negative_threshold:
245 | r = random.random()
246 | if r > negative_ratio:
247 | continue
248 | appliance_new.append(temp_appliance)
249 | main_new.append(temp_main)
250 | count += 1
251 | if count % 1000 == 0:
252 | print('Train - Type 2, Appliance: %s processing: %f' % (appliance_name, (j / random_clip)))
253 | print('Appliance: %s complete!' % appliance_name)
254 | np.save(os.path.join(data_path, '%s\\appliance_train.npy' % appliance_name), appliance_new)
255 | np.save(os.path.join(data_path, '%s\\main_train.npy' % appliance_name), main_new)
256 |
257 | # test process
258 | current_head = 1
259 | data_length = len(appliance_data_test)
260 | end = data_length - window_width - 1
261 | while current_head < end:
262 | temp_main = []
263 | temp_appliance = []
264 | t_a = []
265 | data_ = exception_process(appliance_data_test[current_head:current_head + window_width])
266 | for i in range(current_head, current_head+window_width):
267 | for k in range(scale_up):
268 | temp_main.append(main_data_test[i])
269 | temp_appliance.append(data_[i-current_head])
270 | t_a.append(data_[i-current_head])
271 | current_head += int(window_width/2)
272 | sum_ = np.sum(t_a)
273 | if sum_ < positive_negative_threshold:
274 | r = random.random()
275 | if r > negative_ratio:
276 | continue
277 | appliance_new.append(temp_appliance)
278 | main_new.append(temp_main)
279 | count += 1
280 | if count % 1000 == 0:
281 | print('Test - Type 1, Appliance: %s processing: %f' % (appliance_name, (current_head / data_length)))
282 |
283 | data_length = len(appliance_data_test) - window_width-1
284 | random_clip = uk_dale_cfg.random_clip[appliance_name]
285 | for j in range(random_clip):
286 | r = random.random()
287 | start = int(r * data_length)
288 | temp_main = []
289 | temp_appliance = []
290 | t_a = []
291 | data_ = exception_process(appliance_data_test[start:start + window_width])
292 | for i in range(start, start+window_width):
293 | for k in range(scale_up):
294 | temp_main.append(main_data_test[i])
295 | temp_appliance.append(data_[i-start])
296 | t_a.append(data_[i-start])
297 | sum_ = np.sum(t_a)
298 | if sum_ < positive_negative_threshold:
299 | r = random.random()
300 | if r > negative_ratio:
301 | continue
302 | appliance_new.append(temp_appliance)
303 | main_new.append(temp_main)
304 | count += 1
305 | if count % 1000 == 0:
306 | print('Test - Type 2, Appliance: %s processing: %f' % (appliance_name, (j / random_clip)))
307 | print('Appliance: %s complete!' % appliance_name)
308 | np.save(os.path.join(data_path, '%s\\appliance_test.npy' % appliance_name), appliance_new)
309 | np.save(os.path.join(data_path, '%s\\main_test.npy' % appliance_name), main_new)
310 |
311 |
312 | def convert512():
313 | for appliance_name in name:
314 | appliance_train = np.load(join(base_path, '%s\\appliance_train.npy' % appliance_name))
315 | appliance_test = np.load(join(base_path, '%s\\appliance_test.npy' % appliance_name))
316 | train_new = []
317 | test_new = []
318 | for i in range(len(appliance_train)):
319 | train_new.append(appliance_train[i][256: 768])
320 | for i in range(len(appliance_test)):
321 | test_new.append(appliance_test[i][256: 768])
322 |
323 | np.save(join(base_path, '%s\\appliance_train_512.npy' % appliance_name), train_new)
324 | np.save(join(base_path, '%s\\appliance_test_512.npy' % appliance_name), test_new)
325 | print('512: %s finished!' % appliance_name)
326 |
327 |
328 | def generateBalancedDataset(thres, ratio):
329 | for appliance_name in name:
330 | appliance_data = np.load(join(base_path, '%s\\appliance_train_512.npy' % appliance_name))
331 | main_data = np.load(join(base_path, '%s\\main_train.npy' % appliance_name))
332 | print('Appliance: %s data load!' % appliance_name)
333 |
334 | appliance_positve = []
335 | main_positive = []
336 | appliance_negative = []
337 | main_negative = []
338 | appliance_new = []
339 | main_new = []
340 |
341 | for i in range(len(appliance_data)):
342 | if np.sum(appliance_data[i]) > thres:
343 | appliance_positve.append(appliance_data[i])
344 | main_positive.append(main_data[i])
345 | else:
346 | appliance_negative.append(appliance_data[i])
347 | main_negative.append(main_data[i])
348 |
349 | print('Appliance: %s positive: %d negative: %d' %
350 | (appliance_name, len(appliance_positve), len(appliance_negative)))
351 |
352 | if len(appliance_positve)*ratio < len(appliance_negative):
353 | negative_length = len(appliance_positve)*ratio
354 | else:
355 | negative_length = len(appliance_negative)
356 | negative_index = np.linspace(0, negative_length-1, negative_length).astype(int)
357 | random.shuffle(negative_index)
358 | positive_index = np.linspace(0, len(appliance_positve)-1, len(appliance_positve)).astype(int)
359 | random.shuffle(positive_index)
360 |
361 | for i in positive_index:
362 | appliance_new.append(appliance_positve[i])
363 | main_new.append(main_positive[i])
364 | for i in negative_index:
365 | appliance_new.append(appliance_negative[i])
366 | main_new.append(main_negative[i])
367 |
368 | print('Appliance: %s length: %d' % (appliance_name, len(appliance_new)))
369 | np.save(join(base_path, '%s\\appliance_train_balanced_512.npy' % appliance_name), appliance_new)
370 | np.save(join(base_path, '%s\\main_train_balanced.npy' % appliance_name), main_new)
371 | print('Appliance: %s finished!' % appliance_name)
372 |
373 |
374 | def shrink(scale):
375 | for appliance_name in name:
376 | appliance_train = np.load(join(base_path, '%s\\appliance_train_balanced_512.npy' % appliance_name))
377 | appliance_test = np.load(join(base_path, '%s\\appliance_test_512.npy' % appliance_name))
378 | main_train = np.load(join(base_path, '%s\\main_train_balanced.npy' % appliance_name))
379 | main_test = np.load(join(base_path, '%s\\main_test.npy' % appliance_name))
380 | atr_new = []
381 | ate_new = []
382 | mtr_new = []
383 | mte_new = []
384 | print('Scale - Appliance: %s data load!' % appliance_name)
385 |
386 | for i in range(len(appliance_train)):
387 | atr_temp = []
388 | mtr_temp = []
389 | for j in range(512):
390 | atr_temp.append(float(appliance_train[i][j]/scale))
391 | for j in range(1024):
392 | mtr_temp.append(float(main_train[i][j]/scale))
393 | atr_new.append(atr_temp)
394 | mtr_new.append(mtr_temp)
395 |
396 | for i in range(len(appliance_test)):
397 | ate_temp = []
398 | mte_temp = []
399 | for j in range(512):
400 | ate_temp.append(float(appliance_test[i][j]/scale))
401 | for j in range(1024):
402 | mte_temp.append(float(main_test[i][j]/scale))
403 | ate_new.append(ate_temp)
404 | mte_new.append(mte_temp)
405 |
406 | np.save(join(base_path, '%s\\appliance_train_%d.npy' % (appliance_name, scale)), atr_new)
407 | np.save(join(base_path, '%s\\main_train_%d.npy' % (appliance_name, scale)), mtr_new)
408 | np.save(join(base_path, '%s\\appliance_test_%d.npy' % (appliance_name, scale)), ate_new)
409 | np.save(join(base_path, '%s\\main_test_%d.npy' % (appliance_name, scale)), mte_new)
410 |
411 | print('Scale: %s finished! ' % appliance_name)
412 |
413 |
414 | def clip_view():
415 | clip_number = 300
416 | for appliance_name in name:
417 | print('Clip - Appliance: %s' % appliance_name)
418 | if not os.path.exists(join(base_path, '%s\\visual_train' % appliance_name)):
419 | os.mkdir(join(base_path, '%s\\visual_train' % appliance_name))
420 | if not os.path.exists(join(base_path, '%s\\visual_test' % appliance_name)):
421 | os.mkdir(join(base_path, '%s\\visual_test' % appliance_name))
422 |
423 | appliance_data = np.load(join(base_path, '%s\\appliance_train_1000.npy' % appliance_name))
424 | main_data = np.load(join(base_path, '%s\\main_train_1000.npy' % appliance_name))
425 | print('Appliance length: %d, main length: %d' % (len(appliance_data), len(main_data)))
426 |
427 | for i in range(clip_number):
428 | fig = plt.figure(figsize=(16, 16), dpi=100)
429 | gs = gridspec.GridSpec(2, 1)
430 | gs.update(wspace=0.05, hspace=0.05)
431 | x = np.linspace(256, 768, 512)
432 | appliance_temp = []
433 | main_temp = []
434 | r = int(random.random()*len(appliance_data))
435 | for j in range(512):
436 | appliance_temp.append(int(appliance_data[r][j]*1000))
437 | for j in range(1024):
438 | main_temp.append(int(main_data[r][j]*1000))
439 |
440 | plt.subplot(2, 1, 1)
441 | plt.xlim(0, 1024)
442 | plt.plot(main_temp)
443 |
444 | plt.subplot(2, 1, 2)
445 | plt.xlim(0, 1024)
446 | plt.plot(x, appliance_temp)
447 |
448 | plt.savefig(join(base_path, '%s\\visual_train\\%d.jpg' % (appliance_name, i)))
449 | plt.close(fig)
450 |
451 | appliance_data = np.load(join(base_path, '%s\\appliance_test_1000.npy' % appliance_name))
452 | main_data = np.load(join(base_path, '%s\\main_test_1000.npy' % appliance_name))
453 |
454 | # test section
455 | for i in range(clip_number):
456 | fig = plt.figure(figsize=(16, 16), dpi=100)
457 | gs = gridspec.GridSpec(2, 1)
458 | gs.update(wspace=0.05, hspace=0.05)
459 | x = np.linspace(256, 768, 512)
460 | appliance_temp = []
461 | main_temp = []
462 | r = int(random.random()*len(appliance_data))
463 | for j in range(512):
464 | appliance_temp.append(int(appliance_data[r][j]*1000))
465 | for j in range(1024):
466 | main_temp.append(int(main_data[r][j]*1000))
467 |
468 | plt.subplot(2, 1, 1)
469 | plt.xlim(0, 1024)
470 | plt.plot(main_temp)
471 |
472 | plt.subplot(2, 1, 2)
473 | plt.xlim(0, 1024)
474 | plt.plot(x, appliance_temp)
475 |
476 | plt.savefig(join(base_path, '%s\\visual_test\\%d.jpg' % (appliance_name, i)))
477 | plt.close(fig)
478 |
479 |
480 | if __name__ == '__main__':
481 | align()
482 | separate()
483 | convert512()
484 | generateBalancedDataset(1500, 1)
485 | shrink(1)
486 |
--------------------------------------------------------------------------------
/model/ukdale_u.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | from __future__ import division
3 | from __future__ import print_function
4 |
5 | import tensorflow as tf
6 | import numpy as np
7 | import argparse
8 | import os
9 | import random
10 | import collections
11 | import math
12 | import time
13 | import matplotlib.pyplot as plt
14 | import matplotlib.gridspec as gridspec
15 | from sklearn.metrics import mean_squared_error
16 | from sklearn.metrics import mean_absolute_error
17 | from sklearn.metrics import r2_score
18 | from tensorflow.contrib.layers import xavier_initializer_conv2d
19 |
20 |
21 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
22 | os.environ['CUDA_VISIBLE_DEVICES'] = "0"
23 | gpu_options = tf.GPUOptions(allow_growth=True)
24 |
25 | current_version = '1'
26 | dataset_name = 'UKDALE'
27 | appliance_name = 'WashingMachine'
28 | appliance_name_folder = '%s_%s' %(dataset_name, appliance_name)
29 | base_root = 'outnilm\\%s\\%s' % (appliance_name_folder, current_version)
30 | folder_list = {
31 | 'base_root': base_root,
32 | 'image': '%s\\image' % base_root,
33 | 'model': '%s\\model' % base_root,
34 | 'test_validation': '%s\\test_validation' % base_root,
35 | 'input': 'data\\UK_DALE\\%s' % appliance_name,
36 | }
37 |
38 | # if there's no checkpoint, it will be 1
39 | isFirst = 1
40 | parser = argparse.ArgumentParser()
41 | if isFirst == 1:
42 | parser.add_argument("--checkpoint",
43 | default=None,
44 | help="directory with checkpoint to resume training from or use for testing")
45 | else:
46 | parser.add_argument("--checkpoint",
47 | default=folder_list['model'],
48 | help="directory with checkpoint to resume training from or use for testing")
49 | parser.add_argument("--output_dir",
50 | default=folder_list['base_root'],
51 | help="where to put output files")
52 | parser.add_argument("--seed", type=int)
53 | parser.add_argument("--max_steps", type=int, help="number of training steps (0 to disable)")
54 | parser.add_argument("--max_epochs", default=120, type=int, help="number of training epochs")
55 | parser.add_argument("--summary_freq", type=int, default=1000, help="update summaries every summary_freq steps")
56 | parser.add_argument("--progress_freq", type=int, default=5000, help="display progress every progress_freq steps")
57 | parser.add_argument("--trace_freq", type=int, default=0, help="trace execution every trace_freq steps")
58 | parser.add_argument("--display_freq", type=int,
59 | default=500,
60 | help="write current training images every display_freq steps")
61 | parser.add_argument("--save_freq", type=int,
62 | default=50000,
63 | help="save model every save_freq steps, 0 to disable")
64 | parser.add_argument('--test_procedure', type=int, default=50000)
65 | parser.add_argument('--validation_procedure', type=int, default=50000)
66 | parser.add_argument("--batch_size", type=int, default=1, help="number of images in batch")
67 | parser.add_argument("--ngf", type=int, default=64, help="number of generator filters in first conv layer")
68 | parser.add_argument("--ndf", type=int, default=64, help="number of discriminator filters in first conv layer")
69 | parser.add_argument("--lr_d", type=float, default=0.001, help="initial learning rate for sgd")
70 | parser.add_argument("--lr_g", type=float, default=0.0005, help="initial learning rate for adam")
71 | parser.add_argument("--beta1", type=float, default=0.5, help="momentum term of adam")
72 | parser.add_argument("--l1_weight", type=float, default=100.0, help="weight on L1 term for generator gradient")
73 | parser.add_argument("--gan_weight", type=float, default=1.0, help="weight on GAN term for generator gradient")
74 |
75 | a = parser.parse_args()
76 | EPS = 1e-12
77 | gggg = 0
78 | scale = 1
79 |
80 | Examples = collections.namedtuple("Examples", "inputs, targets, count,"
81 | "inputs_test, targets_test, count_test,"
82 | "steps_per_epoch")
83 | Model = collections.namedtuple("Model", "outputs, discrim_loss,"
84 | "gen_loss_GAN, gen_loss_L1, train")
85 |
86 |
87 | def discrim_conv(batch_input, out_channels, stride):
88 | return tf.layers.conv2d(batch_input, out_channels, kernel_size=(4, 1), strides=stride, padding="same",
89 | kernel_initializer=xavier_initializer_conv2d())
90 |
91 |
92 | def gen_conv(batch_input, out_channels):
93 | return tf.layers.conv2d(batch_input, out_channels, kernel_size=(4, 1), strides=(2, 1), padding="same",
94 | kernel_initializer=xavier_initializer_conv2d())
95 |
96 |
97 | def gen_deconv(batch_input, out_channels):
98 | return tf.layers.conv2d_transpose(batch_input, out_channels, kernel_size=(4, 1), strides=(2, 1), padding="same",
99 | kernel_initializer=xavier_initializer_conv2d())
100 |
101 |
102 | def lrelu(x, a):
103 | with tf.name_scope("lrelu"):
104 | x = tf.identity(x)
105 | return (0.5 * (1 + a)) * x + (0.5 * (1 - a)) * tf.abs(x)
106 |
107 |
108 | def batchnorm(x, scope='batch_instance_norm'):
109 | with tf.variable_scope(scope):
110 | ch = x.shape[-1]
111 | eps = 1e-5
112 |
113 | batch_mean, batch_sigma = tf.nn.moments(x, axes=[0, 1, 2], keep_dims=True)
114 | x_batch = (x - batch_mean) / (tf.sqrt(batch_sigma + eps))
115 |
116 | ins_mean, ins_sigma = tf.nn.moments(x, axes=[1, 2], keep_dims=True)
117 | x_ins = (x - ins_mean) / (tf.sqrt(ins_sigma + eps))
118 |
119 | rho = tf.get_variable("rho", [ch], initializer=tf.constant_initializer(1.0),
120 | constraint=lambda x: tf.clip_by_value(x, clip_value_min=0.0, clip_value_max=1.0))
121 | gamma = tf.get_variable("gamma", [ch], initializer=tf.constant_initializer(1.0))
122 | beta = tf.get_variable("beta", [ch], initializer=tf.constant_initializer(0.0))
123 |
124 | x_hat = rho * x_batch + (1 - rho) * x_ins
125 | x_hat = x_hat * gamma + beta
126 |
127 | return x_hat
128 |
129 |
130 | def create_generator(generator_inputs, generator_outputs_channels):
131 | layers = []
132 | with tf.variable_scope("encoder_1"):
133 | output = gen_conv(generator_inputs, a.ngf)
134 | layers.append(output)
135 |
136 | layer_specs = [
137 | a.ngf * 2,
138 | a.ngf * 4,
139 | a.ngf * 8,
140 | a.ngf * 8,
141 | a.ngf * 8,
142 | a.ngf * 8,
143 | a.ngf * 8,
144 | ]
145 |
146 | for out_channels in layer_specs:
147 | with tf.variable_scope("encoder_%d" % (len(layers) + 1)):
148 | rectified = lrelu(layers[-1], 0.2)
149 | convolved = gen_conv(rectified, out_channels)
150 | output = batchnorm(convolved)
151 | layers.append(output)
152 |
153 | layer_specs = [
154 | (a.ngf * 8, 0.5),
155 | (a.ngf * 8, 0.5),
156 | (a.ngf * 8, 0.5),
157 | (a.ngf * 8, 0.0),
158 | (a.ngf * 4, 0.0),
159 | (a.ngf * 2, 0.0),
160 | (a.ngf, 0.0),
161 | ]
162 |
163 | num_encoder_layers = len(layers)
164 | for decoder_layer, (out_channels, dropout) in enumerate(layer_specs):
165 | skip_layer = num_encoder_layers - decoder_layer - 1
166 | with tf.variable_scope("decoder_%d" % (skip_layer + 1)):
167 | if decoder_layer == 0:
168 | input = layers[-1]
169 | else:
170 | input = tf.concat([layers[-1], layers[skip_layer]], axis=3)
171 | rectified = tf.nn.relu(input)
172 | output = gen_deconv(rectified, out_channels)
173 | output = batchnorm(output)
174 | if dropout > 0.0:
175 | output = tf.nn.dropout(output, keep_prob=1 - dropout)
176 | layers.append(output)
177 |
178 | with tf.variable_scope("decoder_1"):
179 | input = tf.concat([layers[-1], layers[0]], axis=3)
180 | rectified = tf.nn.relu(input)
181 | output = gen_deconv(rectified, generator_outputs_channels)
182 | layers.append(output)
183 |
184 | return layers[-1]
185 |
186 |
187 | def create_model(inputs, targets, step):
188 | learning_rate_d = tf.train.exponential_decay(a.lr_d, step, 50000, 0.95, staircase=True)
189 | learning_rate_g = tf.train.exponential_decay(a.lr_g, step, 50000, 0.95, staircase=True)
190 |
191 | # def create_discriminator(discrim_inputs, discrim_targets):
192 | # n_layers = 3
193 | # layers = []
194 | #
195 | # input = tf.concat([discrim_inputs, discrim_targets], axis=1)
196 | # with tf.variable_scope("layer_1"):
197 | # convolved = discrim_conv(input, a.ndf, stride=(2, 1))
198 | # rectified = lrelu(convolved, 0.2)
199 | # layers.append(rectified)
200 | # for i in range(n_layers):
201 | # with tf.variable_scope("layer_%d" % (len(layers) + 1)):
202 | # out_channels = a.ndf * min(2**(i+1), 8)
203 | # stride = 1 if i == n_layers - 1 else (2, 1)
204 | # convolved = discrim_conv(layers[-1], out_channels, stride=stride)
205 | # normalized = batchnorm(convolved)
206 | # rectified = lrelu(normalized, 0.2)
207 | # with tf.variable_scope("layer_%d" % (len(layers) + 1)):
208 | # convolved = discrim_conv(rectified, out_channels=1, stride=1)
209 | # output = tf.sigmoid(convolved)
210 | # layers.append(output)
211 | #
212 | # return layers[-1]
213 | def create_discriminator(discrim_inputs, discrim_targets):
214 | n_layers = 3
215 | layers = []
216 |
217 | # 2x [batch, height, width, in_channels] => [batch, height, width, in_channels * 2]
218 | input = tf.concat([discrim_inputs, discrim_targets], axis=1)
219 |
220 | # layer_1: [batch, 256, 256, in_channels * 2] => [batch, 128, 128, ndf]
221 | with tf.variable_scope("layer_1"):
222 | convolved = discrim_conv(input, a.ndf, stride=(2, 1))
223 | rectified = lrelu(convolved, 0.2)
224 | layers.append(rectified)
225 |
226 | # layer_2: [batch, 128, 128, ndf] => [batch, 64, 64, ndf * 2]
227 | # layer_3: [batch, 64, 64, ndf * 2] => [batch, 32, 32, ndf * 4]
228 | # layer_4: [batch, 32, 32, ndf * 4] => [batch, 31, 31, ndf * 8]
229 | for i in range(n_layers):
230 | with tf.variable_scope("layer_%d" % (len(layers) + 1)):
231 | out_channels = a.ndf * min(2**(i+1), 8)
232 | stride = 1 if i == n_layers - 1 else (2, 1) # last layer here has stride 1
233 | convolved = discrim_conv(layers[-1], out_channels, stride=stride)
234 | normalized = batchnorm(convolved)
235 | rectified = lrelu(normalized, 0.2)
236 | layers.append(rectified)
237 |
238 | # layer_5: [batch, 31, 31, ndf * 8] => [batch, 30, 30, 1]
239 | with tf.variable_scope("layer_%d" % (len(layers) + 1)):
240 | convolved = discrim_conv(rectified, out_channels=1, stride=1)
241 | output = tf.sigmoid(convolved)
242 | layers.append(output)
243 |
244 | return layers[-1]
245 |
246 | with tf.variable_scope("generator"):
247 | out_channels = int(targets.get_shape()[-1])
248 | outputs = create_generator(inputs, out_channels)[:, 256:768, :, :]
249 |
250 | with tf.name_scope("real_discriminator"):
251 | with tf.variable_scope("discriminator"):
252 | predict_real = create_discriminator(inputs, targets)
253 |
254 | with tf.name_scope("fake_discriminator"):
255 | with tf.variable_scope("discriminator", reuse=True):
256 | predict_fake = create_discriminator(inputs, outputs)
257 |
258 | with tf.name_scope("discriminator_loss"):
259 | # minimizing -tf.log will try to get inputs to 1
260 | # predict_real => 1
261 | # predict_fake => 0
262 | discrim_loss = tf.reduce_mean(-(tf.log(predict_real + EPS) + tf.log(1 - predict_fake + EPS)))
263 |
264 | with tf.name_scope("generator_loss"):
265 | # predict_fake => 1
266 | # abs(targets - outputs) => 0
267 | gen_loss_GAN = tf.reduce_mean(-tf.log(predict_fake + EPS))
268 | gen_loss_L1 = tf.reduce_mean(tf.abs(targets - outputs))
269 | gen_loss = gen_loss_GAN * a.gan_weight + gen_loss_L1 * a.l1_weight
270 |
271 | with tf.name_scope("discriminator_train"):
272 | discrim_tvars = [var for var in tf.trainable_variables() if var.name.startswith("discriminator")]
273 | discrim_optim = tf.train.GradientDescentOptimizer(learning_rate=learning_rate_d)
274 | discrim_grads_and_vars = discrim_optim.compute_gradients(discrim_loss, var_list=discrim_tvars)
275 | discrim_train = discrim_optim.apply_gradients(discrim_grads_and_vars)
276 |
277 | with tf.name_scope("generator_train"):
278 | with tf.control_dependencies([discrim_train]):
279 | gen_tvars = [var for var in tf.trainable_variables() if var.name.startswith("generator")]
280 | gen_optim = tf.train.AdamOptimizer(learning_rate=learning_rate_g, beta1=a.beta1)
281 | gen_grads_and_vars = gen_optim.compute_gradients(gen_loss, var_list=gen_tvars)
282 | gen_train = gen_optim.apply_gradients(gen_grads_and_vars)
283 |
284 | ema = tf.train.ExponentialMovingAverage(decay=0.99)
285 | update_losses = ema.apply([discrim_loss, gen_loss_GAN, gen_loss_L1])
286 |
287 | global_step = tf.train.get_or_create_global_step()
288 | incr_global_step = tf.assign(global_step, global_step+1)
289 |
290 | return Model(
291 | discrim_loss=ema.average(discrim_loss),
292 | gen_loss_GAN=ema.average(gen_loss_GAN),
293 | gen_loss_L1=ema.average(gen_loss_L1),
294 | outputs=outputs,
295 | train=tf.group(update_losses, incr_global_step, gen_train),
296 | )
297 |
298 |
299 | def display_image(inputs, targets, outputs):
300 | global gggg
301 | fig = plt.figure(figsize=(16, 16), dpi=100)
302 | gs = gridspec.GridSpec(3, 1)
303 | gs.update(wspace=0.05, hspace=0.05)
304 | agg = np.reshape(inputs, [1024])
305 | app = np.reshape(targets, [512])
306 | out = np.reshape(outputs, [512])
307 | agg_new = []
308 | app_new = []
309 | out_new = []
310 | x = np.linspace(256, 768, 512)
311 |
312 | for i in agg:
313 | agg_new.append(int(i*scale))
314 | for i in range(512):
315 | app_new.append(int(app[i]*scale))
316 | out_new.append(int(out[i]*scale))
317 |
318 | plt.subplot(3, 1, 1)
319 | plt.xlim(0, 1024)
320 | plt.plot(agg_new)
321 |
322 | plt.subplot(3, 1, 2)
323 | plt.xlim(0, 1024)
324 | plt.plot(x, app_new)
325 |
326 | plt.subplot(3, 1, 3)
327 | plt.xlim(0, 1024)
328 | plt.plot(x, out_new)
329 |
330 | plt.savefig(('%s/{}.png' % folder_list['image'])
331 | .format(str(gggg).zfill(3)), bbox_inches='tight')
332 | gggg += 1
333 | plt.close(fig)
334 |
335 |
336 | def metric(target_data, output_data, step, epoch):
337 | tar_new = []
338 | out_new = []
339 | mae = []
340 |
341 | for i in range(len(output_data)):
342 | for j in range(len(output_data[i])):
343 | if output_data[i][j] < 0:
344 | o = 0
345 | else:
346 | o = output_data[i][j]
347 | out_new.append(o)
348 | tar_new.append(target_data[i][j])
349 |
350 | for i in range(len(out_new)):
351 | r = abs(tar_new[i] - out_new[i])
352 | mae.append(r)
353 |
354 | accuracy = (1.0-(np.sum(mae, dtype=np.int64)/(2*np.sum(tar_new, dtype=np.int64))))*100
355 | print('np.sum(mae):')
356 | print(np.sum(mae))
357 | print('np.sum(tar_new):')
358 | print(np.sum(tar_new))
359 | sae = abs(np.sum(tar_new, dtype=np.int64)-np.sum(out_new, dtype=np.int64))/np.sum(tar_new, dtype=np.int64)
360 | mse = mean_squared_error(tar_new, out_new)
361 | mae = mean_absolute_error(tar_new, out_new)
362 | r2 = r2_score(tar_new, out_new)
363 |
364 | with open('%s\\test.txt' % folder_list['test_validation'], 'a+') as f:
365 | print('STEP: %d' % (step+1), file=f)
366 | print('Epoch: %d' % epoch, file=f)
367 | print('Accuracy: %f' % accuracy, file=f)
368 | print('SAE: %f' % sae, file=f)
369 | print('MSE: %f' % mse, file=f)
370 | print('MAE: %f' % mae, file=f)
371 | print('R^2: %f' % r2, file=f)
372 | print('', file=f)
373 |
374 |
375 | def load_examples():
376 | base_path = folder_list['input']
377 |
378 | ap_data = np.load(os.path.join(base_path, 'appliance_train_1.npy'))
379 | ag_data = np.load(os.path.join(base_path, 'main_train_1.npy'))
380 | ap_data_test = np.load(os.path.join(base_path, 'appliance_test_1.npy'))
381 | ag_data_test = np.load(os.path.join(base_path, 'main_test_1.npy'))
382 | print('Data load complete!')
383 |
384 | appliance_data = tf.cast(ap_data, tf.float32)
385 | aggregate_data = tf.cast(ag_data, tf.float32)
386 | appliance_data_test = tf.cast(ap_data_test, tf.float32)
387 | aggregate_data_test = tf.cast(ag_data_test, tf.float32)
388 | print('cast complete!')
389 |
390 | queue = tf.train.slice_input_producer([aggregate_data, appliance_data], shuffle=True)
391 | inputs_batch, targets_batch = tf.train.batch(queue, batch_size=a.batch_size)
392 | queue_test = tf.train.slice_input_producer([aggregate_data_test, appliance_data_test], shuffle=False)
393 | inputs_batch_test, targets_batch_test = tf.train.batch(queue_test, batch_size=a.batch_size)
394 |
395 | steps_per_epoch = int(math.ceil(len(ap_data) / a.batch_size))
396 |
397 | return Examples(
398 | inputs=inputs_batch,
399 | targets=targets_batch,
400 | count=len(ap_data),
401 | inputs_test=inputs_batch_test,
402 | targets_test=targets_batch_test,
403 | count_test=len(ap_data_test),
404 | steps_per_epoch=steps_per_epoch,
405 | )
406 |
407 |
408 | def main():
409 | if a.seed is None:
410 | a.seed = random.randint(0, 2**31 - 1)
411 | tf.set_random_seed(a.seed)
412 | np.random.seed(a.seed)
413 | random.seed(a.seed)
414 |
415 | for folder_name, folder_path in folder_list.items():
416 | if not os.path.exists(folder_path):
417 | os.makedirs(folder_path)
418 | print('Folder creation complete!')
419 |
420 | with open(os.path.join(folder_list['base_root'], 'config.txt'), 'w') as f:
421 | for k, v in a._get_kwargs():
422 | print(k, "=", v, file=f)
423 | print('Config save complete!')
424 |
425 | examples = load_examples()
426 | global_step = tf.placeholder(tf.float32, None)
427 | inputs = tf.placeholder(tf.float32, [a.batch_size, 1024, 1, 1])
428 | targets = tf.placeholder(tf.float32, [a.batch_size, 512, 1, 1])
429 | i_ = tf.reshape(examples.inputs, [a.batch_size, 1024, 1, 1])
430 | t_ = tf.reshape(examples.targets, [a.batch_size, 512, 1, 1])
431 | i_t = tf.reshape(examples.inputs_test, [a.batch_size, 1024, 1, 1])
432 | t_t = tf.reshape(examples.targets_test, [a.batch_size, 512, 1, 1])
433 | model = create_model(inputs, targets, global_step)
434 | print('model complete!')
435 |
436 | with tf.name_scope("display_images"):
437 | display_fetches = {
438 | 'output': model.outputs,
439 | }
440 |
441 | tf.summary.scalar("discriminator_loss", model.discrim_loss)
442 | tf.summary.scalar("generator_loss_GAN", model.gen_loss_GAN)
443 | tf.summary.scalar("generator_loss_L1", model.gen_loss_L1)
444 |
445 | with tf.name_scope("parameter_count"):
446 | parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) for v in tf.trainable_variables()])
447 |
448 | saver = tf.train.Saver(max_to_keep=50)
449 |
450 | logdir = a.output_dir if (a.trace_freq > 0 or a.summary_freq > 0) else None
451 | sv = tf.train.Supervisor(logdir=logdir, save_summaries_secs=0, saver=None)
452 | with sv.managed_session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:
453 | print("parameter_count =", sess.run(parameter_count))
454 | if a.checkpoint is not None:
455 | print("loading model from checkpoint")
456 | checkpoint = tf.train.latest_checkpoint(a.checkpoint)
457 | saver.restore(sess, checkpoint)
458 |
459 | max_steps = 2**32
460 | if a.max_epochs is not None:
461 | max_steps = examples.steps_per_epoch * a.max_epochs
462 | if a.max_steps is not None:
463 | max_steps = a.max_steps
464 |
465 | start = time.time()
466 | output_test = []
467 | target_test = []
468 |
469 | for step in range(max_steps):
470 |
471 | def should(freq):
472 | return freq > 0 and ((step + 1) % freq == 0 or step == max_steps - 1)
473 |
474 | options = None
475 | run_metadata = None
476 | if should(a.trace_freq):
477 | options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
478 | run_metadata = tf.RunMetadata()
479 |
480 | fetches = {
481 | "train": model.train,
482 | "global_step": sv.global_step,
483 | }
484 | if should(a.progress_freq):
485 | fetches["discrim_loss"] = model.discrim_loss
486 | fetches["gen_loss_GAN"] = model.gen_loss_GAN
487 | fetches["gen_loss_L1"] = model.gen_loss_L1
488 |
489 | if should(a.summary_freq):
490 | fetches["summary"] = sv.summary_op
491 |
492 | if should(a.display_freq):
493 | fetches["display"] = display_fetches
494 |
495 | inputs_, targets_ = sess.run([i_, t_])
496 | results = sess.run(fetches,
497 | options=options,
498 | run_metadata=run_metadata,
499 | feed_dict={global_step: step,
500 | inputs: inputs_,
501 | targets: targets_})
502 |
503 | if should(a.display_freq):
504 | data = results['display']
505 | display_image(inputs_, targets_, data['output'])
506 |
507 | if should(a.summary_freq):
508 | sv.summary_writer.add_summary(results["summary"], results["global_step"])
509 |
510 | if should(a.progress_freq):
511 | train_epoch = math.ceil(results["global_step"] / examples.steps_per_epoch)
512 | train_step = (results["global_step"] - 1) % examples.steps_per_epoch + 1
513 | rate = (step + 1) * a.batch_size / (time.time() - start)
514 | print("progress epoch %d step %d image/sec %0.1f" %
515 | (train_epoch, train_step+1, rate))
516 |
517 | print("discrim_loss", results["discrim_loss"])
518 | print("gen_loss_GAN", results["gen_loss_GAN"])
519 | print("gen_loss_L1", results["gen_loss_L1"])
520 |
521 | if should(a.save_freq):
522 | print("saving model")
523 | saver.save(sess, os.path.join(folder_list['model'], "model"), global_step=sv.global_step)
524 |
525 | if should(a.test_procedure):
526 | print('Test procedure!')
527 | target_test.clear()
528 | output_test.clear()
529 | max_steps_test = examples.count_test
530 | for step_test in range(max_steps_test):
531 | inputs_, targets_= sess.run([i_t, t_t])
532 | data = sess.run({
533 | 'output': model.outputs,
534 | }, feed_dict={
535 | global_step: results['global_step'],
536 | inputs: inputs_,
537 | targets: targets_
538 | })
539 | _target = np.reshape(targets_, [a.batch_size, 512])
540 | _output = np.reshape(data['output'], [a.batch_size, 512])
541 | for i in range(a.batch_size):
542 | tar_temp = []
543 | out_temp = []
544 | for j in range(512):
545 | tar_temp.append(int(_target[i][j] * scale))
546 | out_temp.append(int(_output[i][j] * scale))
547 | target_test.append(tar_temp)
548 | output_test.append(out_temp)
549 | if step_test % 1000 == 0:
550 | print('Process Test: %f Rate: %f' % (step_test / max_steps_test,
551 | (time.time() - start) / max_steps_test))
552 | np.save('%s\\test_target_%d.npy' % (folder_list['test_validation'], results['global_step']+1), target_test)
553 | np.save('%s\\test_output_%d.npy' % (folder_list['test_validation'], results['global_step']+1), output_test)
554 | train_epoch = math.ceil(results["global_step"] / examples.steps_per_epoch)
555 | metric(target_test, output_test, results['global_step'],train_epoch)
556 | print('Test procedure complete!')
557 |
558 | if sv.should_stop():
559 | break
560 |
561 |
562 | main()
563 |
--------------------------------------------------------------------------------
/preprocess/refit_process.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.append('preprocess')
3 | import matplotlib
4 | matplotlib.use("TkAgg")
5 | import matplotlib.pyplot as plt
6 | from matplotlib.pyplot import savefig
7 | import numpy as np
8 | import refit_cfg
9 | import os
10 | import random
11 | from sklearn.model_selection import train_test_split
12 |
13 |
14 | name = ['WashingMachine', 'Kettle', 'Microwave', 'Fridge', 'Dishwasher']
15 | appliance_dict = {
16 | 'WashingMachine': refit_cfg.washingmachine,
17 | 'Kettle': refit_cfg.kettle,
18 | 'Microwave': refit_cfg.microwave,
19 | 'Fridge': refit_cfg.fridge,
20 | 'Dishwasher': refit_cfg.dishwasher
21 | }
22 |
23 |
24 | def align_process(house_id):
25 | data = np.load('data\\REFIT\\original_data\\%d.npy' % house_id)
26 | new_data = []
27 | current_index = 0
28 | current_time = int(data[0][0])
29 | end_time = int(data[-1][0]) + 8
30 | interval_threshold = refit_cfg.separation_threshold
31 | isend = 0
32 | data_length = len(data)
33 |
34 | while current_time <= end_time:
35 | current_interval = int(data[current_index+1][0]) - int(data[current_index][0])
36 | if current_interval < interval_threshold: # small interval
37 | if current_time > int(data[current_index][0]):
38 | temp_index = current_index + 1
39 | while current_time > int(data[temp_index][0]):
40 | temp_index += 1
41 | if temp_index > (data_length-1):
42 | temp_index -= 1
43 | break
44 |
45 | if abs(current_time - int(data[temp_index-1][0])) > abs(int(data[temp_index][0])-current_time):
46 | current_index = temp_index
47 | if temp_index == (data_length-1):
48 | print('The end!')
49 | isend = 1
50 | else:
51 | current_index = temp_index - 1
52 | t = []
53 | for element in data[current_index]:
54 | t.append(element)
55 | t[0] = current_time
56 | new_data.append(t)
57 | if isend == 1:
58 | break
59 | current_time += 8
60 | if current_index % 1000 == 0:
61 | print('House %d processing: %f' % (house_id, current_index/data_length))
62 | else: # big interval
63 | current_index += 1
64 | current_time = int(data[current_index][0])
65 |
66 | np.save('data\\REFIT\\after_align\\%d.npy' % house_id, new_data)
67 |
68 |
69 | def visual(house_id, channel_id, start, length):
70 | data = np.load('data\\REFIT\\after_align\\%d.npy' % house_id)
71 | print(len(data))
72 | target = []
73 | c = channel_id+1
74 | for r in data:
75 | target.append(int(r[c]))
76 | y = target[start:start+length]
77 | plt.plot(y)
78 | plt.show()
79 |
80 |
81 | def diff(house_id):
82 | data = np.load('data\\REFIT\\after_align\\%d.npy' % house_id)
83 | d = []
84 | for i in range(len(data)-1):
85 | d.append(int(data[i+1][0])-int(data[i][0]))
86 | plt.plot(d)
87 | plt.show()
88 | plt.close()
89 |
90 |
91 | def appliance_separation(dict, appliance_name):
92 | path = 'data\\REFIT\\appliance_data\\%s' % appliance_name
93 | if not os.path.exists(path):
94 | os.mkdir(path)
95 |
96 | for house_id, channel_id in dict.items():
97 | data = np.load('data\\REFIT\\after_align\\%d.npy' % house_id)
98 | appliance_data = []
99 | for row in data:
100 | appliance_data.append([row[1], row[channel_id+1]])
101 | np.save(os.path.join(path, '%d_%d.npy' % (house_id, channel_id)), appliance_data)
102 | print('Appliance %s House %d complete!' % (appliance_name, house_id))
103 |
104 |
105 | def show_appliance(house_id, appliance_name):
106 | channel_id = appliance_dict[appliance_name][house_id]
107 | data = np.load('data\\REFIT\\after_align\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id))
108 | print(len(data))
109 | mains = []
110 | app = []
111 | for i in data:
112 | mains.append(int(i[0]))
113 | app.append(int(i[1]))
114 | plt.figure(figsize=(20, 8))
115 | plt.plot(mains)
116 | plt.plot(app)
117 | plt.show()
118 |
119 |
120 | def cull(cull_dict):
121 | for appliance_name, _dict in cull_dict.items():
122 | path = 'data\\REFIT\\after_culling\\%s' % appliance_name
123 | if not os.path.exists(path):
124 | os.mkdir(path)
125 | for house_id, cull_list in _dict.items():
126 | channel_id = appliance_dict[appliance_name][house_id]
127 | data = np.load('data\\REFIT\\after_align\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id))
128 | new_data = []
129 | _cull_list = [[0, cull_list[0][0]]]
130 | for i in range(len(cull_list)-1):
131 | _cull_list.append([cull_list[i][1], cull_list[i+1][0]])
132 | _cull_list.append([cull_list[-1][1], (len(data)-1)])
133 |
134 | for i in _cull_list:
135 | if i[1] - i[0] != 0:
136 | for j in range(i[0], i[1]):
137 | new_data.append(data[j])
138 | np.save('data\\REFIT\\after_culling\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id), new_data)
139 | print('House %d %s complete!' % (house_id, appliance_name))
140 |
141 |
142 | def appliance_separation(dict, appliance_name):
143 | """
144 | 将各个电器的数据进行分解,放置到appliance_data文件夹下对应电器的文件夹中,以house_id和channel_id进行命名
145 | :param dict: 电器数据来源
146 | :param appliance_name: 当前电器的名称,用以创建文件夹
147 | :return:
148 | """
149 | path = 'data\\REFIT\\appliance_data\\%s' % appliance_name
150 | if not os.path.exists(path):
151 | os.mkdir(path)
152 |
153 | for house_id, channel_id in dict.items():
154 | data = np.load('data\\REFIT\\after_align\\%d.npy' % house_id)
155 | appliance_data = []
156 | for row in data:
157 | appliance_data.append([row[1], row[channel_id+1]]) # 将mains 和 appliance 作为一条单独的记录
158 | np.save(os.path.join(path, '%d_%d.npy' % (house_id, channel_id)), appliance_data)
159 | print('Appliance %s House %d complete!' % (appliance_name, house_id))
160 |
161 |
162 | def show_appliance(house_id, appliance_name):
163 | """
164 | 具体观察每个电器的图形表示,将大段的数据缺失或者数据错误进行标注,构造cull_dict字典,在cull进行片段删除
165 | :param house_id:
166 | :param appliance_name:
167 | :return:
168 | """
169 | channel_id = appliance_dict[appliance_name][house_id]
170 | data = np.load('data\\REFIT\\after_culling\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id))
171 | print(len(data))
172 | mains = []
173 | app = []
174 | for i in data:
175 | mains.append(int(i[0]))
176 | app.append(int(i[1]))
177 | plt.figure(figsize=(20, 8))
178 | plt.plot(mains)
179 | plt.plot(app)
180 | plt.show()
181 |
182 |
183 | def cull(cull_dict):
184 | """
185 | 根据画的图,将大段的空缺段进行删除,删除之后,需要进行比对
186 | :param cull_dict:
187 | :return:
188 | """
189 | for appliance_name, _dict in cull_dict.items():
190 | path = 'data\\REFIT\\after_culling_2\\%s' % appliance_name
191 | if not os.path.exists(path):
192 | os.mkdir(path)
193 | for house_id, cull_list in _dict.items():
194 | channel_id = appliance_dict[appliance_name][house_id]
195 | data = np.load('data\\REFIT\\after_culling_2\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id))
196 | new_data = []
197 | # 对cull_list进行变形,变成表征合理数据的区间
198 | _cull_list = [[0, cull_list[0][0]]]
199 | for i in range(len(cull_list)-1):
200 | _cull_list.append([cull_list[i][1], cull_list[i+1][0]])
201 | _cull_list.append([cull_list[-1][1], (len(data)-1)])
202 |
203 | for i in _cull_list:
204 | if i[1] - i[0] != 0:
205 | for j in range(i[0], i[1]):
206 | new_data.append(data[j])
207 | np.save('data\\REFIT\\after_culling_2\\%s\\%d_%d.npy' % (appliance_name, house_id, channel_id), new_data)
208 | print('House %d %s complete!' % (house_id, appliance_name))
209 |
210 |
211 | def separate(appliance_name):
212 | window_width = refit_cfg.window_width[appliance_name]
213 | data_path = 'data\\REFIT\\after_culling\\%s' % appliance_name
214 | count = 0
215 | appliance_train_validation = []
216 | appliance_test = []
217 | main_train_validation = []
218 | main_test = []
219 |
220 | for house_id, channel_id in refit_cfg.train_validation[appliance_name].items():
221 | # train & validation
222 | appliance_train_validation.clear()
223 | main_train_validation.clear()
224 | data = np.load(os.path.join(data_path, '%s_%s.npy' % (house_id, channel_id)))
225 | current_head = 0
226 | data_length = len(data)
227 | end = data_length - window_width - 1
228 | while current_head < end:
229 | temp_main = []
230 | temp_appliance = []
231 | for i in range(current_head, current_head+window_width):
232 | temp_main.append(data[i][0])
233 | temp_appliance.append(data[i][1])
234 | r = random.random()
235 | current_head += int(window_width*r)
236 | appliance_train_validation.append(temp_appliance)
237 | main_train_validation.append(temp_main)
238 | count += 1
239 | if count % 1000 == 0:
240 | print('T & V 1: House %d %f' % (house_id, (current_head / data_length)))
241 |
242 | data_length -= window_width
243 | random_clip = refit_cfg.random_clip[appliance_name]
244 | for i in range(random_clip):
245 | r = random.random()
246 | start = int(r*data_length)
247 | temp_main = []
248 | temp_appliance = []
249 | for j in range(start, start + window_width):
250 | temp_main.append(data[j][0])
251 | temp_appliance.append(data[j][1])
252 | appliance_train_validation.append(temp_appliance)
253 | main_train_validation.append(temp_main)
254 | count += 1
255 | if count % 1000 == 0:
256 | print('T & V 2: House %d %f' % (house_id, (i / random_clip)))
257 | print('Train & Validation: House %d %s complete!' % (house_id, appliance_name))
258 | np.save(os.path.join(data_path, '1024\\appliance_train_validation_%d.npy' % house_id), appliance_train_validation)
259 | np.save(os.path.join(data_path, '1024\\main_train_validation_%d.npy' % house_id), main_train_validation)
260 |
261 |
262 | # test
263 | count = 0
264 | for house_id, channel_id in refit_cfg.test[appliance_name].items():
265 | appliance_test.clear()
266 | main_test.clear()
267 | data = np.load(os.path.join(data_path, '%s_%s.npy' % (house_id, channel_id)))
268 | current_head = 0
269 | data_length = len(data)
270 | end = data_length - window_width - 1
271 | while current_head < end:
272 | temp_main = []
273 | temp_appliance = []
274 | for i in range(current_head, current_head+window_width):
275 | temp_main.append(data[i][0])
276 | temp_appliance.append(data[i][1])
277 | r = random.random()
278 | current_head += int(r*window_width)
279 | appliance_test.append(temp_appliance)
280 | main_test.append(temp_main)
281 | count += 1
282 | if count % 1000 == 0:
283 | print('Test 1: House %d %f' % (house_id, (current_head / data_length)))
284 |
285 | data_length -= window_width
286 | for i in range(refit_cfg.random_clip[appliance_name]):
287 | r = random.random()
288 | start = int(r*data_length)
289 | temp_main = []
290 | temp_appliance = []
291 | for j in range(start, start + window_width):
292 | temp_main.append(data[j][0])
293 | temp_appliance.append(data[j][1])
294 | appliance_test.append(temp_appliance)
295 | main_test.append(temp_main)
296 | count += 1
297 | if count % 1000 == 0:
298 | print('Test 2: House %d %f' % (house_id, (i / data_length)))
299 | print('Test 2: House %d %s complete!' % (house_id, appliance_name))
300 | np.save(os.path.join(data_path, '1024\\appliance_test_%d.npy' % house_id), appliance_test)
301 | np.save(os.path.join(data_path, '1024\\main_test_%d.npy' % house_id), main_test)
302 |
303 |
304 | def clip_visual(appliance_name):
305 | base_path = 'data\\REFIT\\after_culling\\%s' % appliance_name
306 | appliance_data = np.load(os.path.join(base_path, 'appliance_train_.npy'))
307 | main_data = np.load(os.path.join(base_path, 'main_train_.npy'))
308 | print('Data load complete!')
309 | loop = 1000
310 | x = np.linspace(256, 768, 512)
311 | length = len(appliance_data)
312 | for i in range(loop):
313 | r = int(random.random()*length)
314 | plt.figure(figsize=(25, 10), dpi=100)
315 | plt.subplot(211)
316 | plt.xlim(0, 1024)
317 | plt.plot(main_data[r])
318 | plt.subplot(212)
319 | plt.xlim(0, 1024)
320 | plt.plot(x, appliance_data[r])
321 | savefig(os.path.join(base_path, 'clip_view\\%d.jpg' % i))
322 | plt.close()
323 |
324 |
325 | def train_validation_split(appliance_name):
326 | data_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
327 | appliance = np.load(os.path.join(data_path, 'appliance_train_validation.npy'))
328 | main = np.load(os.path.join(data_path, 'main_train_validation.npy'))
329 | appliance_train, appliance_validation, main_train, main_validation = \
330 | train_test_split(appliance, main, test_size=0.2)
331 | print(len(appliance_train))
332 | print(len(main_train))
333 |
334 | np.save(os.path.join(data_path, 'appliance_train.npy'), appliance_train)
335 | np.save(os.path.join(data_path, 'main_train.npy'), main_train)
336 | np.save(os.path.join(data_path, 'appliance_validation.npy'), appliance_validation)
337 | np.save(os.path.join(data_path, 'main_validation.npy'), main_validation)
338 |
339 |
340 | def data_integration(appliance_name):
341 | data_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
342 | appliance = []
343 | main = []
344 | for house_id, channel_id in refit_cfg.train_validation[appliance_name].items():
345 | appliance_data = np.load(os.path.join(data_path, 'appliance_train_validation_%d.npy' % house_id))
346 | main_data = np.load(os.path.join(data_path, 'main_train_validation_%d.npy' % house_id))
347 | for i in appliance_data:
348 | appliance.append(i)
349 | for i in main_data:
350 | main.append(i)
351 |
352 | print(len(appliance))
353 | print(len(main))
354 | np.save(os.path.join(data_path, 'appliance_train_validation.npy'), appliance)
355 | np.save(os.path.join(data_path, 'main_train_validation.npy'), main)
356 |
357 | appliance_test = []
358 | main_test = []
359 | for house_id, channel_id in refit_cfg.test[appliance_name].items():
360 | appliance_data = np.load(os.path.join(data_path, 'appliance_test_%d.npy' % house_id))
361 | main_data = np.load(os.path.join(data_path, 'main_test_%d.npy' % house_id))
362 | for i in appliance_data:
363 | appliance_test.append(i)
364 | for i in main_data:
365 | main_test.append(i)
366 |
367 | print(len(appliance_test))
368 | print(len(main_test))
369 | np.save(os.path.join(data_path, 'appliance_test.npy'), appliance_test)
370 | np.save(os.path.join(data_path, 'main_test.npy'), main_test)
371 |
372 |
373 | def positive_negative(appliance_name):
374 | base_path = 'data\\REFIT\\after_culling\\%s' % appliance_name
375 | appliance_data = np.load(os.path.join(base_path, 'appliance_train.npy'))
376 | count = 0
377 | threshold = [0, 50, 100, 200, 500, 1000, 2000, 5000, 10000]
378 | d = {}
379 | for i in range(len(threshold)):
380 | d[threshold[i]] = 0
381 | print(d)
382 |
383 | for th in threshold:
384 | for i in appliance_data:
385 | sum = 0
386 | for j in i:
387 | sum += int(j)
388 | if sum > th:
389 | d[th] += 1
390 | print('Thres %d complete!' % th)
391 |
392 | for thres, count in d.items():
393 | print('Thres: %d %d/%d %f' % (thres, count, len(appliance_data), count/len(appliance_data)))
394 |
395 |
396 | def clip_view(appliance_name, thres):
397 | base_path = 'data\\REFIT\\after_culling\\%s' % appliance_name
398 | appliance_data = np.load(os.path.join(base_path, 'appliance_train.npy'))
399 | count = 0
400 |
401 | for i in appliance_data:
402 | sum = 0
403 | for j in i:
404 | sum += int(j)
405 | if sum > thres:
406 | plt.figure(figsize=(25, 10), dpi=100)
407 | plt.plot(i.astype(int))
408 | savefig(os.path.join(base_path, 'clip_view\\%d.jpg' % count))
409 | plt.close()
410 | count += 1
411 |
412 |
413 | def test_process(appliance_name):
414 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
415 | appliance_data = np.load(os.path.join(base_path, 'appliance_test_512.npy'))
416 | temp = [0.0]*512
417 | new_app = []
418 | for i in range(len(appliance_data)):
419 | max = np.max(appliance_data[i])
420 | if max < 0.05:
421 | print(max)
422 | new_app.append(temp)
423 | else:
424 | new_app.append(appliance_data[i])
425 | np.save(os.path.join(base_path, 'appliance_test_512.npy'), new_app)
426 |
427 |
428 | def separate_positive_negative(appliance_name, thres, peak):
429 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
430 | appliance_data = np.load(os.path.join(base_path, 'appliance_train.npy'))
431 | main_data = np.load(os.path.join(base_path, 'main_train.npy'))
432 | count = 0
433 | appliance_positive = []
434 | appliance_negative = []
435 | main_positive = []
436 | main_negative = []
437 | appliance_temp = [0] * 1024
438 |
439 | for i in range(len(appliance_data)):
440 | sum = 0
441 | max = 0
442 | for j in appliance_data[i]:
443 | sum += int(j)
444 | for j in range(512):
445 | if int(appliance_data[i][j+256]) > max:
446 | max = int(appliance_data[i][j+256])
447 | if max < peak:
448 | sum = 0
449 | if sum > thres:
450 | appliance_positive.append(appliance_data[i])
451 | main_positive.append(main_data[i])
452 | else:
453 | appliance_negative.append(appliance_temp)
454 | main_negative.append(main_data[i])
455 | if i % 1000 == 0:
456 | print('Processing: %f' % (i/len(appliance_data)))
457 |
458 | np.save(os.path.join(base_path, 'appliance_positive.npy'), appliance_positive)
459 | np.save(os.path.join(base_path, 'main_positive.npy'), main_positive)
460 | np.save(os.path.join(base_path, 'appliance_negative.npy'), appliance_negative)
461 | np.save(os.path.join(base_path, 'main_negative.npy'), main_negative)
462 |
463 |
464 | def generate_balanced_dataset(appliance_name, negative_ratio):
465 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
466 | appliance_positive = list(np.load(os.path.join(base_path, 'appliance_positive.npy')))
467 | appliance_negative = np.load(os.path.join(base_path, 'appliance_negative.npy'))
468 | main_positive = list(np.load(os.path.join(base_path, 'main_positive.npy')))
469 | main_negative = np.load(os.path.join(base_path, 'main_negative.npy'))
470 | print('Data load complete!')
471 |
472 | positive_length = len(appliance_positive)
473 | negative_length = len(appliance_negative)
474 | print('Postive length: %d negative length: %d' % (positive_length, negative_length))
475 | for i in range(int(positive_length*negative_ratio)):
476 | r = int(random.random()*negative_length)
477 | appliance_positive.append(appliance_negative[r])
478 | main_positive.append(main_negative[r])
479 | print('Data generate complete! length: %d' % (len(appliance_positive)))
480 |
481 | index = np.linspace(0, len(appliance_positive)-1, len(appliance_positive)).astype(int)
482 | random.shuffle(index)
483 | appliance_new = []
484 | main_new = []
485 |
486 | for i in index:
487 | appliance_new.append(appliance_positive[i])
488 | main_new.append(main_positive[i])
489 | print('Data shuffle complete!')
490 |
491 | np.save(os.path.join(base_path, 'appliance_train_balanced.npy'), appliance_new)
492 | np.save(os.path.join(base_path, 'main_train_balanced.npy'), main_new)
493 | print('Data save complete!')
494 |
495 |
496 | def shrink(appliance_name, scale):
497 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
498 | appliance_data = np.load(os.path.join(base_path, 'appliance_train_balanced.npy'))
499 | main_data = np.load(os.path.join(base_path, 'main_train_balanced.npy'))
500 | appliance_new = []
501 | main_new = []
502 | print('Data load complete!')
503 |
504 | for i in range(len(appliance_data)):
505 | appliance_temp = []
506 | main_temp = []
507 | for j in range(len(appliance_data[i])):
508 | appliance_temp.append(float(int(appliance_data[i][j])/scale))
509 | for j in range(len(main_data[i])):
510 | main_temp.append(float(int(main_data[i][j])/scale))
511 | appliance_new.append(appliance_temp)
512 | main_new.append(main_temp)
513 | print('Process complete!')
514 |
515 | np.save(os.path.join(base_path, 'appliance_train_%d.npy' % scale), appliance_new)
516 | np.save(os.path.join(base_path, 'main_train_%d.npy' % scale), main_new)
517 |
518 |
519 | def shrink_validation(appliance_name, scale):
520 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
521 | appliance_data = np.load(os.path.join(base_path, 'appliance_validation.npy'))
522 | main_data = np.load(os.path.join(base_path, 'main_validation.npy'))
523 | appliance_new = []
524 | main_new = []
525 | print('Data load complete!')
526 |
527 | for i in range(len(appliance_data)):
528 | appliance_temp = []
529 | main_temp = []
530 | for j in range(len(appliance_data[i])):
531 | appliance_temp.append(float(int(appliance_data[i][j])/scale))
532 | for j in range(len(main_data[i])):
533 | main_temp.append(float(int(main_data[i][j])/scale))
534 | appliance_new.append(appliance_temp)
535 | main_new.append(main_temp)
536 | print('Process complete!')
537 |
538 | np.save(os.path.join(base_path, 'appliance_validation_%d.npy' % scale), appliance_new)
539 | np.save(os.path.join(base_path, 'main_validation_%d.npy' % scale), main_new)
540 |
541 |
542 | def appliance_1024to512(appliance_name):
543 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
544 | appliance_train = np.load(os.path.join(base_path, 'appliance_train_1000.npy'))
545 | appliance_validation = np.load(os.path.join(base_path, 'appliance_validation_1000.npy'))
546 | appliance_test = np.load(os.path.join(base_path, 'appliance_test_1000.npy'))
547 | at_new = []
548 | av_new = []
549 | ae_new = []
550 |
551 | for i in range(len(appliance_train)):
552 | at_temp = []
553 | for j in range(256, 768):
554 | at_temp.append(float(appliance_train[i][j]))
555 | at_new.append(at_temp)
556 | for i in range(len(appliance_validation)):
557 | av_temp = []
558 | for j in range(256, 768):
559 | av_temp.append(float(appliance_validation[i][j]))
560 | av_new.append(av_temp)
561 | for i in range(len(appliance_test)):
562 | ae_temp = []
563 | for j in range(256, 768):
564 | ae_temp.append(float(appliance_test[i][j]))
565 | ae_new.append(ae_temp)
566 |
567 | np.save(os.path.join(base_path, 'appliance_train_512.npy'), at_new)
568 | np.save(os.path.join(base_path, 'appliance_validation_512.npy'), av_new)
569 | np.save(os.path.join(base_path, 'appliance_test_512.npy'), ae_new)
570 |
571 |
572 | def shrink_test(appliance_name, scale):
573 | base_path = 'data\\REFIT\\after_culling\\%s\\1024' % appliance_name
574 | appliance_data = np.load(os.path.join(base_path, 'appliance_test.npy'))
575 | main_data = np.load(os.path.join(base_path, 'main_test.npy'))
576 | appliance_new = []
577 | main_new = []
578 | print('Data load complete!')
579 |
580 | for i in range(len(appliance_data)):
581 | appliance_temp = []
582 | main_temp = []
583 | for j in range(len(appliance_data[i])):
584 | appliance_temp.append(float(int(appliance_data[i][j])/scale))
585 | for j in range(len(main_data[i])):
586 | main_temp.append(float(int(main_data[i][j])/scale))
587 | appliance_new.append(appliance_temp)
588 | main_new.append(main_temp)
589 | print('Process complete!')
590 |
591 | np.save(os.path.join(base_path, 'appliance_test_1000.npy'), appliance_new)
592 | np.save(os.path.join(base_path, 'main_test_1000.npy'), main_new)
593 |
594 |
595 | if __name__ == '__main__':
596 | appliance_name = 'WashingMachine'
597 | separate(appliance_name)
598 | data_integration(appliance_name)
599 | train_validation_split(appliance_name)
600 | separate_positive_negative(appliance_name, 1500, 20)
601 | generate_balanced_dataset(appliance_name, 1)
602 | shrink(appliance_name, 1000)
603 | shrink_validation(appliance_name, 1000)
604 | shrink_test(appliance_name, 1000)
605 | appliance_1024to512(appliance_name)
606 | # test_process(appliance_name)
607 | print('Process complete!!!')
608 |
--------------------------------------------------------------------------------
/model/refit_u.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | from __future__ import division
3 | from __future__ import print_function
4 |
5 | import tensorflow as tf
6 | import numpy as np
7 | import argparse
8 | import os
9 | import random
10 | import collections
11 | import math
12 | import time
13 | import matplotlib.pyplot as plt
14 | import matplotlib.gridspec as gridspec
15 | from sklearn.metrics import mean_squared_error
16 | from sklearn.metrics import mean_absolute_error
17 | from sklearn.metrics import r2_score
18 | from tensorflow.contrib.layers import xavier_initializer_conv2d
19 |
20 |
21 | os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
22 | os.environ['CUDA_VISIBLE_DEVICES'] = "0"
23 |
24 | current_version = '1'
25 | dataset_name = 'REFIT'
26 | appliance_name = 'WashingMachine'
27 | appliance_name_folder = '%s_%s' % (dataset_name, appliance_name)
28 | base_root = 'outnilm\\%s\\%s' % (appliance_name_folder, current_version)
29 | folder_list = {
30 | 'base_root': base_root,
31 | 'image': '%s\\image' % base_root,
32 | 'model': '%s\\model' % base_root,
33 | 'test_validation': '%s\\test_validation' % base_root,
34 | 'input': 'data\\REFIT\\after_culling\\%s\\1024\\1' % appliance_name,
35 | }
36 |
37 |
38 | isFirst = 1
39 | parser = argparse.ArgumentParser()
40 | if isFirst == 1:
41 | parser.add_argument("--checkpoint",
42 | default=None,
43 | help="directory with checkpoint to resume training from or use for testing")
44 | else:
45 | parser.add_argument("--checkpoint",
46 | default=folder_list['model'],
47 | help="directory with checkpoint to resume training from or use for testing")
48 | parser.add_argument("--output_dir",
49 | default=folder_list['base_root'],
50 | help="where to put output files")
51 | parser.add_argument("--seed", type=int)
52 | parser.add_argument("--max_steps", type=int, help="number of training steps (0 to disable)")
53 | parser.add_argument("--max_epochs", default=100, type=int, help="number of training epochs")
54 | parser.add_argument("--summary_freq", type=int, default=1000, help="update summaries every summary_freq steps")
55 | parser.add_argument("--progress_freq", type=int, default=5000, help="display progress every progress_freq steps")
56 | parser.add_argument("--trace_freq", type=int, default=0, help="trace execution every trace_freq steps")
57 | # 修改这里使得每隔100展示一次训练的图片
58 | parser.add_argument("--display_freq", type=int,
59 | default=500,
60 | help="write current training images every display_freq steps")
61 | parser.add_argument("--save_freq", type=int,
62 | default=50000,
63 | help="save model every save_freq steps, 0 to disable")
64 | parser.add_argument('--test_procedure', type=int, default=50000)
65 | parser.add_argument('--validation_procedure', type=int, default=50000)
66 | parser.add_argument("--batch_size", type=int, default=1, help="number of images in batch")
67 | parser.add_argument("--ngf", type=int, default=64, help="number of generator filters in first conv layer")
68 | parser.add_argument("--ndf", type=int, default=64, help="number of discriminator filters in first conv layer")
69 | parser.add_argument("--lr_d", type=float, default=0.001, help="initial learning rate for sgd")
70 | parser.add_argument("--lr_g", type=float, default=0.0005, help="initial learning rate for adam")
71 | parser.add_argument("--beta1", type=float, default=0.5, help="momentum term of adam")
72 | parser.add_argument("--l1_weight", type=float, default=100.0, help="weight on L1 term for generator gradient")
73 | parser.add_argument("--gan_weight", type=float, default=1.0, help="weight on GAN term for generator gradient")
74 |
75 | a = parser.parse_args()
76 | EPS = 1e-12
77 | gggg = 0
78 | scale = 1000
79 |
80 | Examples = collections.namedtuple("Examples", "inputs, targets, count,"
81 | "inputs_validation, targets_validation, count_validation, "
82 | "inputs_test, targets_test, count_test,"
83 | "steps_per_epoch")
84 | Model = collections.namedtuple("Model", "outputs, discrim_loss,"
85 | "gen_loss_GAN, gen_loss_L1, train")
86 |
87 |
88 | def discrim_conv(batch_input, out_channels, stride):
89 | return tf.layers.conv2d(batch_input, out_channels, kernel_size=(4, 1), strides=stride, padding="same",
90 | kernel_initializer=xavier_initializer_conv2d())
91 |
92 |
93 | def gen_conv(batch_input, out_channels):
94 | return tf.layers.conv2d(batch_input, out_channels, kernel_size=(4, 1), strides=(2, 1), padding="same",
95 | kernel_initializer=xavier_initializer_conv2d())
96 |
97 |
98 | def gen_deconv(batch_input, out_channels):
99 | return tf.layers.conv2d_transpose(batch_input, out_channels, kernel_size=(4, 1), strides=(2, 1), padding="same",
100 | kernel_initializer=xavier_initializer_conv2d())
101 |
102 |
103 | def lrelu(x, a):
104 | with tf.name_scope("lrelu"):
105 | x = tf.identity(x)
106 | return (0.5 * (1 + a)) * x + (0.5 * (1 - a)) * tf.abs(x)
107 |
108 |
109 | def batchnorm(x, scope='batch_instance_norm'):
110 | with tf.variable_scope(scope):
111 | ch = x.shape[-1]
112 | eps = 1e-5
113 |
114 | batch_mean, batch_sigma = tf.nn.moments(x, axes=[0, 1, 2], keep_dims=True)
115 | x_batch = (x - batch_mean) / (tf.sqrt(batch_sigma + eps))
116 |
117 | ins_mean, ins_sigma = tf.nn.moments(x, axes=[1, 2], keep_dims=True)
118 | x_ins = (x - ins_mean) / (tf.sqrt(ins_sigma + eps))
119 |
120 | rho = tf.get_variable("rho", [ch], initializer=tf.constant_initializer(1.0),
121 | constraint=lambda x: tf.clip_by_value(x, clip_value_min=0.0, clip_value_max=1.0))
122 | gamma = tf.get_variable("gamma", [ch], initializer=tf.constant_initializer(1.0))
123 | beta = tf.get_variable("beta", [ch], initializer=tf.constant_initializer(0.0))
124 |
125 | x_hat = rho * x_batch + (1 - rho) * x_ins
126 | x_hat = x_hat * gamma + beta
127 |
128 | return x_hat
129 |
130 |
131 | def create_generator(generator_inputs, generator_outputs_channels):
132 | layers = []
133 | with tf.variable_scope("encoder_1"):
134 | output = gen_conv(generator_inputs, a.ngf)
135 | layers.append(output)
136 |
137 | layer_specs = [
138 | a.ngf * 2,
139 | a.ngf * 4,
140 | a.ngf * 8,
141 | a.ngf * 8,
142 | a.ngf * 8,
143 | a.ngf * 8,
144 | a.ngf * 8,
145 | ]
146 |
147 | for out_channels in layer_specs:
148 | with tf.variable_scope("encoder_%d" % (len(layers) + 1)):
149 | rectified = lrelu(layers[-1], 0.2)
150 | convolved = gen_conv(rectified, out_channels)
151 | output = batchnorm(convolved)
152 | layers.append(output)
153 |
154 | layer_specs = [
155 | (a.ngf * 8, 0.5),
156 | (a.ngf * 8, 0.5),
157 | (a.ngf * 8, 0.5),
158 | (a.ngf * 8, 0.0),
159 | (a.ngf * 4, 0.0),
160 | (a.ngf * 2, 0.0),
161 | (a.ngf, 0.0),
162 | ]
163 |
164 | num_encoder_layers = len(layers)
165 | for decoder_layer, (out_channels, dropout) in enumerate(layer_specs):
166 | skip_layer = num_encoder_layers - decoder_layer - 1
167 | with tf.variable_scope("decoder_%d" % (skip_layer + 1)):
168 | if decoder_layer == 0:
169 | input = layers[-1]
170 | else:
171 | input = tf.concat([layers[-1], layers[skip_layer]], axis=3)
172 | rectified = tf.nn.relu(input)
173 | output = gen_deconv(rectified, out_channels)
174 | output = batchnorm(output)
175 | if dropout > 0.0:
176 | output = tf.nn.dropout(output, keep_prob=1 - dropout)
177 | layers.append(output)
178 |
179 | with tf.variable_scope("decoder_1"):
180 | input = tf.concat([layers[-1], layers[0]], axis=3)
181 | rectified = tf.nn.relu(input)
182 | output = gen_deconv(rectified, generator_outputs_channels)
183 | layers.append(output)
184 |
185 | return layers[-1]
186 |
187 |
188 | def create_model(inputs, targets, step):
189 | learning_rate_d = tf.train.exponential_decay(a.lr_d, step, 50000, 0.95, staircase=True)
190 | learning_rate_g = tf.train.exponential_decay(a.lr_g, step, 50000, 0.95, staircase=True)
191 |
192 | def create_discriminator(discrim_inputs, discrim_targets):
193 | n_layers = 3
194 | layers = []
195 |
196 | input = tf.concat([discrim_inputs, discrim_targets], axis=1)
197 |
198 | with tf.variable_scope("layer_1"):
199 | convolved = discrim_conv(input, a.ndf, stride=(2, 1))
200 | rectified = lrelu(convolved, 0.2)
201 | layers.append(rectified)
202 |
203 | for i in range(n_layers):
204 | with tf.variable_scope("layer_%d" % (len(layers) + 1)):
205 | out_channels = a.ndf * min(2**(i+1), 8)
206 | stride = 1 if i == n_layers - 1 else (2, 1)
207 | convolved = discrim_conv(layers[-1], out_channels, stride=stride)
208 | normalized = batchnorm(convolved)
209 | rectified = lrelu(normalized, 0.2)
210 | layers.append(rectified)
211 |
212 | with tf.variable_scope("layer_%d" % (len(layers) + 1)):
213 | convolved = discrim_conv(rectified, out_channels=1, stride=1)
214 | output = tf.sigmoid(convolved)
215 | layers.append(output)
216 |
217 | return layers[-1]
218 |
219 | with tf.variable_scope("generator"):
220 | out_channels = int(targets.get_shape()[-1])
221 | outputs = create_generator(inputs, out_channels)[:, 256:768, :, :]
222 |
223 | with tf.name_scope("real_discriminator"):
224 | with tf.variable_scope("discriminator"):
225 | predict_real = create_discriminator(inputs, targets)
226 |
227 | with tf.name_scope("fake_discriminator"):
228 | with tf.variable_scope("discriminator", reuse=True):
229 | predict_fake = create_discriminator(inputs, outputs)
230 |
231 | with tf.name_scope("discriminator_loss"):
232 | # minimizing -tf.log will try to get inputs to 1
233 | # predict_real => 1
234 | # predict_fake => 0
235 | discrim_loss = tf.reduce_mean(-(tf.log(predict_real + EPS) + tf.log(1 - predict_fake + EPS)))
236 |
237 | with tf.name_scope("generator_loss"):
238 | # predict_fake => 1
239 | # abs(targets - outputs) => 0
240 | gen_loss_GAN = tf.reduce_mean(-tf.log(predict_fake + EPS))
241 | gen_loss_L1 = tf.reduce_mean(tf.abs(targets - outputs))
242 | gen_loss = gen_loss_GAN * a.gan_weight + gen_loss_L1 * a.l1_weight
243 |
244 | with tf.name_scope("discriminator_train"):
245 | discrim_tvars = [var for var in tf.trainable_variables() if var.name.startswith("discriminator")]
246 | discrim_optim = tf.train.GradientDescentOptimizer(learning_rate=learning_rate_d)
247 | discrim_grads_and_vars = discrim_optim.compute_gradients(discrim_loss, var_list=discrim_tvars)
248 | discrim_train = discrim_optim.apply_gradients(discrim_grads_and_vars)
249 |
250 | with tf.name_scope("generator_train"):
251 | with tf.control_dependencies([discrim_train]):
252 | gen_tvars = [var for var in tf.trainable_variables() if var.name.startswith("generator")]
253 | gen_optim = tf.train.AdamOptimizer(learning_rate=learning_rate_g, beta1=a.beta1)
254 | gen_grads_and_vars = gen_optim.compute_gradients(gen_loss, var_list=gen_tvars)
255 | gen_train = gen_optim.apply_gradients(gen_grads_and_vars)
256 |
257 | ema = tf.train.ExponentialMovingAverage(decay=0.99)
258 | update_losses = ema.apply([discrim_loss, gen_loss_GAN, gen_loss_L1])
259 |
260 | global_step = tf.train.get_or_create_global_step()
261 | incr_global_step = tf.assign(global_step, global_step+1)
262 |
263 | return Model(
264 | discrim_loss=ema.average(discrim_loss),
265 | gen_loss_GAN=ema.average(gen_loss_GAN),
266 | gen_loss_L1=ema.average(gen_loss_L1),
267 | outputs=outputs,
268 | train=tf.group(update_losses, incr_global_step, gen_train),
269 | )
270 |
271 |
272 | def display_image(inputs, targets, outputs):
273 | global gggg
274 | fig = plt.figure(figsize=(16, 16), dpi=100)
275 | gs = gridspec.GridSpec(3, 1)
276 | gs.update(wspace=0.05, hspace=0.05)
277 | agg = np.reshape(inputs, [1024])
278 | app = np.reshape(targets, [512])
279 | out = np.reshape(outputs, [512])
280 | agg_new = []
281 | app_new = []
282 | out_new = []
283 | x = np.linspace(256, 768, 512)
284 |
285 | for i in agg:
286 | agg_new.append(int(i*scale))
287 | for i in range(512):
288 | app_new.append(int(app[i]*scale))
289 | out_new.append(int(out[i]*scale))
290 |
291 | plt.subplot(3, 1, 1)
292 | plt.xlim(0, 1024)
293 | plt.plot(agg_new)
294 |
295 | plt.subplot(3, 1, 2)
296 | plt.xlim(0, 1024)
297 | plt.plot(x, app_new)
298 |
299 | plt.subplot(3, 1, 3)
300 | plt.xlim(0, 1024)
301 | plt.plot(x, out_new)
302 |
303 | plt.savefig(('%s/{}.png' % folder_list['image'])
304 | .format(str(gggg).zfill(3)), bbox_inches='tight')
305 | gggg += 1
306 | plt.close(fig)
307 |
308 |
309 | def metric(target_data, output_data, t_v, step):
310 | tar_new = []
311 | out_new = []
312 | mae = []
313 |
314 | for i in range(len(output_data)):
315 | for j in range(len(output_data[i])):
316 | if output_data[i][j] < 0:
317 | o = 0
318 | else:
319 | o = output_data[i][j]
320 | out_new.append(o)
321 | tar_new.append(target_data[i][j])
322 |
323 | for i in range(len(out_new)):
324 | r = abs(tar_new[i] - out_new[i])
325 | mae.append(r)
326 |
327 | accuracy = (1.0-(np.sum(mae, dtype=np.int64)/(2*np.sum(tar_new, dtype=np.int64))))*100
328 | print('np.sum(mae):')
329 | print(np.sum(mae))
330 | print('np.sum(tar_new):')
331 | print(np.sum(tar_new))
332 | sae = abs(np.sum(tar_new, dtype=np.int64)-np.sum(out_new, dtype=np.int64))/np.sum(tar_new, dtype=np.int64)
333 | mse = mean_squared_error(tar_new, out_new)
334 | mae = mean_absolute_error(tar_new, out_new)
335 | r2 = r2_score(tar_new, out_new)
336 |
337 | if t_v == 'validation':
338 | with open('%s\\validation.txt' % folder_list['test_validation'], 'a+') as f:
339 | print('STEP: %d' % (step+1), file=f)
340 | print('Accuracy: %f' % accuracy, file=f)
341 | print('SAE: %f' % sae, file=f)
342 | print('MSE: %f' % mse, file=f)
343 | print('MAE: %f' % mae, file=f)
344 | print('R^2: %f' % r2, file=f)
345 | print('', file=f)
346 | else:
347 | with open('%s\\test.txt' % folder_list['test_validation'], 'a+') as f:
348 | print('STEP: %d' % (step+1), file=f)
349 | print('Accuracy: %f' % accuracy, file=f)
350 | print('SAE: %f' % sae, file=f)
351 | print('MSE: %f' % mse, file=f)
352 | print('MAE: %f' % mae, file=f)
353 | print('R^2: %f' % r2, file=f)
354 | print('', file=f)
355 |
356 |
357 | def load_examples():
358 | base_path = folder_list['input']
359 |
360 | ap_data = np.load(os.path.join(base_path, 'appliance_train_512.npy'))
361 | ag_data = np.load(os.path.join(base_path, 'main_train_1000.npy'))
362 | ap_data_validation = np.load(os.path.join(base_path, 'appliance_validation_512.npy'))
363 | ag_data_validation = np.load(os.path.join(base_path, 'main_validation_1000.npy'))
364 | ap_data_test = np.load(os.path.join(base_path, 'appliance_test_512.npy'))
365 | ag_data_test = np.load(os.path.join(base_path, 'main_test_1000.npy'))
366 | print('Data load complete!')
367 |
368 | appliance_data = tf.cast(ap_data, tf.float32)
369 | aggregate_data = tf.cast(ag_data, tf.float32)
370 | appliance_data_validation = tf.cast(ap_data_validation, tf.float32)
371 | aggregate_data_validation = tf.cast(ag_data_validation, tf.float32)
372 | appliance_data_test = tf.cast(ap_data_test, tf.float32)
373 | aggregate_data_test = tf.cast(ag_data_test, tf.float32)
374 | print('cast complete!')
375 |
376 | queue = tf.train.slice_input_producer([aggregate_data, appliance_data], shuffle=True)
377 | inputs_batch, targets_batch = tf.train.batch(queue, batch_size=a.batch_size)
378 | queue_validation = tf.train.slice_input_producer([aggregate_data_validation, appliance_data_validation], shuffle=False)
379 | inputs_batch_validation, targets_batch_validation = tf.train.batch(queue_validation, batch_size=a.batch_size)
380 | queue_test = tf.train.slice_input_producer([aggregate_data_test, appliance_data_test], shuffle=False)
381 | inputs_batch_test, targets_batch_test = tf.train.batch(queue_test, batch_size=a.batch_size)
382 |
383 | steps_per_epoch = int(math.ceil(len(ap_data) / a.batch_size))
384 |
385 | return Examples(
386 | inputs=inputs_batch,
387 | targets=targets_batch,
388 | count=len(ap_data),
389 | inputs_validation=inputs_batch_validation,
390 | targets_validation=targets_batch_validation,
391 | count_validation=len(ap_data_validation),
392 | inputs_test=inputs_batch_test,
393 | targets_test=targets_batch_test,
394 | count_test=len(ap_data_test),
395 | steps_per_epoch=steps_per_epoch,
396 | )
397 |
398 |
399 | def main():
400 | if a.seed is None:
401 | a.seed = random.randint(0, 2**31 - 1)
402 | tf.set_random_seed(a.seed)
403 | np.random.seed(a.seed)
404 | random.seed(a.seed)
405 |
406 | for folder_name, folder_path in folder_list.items():
407 | if not os.path.exists(folder_path):
408 | os.makedirs(folder_path)
409 | print('Folder creation complete!')
410 |
411 | with open(os.path.join(folder_list['base_root'], 'config.txt'), 'w') as f:
412 | for k, v in a._get_kwargs():
413 | print(k, "=", v, file=f)
414 | print('Config save complete!')
415 |
416 | examples = load_examples()
417 | trainable = tf.placeholder(tf.bool)
418 | global_step = tf.placeholder(tf.float32, None)
419 | inputs = tf.placeholder(tf.float32, [a.batch_size, 1024, 1, 1])
420 | targets = tf.placeholder(tf.float32, [a.batch_size, 512, 1, 1])
421 | i_ = tf.reshape(examples.inputs, [a.batch_size, 1024, 1, 1])
422 | t_ = tf.reshape(examples.targets, [a.batch_size, 512, 1, 1])
423 | i_t = tf.reshape(examples.inputs_test, [a.batch_size, 1024, 1, 1])
424 | t_t = tf.reshape(examples.targets_test, [a.batch_size, 512, 1, 1])
425 | i_v = tf.reshape(examples.inputs_validation, [a.batch_size, 1024, 1, 1])
426 | t_v = tf.reshape(examples.targets_validation, [a.batch_size, 512, 1, 1])
427 | model = create_model(inputs, targets, global_step)
428 | print('model complete!')
429 |
430 | with tf.name_scope("display_images"):
431 | display_fetches = {
432 | 'output': model.outputs,
433 | }
434 |
435 | tf.summary.scalar("discriminator_loss", model.discrim_loss)
436 | tf.summary.scalar("generator_loss_GAN", model.gen_loss_GAN)
437 | tf.summary.scalar("generator_loss_L1", model.gen_loss_L1)
438 |
439 | with tf.name_scope("parameter_count"):
440 | parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) for v in tf.trainable_variables()])
441 |
442 | saver = tf.train.Saver(max_to_keep=50)
443 |
444 | logdir = a.output_dir if (a.trace_freq > 0 or a.summary_freq > 0) else None
445 | sv = tf.train.Supervisor(logdir=logdir, save_summaries_secs=0, saver=None)
446 | with sv.managed_session() as sess:
447 | print("parameter_count =", sess.run(parameter_count))
448 | if a.checkpoint is not None:
449 | print("loading model from checkpoint")
450 | checkpoint = tf.train.latest_checkpoint(a.checkpoint)
451 | saver.restore(sess, checkpoint)
452 |
453 | max_steps = 2**32
454 | if a.max_epochs is not None:
455 | max_steps = examples.steps_per_epoch * a.max_epochs
456 | if a.max_steps is not None:
457 | max_steps = a.max_steps
458 |
459 | start = time.time()
460 | output_validation = []
461 | target_validation = []
462 | output_test = []
463 | target_test = []
464 |
465 | for step in range(max_steps):
466 |
467 | def should(freq):
468 | return freq > 0 and ((step + 1) % freq == 0 or step == max_steps - 1)
469 |
470 | options = None
471 | run_metadata = None
472 | if should(a.trace_freq):
473 | options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
474 | run_metadata = tf.RunMetadata()
475 |
476 | fetches = {
477 | "train": model.train,
478 | "global_step": sv.global_step,
479 | }
480 | if should(a.progress_freq):
481 | fetches["discrim_loss"] = model.discrim_loss
482 | fetches["gen_loss_GAN"] = model.gen_loss_GAN
483 | fetches["gen_loss_L1"] = model.gen_loss_L1
484 |
485 | if should(a.summary_freq):
486 | fetches["summary"] = sv.summary_op
487 |
488 | if should(a.display_freq):
489 | fetches["display"] = display_fetches
490 |
491 | inputs_, targets_ = sess.run([i_, t_])
492 | results = sess.run(fetches,
493 | options=options,
494 | run_metadata=run_metadata,
495 | feed_dict={global_step: step,
496 | inputs: inputs_,
497 | targets: targets_})
498 |
499 | if should(a.display_freq):
500 | data = results['display']
501 | display_image(inputs_, targets_, data['output'])
502 |
503 | if should(a.summary_freq):
504 | sv.summary_writer.add_summary(results["summary"], results["global_step"])
505 |
506 | if should(a.progress_freq):
507 | train_epoch = math.ceil(results["global_step"] / examples.steps_per_epoch)
508 | train_step = (results["global_step"] - 1) % examples.steps_per_epoch + 1
509 | rate = (step + 1) * a.batch_size / (time.time() - start)
510 | print("progress epoch %d step %d image/sec %0.1f" %
511 | (train_epoch, train_step+1, rate))
512 | print("discrim_loss", results["discrim_loss"])
513 | print("gen_loss_GAN", results["gen_loss_GAN"])
514 | print("gen_loss_L1", results["gen_loss_L1"])
515 |
516 | if should(a.save_freq):
517 | print("saving model")
518 | saver.save(sess, os.path.join(folder_list['model'], "model"), global_step=sv.global_step)
519 |
520 | if should(a.test_procedure):
521 | print('Test procedure!')
522 | target_test.clear()
523 | output_test.clear()
524 | max_steps_test = examples.count_test
525 | for step_test in range(max_steps_test):
526 | inputs_, targets_= sess.run([i_t, t_t])
527 | data = sess.run({
528 | 'output': model.outputs,
529 | }, feed_dict={
530 | global_step: results['global_step'],
531 | inputs: inputs_,
532 | targets: targets_
533 | })
534 | _target = np.reshape(targets_, [a.batch_size, 512])
535 | _output = np.reshape(data['output'], [a.batch_size, 512])
536 | for i in range(a.batch_size):
537 | tar_temp = []
538 | out_temp = []
539 | for j in range(512):
540 | tar_temp.append(int(_target[i][j] * scale))
541 | out_temp.append(int(_output[i][j] * scale))
542 | target_test.append(tar_temp)
543 | output_test.append(out_temp)
544 | if step_test % 1000 == 0:
545 | print('Process Test: %f Rate: %f' % (step_test / max_steps_test,
546 | (time.time() - start) / max_steps_test))
547 | np.save('%s\\test_target_%d.npy' % (folder_list['test_validation'], results['global_step']+1), target_test)
548 | np.save('%s\\test_output_%d.npy' % (folder_list['test_validation'], results['global_step']+1), output_test)
549 | metric(target_test, output_test, 'test', results['global_step'])
550 | print('Test procedure complete!')
551 |
552 | if should(a.validation_procedure):
553 | print('Validation procedure!')
554 | target_validation.clear()
555 | output_validation.clear()
556 | max_steps_validation = examples.count_validation
557 | for step_validation in range(max_steps_validation):
558 | inputs_, targets_ = sess.run([i_v, t_v])
559 | data = sess.run({
560 | 'output': model.outputs,
561 | }, feed_dict={
562 | global_step: results['global_step'],
563 | inputs: inputs_,
564 | targets: targets_
565 | })
566 | _target = np.reshape(targets_, [a.batch_size, 512])
567 | _output = np.reshape(data['output'], [a.batch_size, 512])
568 | for i in range(a.batch_size):
569 | tar_temp = []
570 | out_temp = []
571 | for j in range(512):
572 | tar_temp.append(int(_target[i][j] * scale))
573 | out_temp.append(int(_output[i][j] * scale))
574 | target_validation.append(tar_temp)
575 | output_validation.append(out_temp)
576 | if step_validation % 1000 == 0:
577 | print('Process Validation: %f Rate: %f' % (step_validation / max_steps_validation,
578 | (time.time() - start) / max_steps_validation))
579 | np.save('%s\\validation_target_%d.npy' % (folder_list['test_validation'], results['global_step']+1), target_validation)
580 | np.save('%s\\validation_output_%d.npy' % (folder_list['test_validation'], results['global_step']+1), output_validation)
581 | metric(target_validation, output_validation, 'validation', results['global_step'])
582 | print('Validation procedure complete!')
583 |
584 | if sv.should_stop():
585 | break
586 |
587 |
588 | main()
589 |
--------------------------------------------------------------------------------