Upload 20 files
Browse files- Attributes.txt +40 -0
- BP神经网络对excel文件数据,小批量训练并且包含交叉验证.py +140 -0
- BP神经网络,10次10折.py +105 -0
- bal.xls +0 -0
- gla.xls +0 -0
- hay.xls +0 -0
- iri.xls +0 -0
- mnist.pkl.gz +3 -0
- neural network.py +136 -0
- new.xls +0 -0
- test.py +137 -0
- test0.py +105 -0
- win.xls +0 -0
- zoo.xls +0 -0
- 神经网络,有留出测试集.py +133 -0
- 神经网络,没有留出.py +131 -0
- 神经网络,添加k折交叉验证.py +138 -0
- 移除小批量之后的算法.py +114 -0
- 网络,k折,无测集,小批量梯度下降优化算法.py +127 -0
- 调包版.py +34 -0
Attributes.txt
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
0: denotes that the attribute is number;
|
2 |
+
1: denotes that the attribute is nominal.
|
3 |
+
|
4 |
+
aut = [0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0];
|
5 |
+
aba = [1,0,0,0,0,0,0,0];
|
6 |
+
bal = [0,0,0,0];
|
7 |
+
car = [1,1,1,1,1,1];
|
8 |
+
cle = [0,1,1,0,0,1,1,0,1,0,1,1,1];
|
9 |
+
con = [0,0,0,0,1,1,0,0,1];
|
10 |
+
der = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0];
|
11 |
+
eco = [0,0,0,0,0,0,0];
|
12 |
+
fla = [1,1,1,1,1,1,1,1,1,1,1];
|
13 |
+
gla = [0,0,0,0,0,0,0,0,0];
|
14 |
+
hay = [0,0,0,0];
|
15 |
+
iri = [0,0,0,0];
|
16 |
+
kr-vs-k = [1,1,1,1,1,1];
|
17 |
+
led = [1,1,1,1,1,1,1];
|
18 |
+
let = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
19 |
+
lym = [1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0];
|
20 |
+
mar = [0,0,0,0,0,0,0,0,0,0,0,0,0];
|
21 |
+
mov = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
22 |
+
new = [0,0,0,0,0];
|
23 |
+
nur = [1,1,1,1,1,1,1,1];
|
24 |
+
OPT = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
25 |
+
pag = [0,0,0,0,0,0,0,0,0,0];
|
26 |
+
pen = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
27 |
+
sat = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
28 |
+
shu = [0,0,0,0,0,0,0,0,0];
|
29 |
+
seg = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
30 |
+
spl = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
|
31 |
+
tae = [1,1,1,1,0];
|
32 |
+
tex = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
33 |
+
thy = [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
|
34 |
+
veh = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
35 |
+
vow = [0,0,0,0,0,0,0,0,0,0,0,0,0];
|
36 |
+
win = [0,0,0,0,0,0,0,0,0,0,0,0,0];
|
37 |
+
wqr = [0,0,0,0,0,0,0,0,0,0,0];
|
38 |
+
wqw = [0,0,0,0,0,0,0,0,0,0,0];
|
39 |
+
yea = [0,0,0,0,0,0,0,0];
|
40 |
+
zoo = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
|
BP神经网络对excel文件数据,小批量训练并且包含交叉验证.py
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
def __init__(self, sizes):
|
7 |
+
self.num_layers = len(sizes)
|
8 |
+
self.sizes = sizes
|
9 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
10 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
11 |
+
|
12 |
+
def feedforward(self, a):
|
13 |
+
for b, w in zip(self.biases, self.weights):
|
14 |
+
a = sigmoid(np.dot(w, a) + b)
|
15 |
+
return a
|
16 |
+
|
17 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, k, file_name):
|
18 |
+
n = len(training_data)
|
19 |
+
for j in range(epochs):
|
20 |
+
np.random.shuffle(training_data)
|
21 |
+
folds = [training_data[i::k] for i in range(k)]
|
22 |
+
|
23 |
+
# 在每个 epoch 的开始打印文件名和 epoch 信息
|
24 |
+
if j == 0:
|
25 |
+
print(f"\nTraining on file: {file_name}")
|
26 |
+
print(f"\nEpoch {j}:")
|
27 |
+
|
28 |
+
for i in range(k):
|
29 |
+
validation_data = folds[i]
|
30 |
+
train_data = [item for fold in folds if fold is not validation_data for item in fold]
|
31 |
+
|
32 |
+
for mini_batch in [train_data[m:m+mini_batch_size] for m in range(0, len(train_data), mini_batch_size)]:
|
33 |
+
self.update_mini_batch(mini_batch, eta)
|
34 |
+
|
35 |
+
# 在每个 fold 结束后打印验证结果
|
36 |
+
print(f"Fold {i}: {self.evaluate(validation_data)}/{len(validation_data)}")
|
37 |
+
|
38 |
+
|
39 |
+
|
40 |
+
def update_mini_batch(self, mini_batch, eta):
|
41 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
42 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
43 |
+
for x, y in mini_batch:
|
44 |
+
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
|
45 |
+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
46 |
+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
47 |
+
self.weights = [w - (eta / len(mini_batch)) * nw for w, nw in zip(self.weights, nabla_w)]
|
48 |
+
self.biases = [b - (eta / len(mini_batch)) * nb for b, nb in zip(self.biases, nabla_b)]
|
49 |
+
|
50 |
+
|
51 |
+
def cost_derivative(self, output_activations, y):
|
52 |
+
return output_activations - y
|
53 |
+
|
54 |
+
|
55 |
+
def evaluate(self, test_data):
|
56 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
57 |
+
return sum(int(x == y) for (x, y) in test_results)
|
58 |
+
|
59 |
+
|
60 |
+
def backprop(self, x, y):
|
61 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
62 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
63 |
+
activation = x
|
64 |
+
activations = [x]
|
65 |
+
zs = []
|
66 |
+
|
67 |
+
for b, w in zip(self.biases, self.weights):
|
68 |
+
z = np.dot(w, activation)+b
|
69 |
+
zs.append(z)
|
70 |
+
activation = sigmoid(z)
|
71 |
+
activations.append(activation)
|
72 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
73 |
+
nabla_b[-1] = delta
|
74 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
75 |
+
|
76 |
+
for l in range(2, self.num_layers):
|
77 |
+
z = zs[-l]
|
78 |
+
sp = sigmoid_prime(z)
|
79 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
80 |
+
nabla_b[-l] = delta
|
81 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
82 |
+
return (nabla_b, nabla_w)
|
83 |
+
|
84 |
+
def sigmoid(z):
|
85 |
+
return 1.0 / (1.0 + np.exp(-z))
|
86 |
+
|
87 |
+
def sigmoid_prime(z):
|
88 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
89 |
+
|
90 |
+
def load_and_preprocess_data(file_path):
|
91 |
+
# Load the dataset
|
92 |
+
data = pd.read_excel(file_path, header=None)
|
93 |
+
# Normalize numerical features
|
94 |
+
data.iloc[:, :-1] = (data.iloc[:, :-1] - data.iloc[:, :-1].mean()) / data.iloc[:, :-1].std()
|
95 |
+
|
96 |
+
# Ensure labels are starting from 0 and continuous
|
97 |
+
if data.iloc[:, -1].dtype == object or np.issubdtype(data.iloc[:, -1].dtype, np.integer):
|
98 |
+
# Create a mapping for labels to integers
|
99 |
+
label_mapping = {label: idx for idx, label in enumerate(np.unique(data.iloc[:, -1]))}
|
100 |
+
# Apply mapping
|
101 |
+
data.iloc[:, -1] = data.iloc[:, -1].map(label_mapping)
|
102 |
+
|
103 |
+
# Split data into features and labels
|
104 |
+
features = data.iloc[:, :-1].values
|
105 |
+
labels = data.iloc[:, -1].values
|
106 |
+
|
107 |
+
# Determine the size for the vectorized result
|
108 |
+
unique_labels = len(np.unique(labels))
|
109 |
+
|
110 |
+
# Vectorize labels for the network
|
111 |
+
labels = np.array([vectorized_result(label, unique_labels) for label in labels])
|
112 |
+
|
113 |
+
# Combine features and labels
|
114 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features], labels))
|
115 |
+
return dataset
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
def vectorized_result(j, size):
|
120 |
+
e = np.zeros((size, 1))
|
121 |
+
e[j] = 1.0
|
122 |
+
return e
|
123 |
+
|
124 |
+
# Directory containing the .xls files
|
125 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
126 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
127 |
+
|
128 |
+
for file in files:
|
129 |
+
file_path = os.path.join(folder_path, file)
|
130 |
+
data = load_and_preprocess_data(file_path)
|
131 |
+
|
132 |
+
# Infer input and output sizes
|
133 |
+
input_size = len(data[0][0])
|
134 |
+
output_size = len(data[0][1])
|
135 |
+
|
136 |
+
# Initialize the network
|
137 |
+
net = Network([input_size, 30, output_size]) # Example: one hidden layer with 30 neurons
|
138 |
+
|
139 |
+
# Train the network with k-fold cross-validation
|
140 |
+
net.SGD(data, 5, 10, 3.0, 5, file) # 5-fold cross-validation
|
BP神经网络,10次10折.py
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
def __init__(self, sizes):
|
7 |
+
self.num_layers = len(sizes)
|
8 |
+
self.sizes = sizes
|
9 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
10 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
11 |
+
|
12 |
+
def feedforward(self, a):
|
13 |
+
for b, w in zip(self.biases, self.weights):
|
14 |
+
a = sigmoid(np.dot(w, a) + b)
|
15 |
+
return a
|
16 |
+
|
17 |
+
def train(self, training_data, epochs, eta):
|
18 |
+
n = len(training_data)
|
19 |
+
for j in range(epochs):
|
20 |
+
np.random.shuffle(training_data)
|
21 |
+
for x, y in training_data:
|
22 |
+
self.update_network(x, y, eta)
|
23 |
+
|
24 |
+
|
25 |
+
def update_network(self, x, y, eta):
|
26 |
+
nabla_b, nabla_w = self.backprop(x, y)
|
27 |
+
self.weights = [w - eta * nw for w, nw in zip(self.weights, nabla_w)]
|
28 |
+
self.biases = [b - eta * nb for b, nb in zip(self.biases, nabla_b)]
|
29 |
+
|
30 |
+
def evaluate(self, test_data):
|
31 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
32 |
+
return sum(int(x == y) for (x, y) in test_results)
|
33 |
+
|
34 |
+
def backprop(self, x, y):
|
35 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
36 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
37 |
+
activation = x
|
38 |
+
activations = [x]
|
39 |
+
zs = []
|
40 |
+
for b, w in zip(self.biases, self.weights):
|
41 |
+
z = np.dot(w, activation) + b
|
42 |
+
zs.append(z)
|
43 |
+
activation = sigmoid(z)
|
44 |
+
activations.append(activation)
|
45 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
46 |
+
nabla_b[-1] = delta
|
47 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
48 |
+
for l in range(2, self.num_layers):
|
49 |
+
z = zs[-l]
|
50 |
+
sp = sigmoid_prime(z)
|
51 |
+
delta = np.dot(self.weights[-l + 1].transpose(), delta) * sp
|
52 |
+
nabla_b[-l] = delta
|
53 |
+
nabla_w[-l] = np.dot(delta, activations[-l - 1].transpose())
|
54 |
+
return (nabla_b, nabla_w)
|
55 |
+
|
56 |
+
def cost_derivative(self, output_activations, y):
|
57 |
+
return (output_activations - y)
|
58 |
+
|
59 |
+
def sigmoid(z):
|
60 |
+
return 1.0 / (1.0 + np.exp(-z))
|
61 |
+
|
62 |
+
def sigmoid_prime(z):
|
63 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
64 |
+
|
65 |
+
def k_fold_cross_validation(dataset, k):
|
66 |
+
np.random.shuffle(dataset)
|
67 |
+
fold_size = len(dataset) // k
|
68 |
+
for i in range(k):
|
69 |
+
validation_data = dataset[i * fold_size:(i + 1) * fold_size]
|
70 |
+
training_data = dataset[:i * fold_size] + dataset[(i + 1) * fold_size:]
|
71 |
+
yield training_data, validation_data
|
72 |
+
|
73 |
+
def load_and_preprocess_data(file_path):
|
74 |
+
data = pd.read_excel(file_path, header=None)
|
75 |
+
features = data.iloc[:, :-1]
|
76 |
+
features = (features - features.mean()) / features.std()
|
77 |
+
labels = data.iloc[:, -1]
|
78 |
+
if labels.dtype == object or np.issubdtype(labels.dtype, np.integer):
|
79 |
+
unique_labels = labels.unique()
|
80 |
+
label_mapping = {label: idx for idx, label in enumerate(unique_labels)}
|
81 |
+
labels = labels.map(label_mapping)
|
82 |
+
label_vectors = np.zeros((labels.size, len(unique_labels)))
|
83 |
+
for i, label in enumerate(labels):
|
84 |
+
label_vectors[i, label] = 1
|
85 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features.to_numpy()], [np.reshape(y, (len(y), 1)) for y in label_vectors]))
|
86 |
+
return dataset
|
87 |
+
|
88 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
89 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
90 |
+
|
91 |
+
for file in files:
|
92 |
+
file_path = os.path.join(folder_path, file)
|
93 |
+
dataset = load_and_preprocess_data(file_path)
|
94 |
+
for iteration in range(10):
|
95 |
+
accuracies = []
|
96 |
+
for i, (train_data, validation_data) in enumerate(k_fold_cross_validation(dataset, 10)):
|
97 |
+
input_size = len(train_data[0][0])
|
98 |
+
output_size = len(train_data[0][1])
|
99 |
+
net = Network([input_size, 30, output_size])
|
100 |
+
net.train(train_data, 30, 1.0)
|
101 |
+
validation_accuracy = net.evaluate(validation_data)
|
102 |
+
accuracies.append(validation_accuracy / len(validation_data))
|
103 |
+
average_accuracy = (sum(accuracies) / len(accuracies)) * 100
|
104 |
+
print(f"\nIteration {iteration + 1} Training on file: {file}")
|
105 |
+
print(f"Average Validation Accuracy: {average_accuracy:.2f}%")
|
bal.xls
ADDED
Binary file (61.4 kB). View file
|
|
gla.xls
ADDED
Binary file (48.1 kB). View file
|
|
hay.xls
ADDED
Binary file (31.7 kB). View file
|
|
iri.xls
ADDED
Binary file (26.6 kB). View file
|
|
mnist.pkl.gz
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f11bb9e41d6c1b6c124aa38fd605497bdcfe2ee08cf7c2bb5a41ab5d759e1416
|
3 |
+
size 17051982
|
neural network.py
ADDED
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import gzip
|
3 |
+
import pickle
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
class Network(object):
|
8 |
+
|
9 |
+
def __init__(self, sizes):
|
10 |
+
self.num_layers = len(sizes)#sizes 列表包含 各层神经元的数量。
|
11 |
+
self.sizes = sizes
|
12 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
13 |
+
self.weights = [np.random.randn(y, x) for x,y in zip(sizes[:-1], sizes[1:])]
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
#例:net = Network([2,3,1]) 创建一个 第一层2个 第二层3个 第三层1个 神经元的 Network对象
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
def feedforward(self, a):
|
22 |
+
#当a为输入时,返回神经网络的输出
|
23 |
+
for b, w in zip(self.biases, self.weights):
|
24 |
+
a = sigmoid(np.dot(w, a) + b)
|
25 |
+
|
26 |
+
return a
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, test_data = None):
|
31 |
+
#epochs=迭代次数 eta=学习速率
|
32 |
+
if test_data: n_test = len(test_data)
|
33 |
+
n = len(training_data)
|
34 |
+
|
35 |
+
for j in range(epochs):
|
36 |
+
np.random.shuffle(training_data)
|
37 |
+
|
38 |
+
mini_batches = [training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)]
|
39 |
+
|
40 |
+
for mini_batch in mini_batches:
|
41 |
+
self.update_mini_batch(mini_batch, eta)
|
42 |
+
|
43 |
+
if test_data:
|
44 |
+
print("Epoch {0}: {1}/ {2}".format(j, self.evaluate(test_data), n_test))
|
45 |
+
else:
|
46 |
+
print("Epoch {0} complete".format(j))
|
47 |
+
|
48 |
+
|
49 |
+
def update_mini_batch(self, mini_batch, eta):
|
50 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
51 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
52 |
+
|
53 |
+
for x, y in mini_batch:
|
54 |
+
delta_nabla_b, delta_nabla_w = self.backdrop(x, y)
|
55 |
+
|
56 |
+
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
57 |
+
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
58 |
+
|
59 |
+
self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)]
|
60 |
+
self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)]
|
61 |
+
|
62 |
+
|
63 |
+
def evaluate(self, test_data): #测试当前迭代期对测试数据的效果
|
64 |
+
test_results = [(np.argmax(self.feedforward(x)), y) for (x, y) in test_data]
|
65 |
+
return sum(int(x == y) for (x, y) in test_results)
|
66 |
+
|
67 |
+
|
68 |
+
def cost_derivative(self, output_activations, y):
|
69 |
+
return output_activations - y
|
70 |
+
|
71 |
+
def backdrop(self, x, y):
|
72 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
73 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
74 |
+
activation = x
|
75 |
+
activations = [x]
|
76 |
+
zs = []
|
77 |
+
#z是上一层的输入
|
78 |
+
for b, w in zip(self.biases, self.weights):
|
79 |
+
z = np.dot(w, activation)+b
|
80 |
+
zs.append(z)
|
81 |
+
activation = sigmoid(z)
|
82 |
+
activations.append(activation)
|
83 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
84 |
+
nabla_b[-1] = delta
|
85 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
86 |
+
|
87 |
+
for l in range(2, self.num_layers):
|
88 |
+
z = zs[-l]
|
89 |
+
sp = sigmoid_prime(z)
|
90 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
91 |
+
nabla_b[-l] = delta
|
92 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
93 |
+
return (nabla_b, nabla_w)
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
def sigmoid(z): #激活函数 常用于二分类 等问题 不过存在 极大值或极小值 梯度趋于0的问题
|
102 |
+
return 1.0/(1.0+np.exp(-z))
|
103 |
+
|
104 |
+
def sigmoid_prime(z): # 计算sigmoid函数的导数
|
105 |
+
return sigmoid(z)*(1-sigmoid(z))
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
def load_data():
|
112 |
+
with gzip.open('C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\BP神经网络\\mnist.pkl.gz', 'rb') as f:
|
113 |
+
training_data, validation_data, test_data = pickle.load(f, encoding='latin1')
|
114 |
+
|
115 |
+
return (training_data, validation_data, test_data)
|
116 |
+
|
117 |
+
def load_data_wrapper():
|
118 |
+
tr_d, va_d, te_d = load_data()
|
119 |
+
training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
|
120 |
+
training_results = [vectorized_result(y) for y in tr_d[1]]
|
121 |
+
training_data = list(zip(training_inputs, training_results))
|
122 |
+
validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
|
123 |
+
validation_data = list(zip(validation_inputs, va_d[1]))
|
124 |
+
test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
|
125 |
+
test_data = list(zip(test_inputs, te_d[1]))
|
126 |
+
return (training_data, validation_data, test_data)
|
127 |
+
|
128 |
+
def vectorized_result(j):
|
129 |
+
e = np.zeros((10, 1))
|
130 |
+
e[j] = 1.0
|
131 |
+
return e
|
132 |
+
|
133 |
+
|
134 |
+
training_data, validation_data, test_data = load_data_wrapper()
|
135 |
+
net = Network([784, 41, 10])
|
136 |
+
net.SGD(training_data, 3, 10, 3.0, test_data = test_data)
|
new.xls
ADDED
Binary file (38.9 kB). View file
|
|
test.py
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import gzip
|
3 |
+
import pickle
|
4 |
+
import pandas as pd
|
5 |
+
|
6 |
+
class Network(object):
|
7 |
+
|
8 |
+
def __init__(self, sizes):
|
9 |
+
self.num_layers = len(sizes)
|
10 |
+
self.sizes = sizes
|
11 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
12 |
+
self.weights = [np.random.randn(y, x) for x,y in zip(sizes[:-1], sizes[1:])]
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
def feedforward(self, a):
|
21 |
+
|
22 |
+
for b, w in zip(self.biases, self.weights):
|
23 |
+
a = sigmoid(np.dot(w, a) + b)
|
24 |
+
|
25 |
+
return a
|
26 |
+
|
27 |
+
|
28 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, k, test_data=None):
|
29 |
+
if test_data:
|
30 |
+
n_test = len(test_data)
|
31 |
+
|
32 |
+
for j in range(epochs):
|
33 |
+
np.random.shuffle(training_data)
|
34 |
+
k_fold = self.k_fold_split(training_data, k)
|
35 |
+
|
36 |
+
for fold in range(k):
|
37 |
+
validation_data = k_fold[fold]
|
38 |
+
train_data = [item for sublist in k_fold[:fold] + k_fold[fold + 1:] for item in sublist]
|
39 |
+
|
40 |
+
for mini_batch in [train_data[k:k+mini_batch_size] for k in range(0, len(train_data), mini_batch_size)]:
|
41 |
+
self.update_mini_batch(mini_batch, eta)
|
42 |
+
|
43 |
+
print(f"Epoch {j}, Fold {fold}: {self.evaluate(validation_data)}/{len(validation_data)}")
|
44 |
+
|
45 |
+
if test_data:
|
46 |
+
print(f"Epoch {j}: {self.evaluate(test_data)}/{n_test}")
|
47 |
+
|
48 |
+
def k_fold_split(self, data, k):
|
49 |
+
fold_size = len(data) // k
|
50 |
+
return [data[i*fold_size:(i+1)*fold_size] for i in range(k)]
|
51 |
+
|
52 |
+
def update_mini_batch(self, mini_batch, eta):
|
53 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
54 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
55 |
+
|
56 |
+
for x, y in mini_batch:
|
57 |
+
delta_nabla_b, delta_nabla_w = self.backdrop(x, y)
|
58 |
+
|
59 |
+
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
60 |
+
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
61 |
+
|
62 |
+
self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)]
|
63 |
+
self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)]
|
64 |
+
|
65 |
+
def evaluate(self, test_data):
|
66 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
67 |
+
return sum(int(x == y) for (x, y) in test_results)
|
68 |
+
|
69 |
+
def cost_derivative(self, output_activations, y):
|
70 |
+
return output_activations - y
|
71 |
+
|
72 |
+
def backdrop(self, x, y):
|
73 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
74 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
75 |
+
activation = x
|
76 |
+
activations = [x]
|
77 |
+
zs = []
|
78 |
+
|
79 |
+
for b, w in zip(self.biases, self.weights):
|
80 |
+
z = np.dot(w, activation)+b
|
81 |
+
zs.append(z)
|
82 |
+
activation = sigmoid(z)
|
83 |
+
activations.append(activation)
|
84 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
85 |
+
nabla_b[-1] = delta
|
86 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
87 |
+
|
88 |
+
for l in range(2, self.num_layers):
|
89 |
+
z = zs[-l]
|
90 |
+
sp = sigmoid_prime(z)
|
91 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
92 |
+
nabla_b[-l] = delta
|
93 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
94 |
+
return (nabla_b, nabla_w)
|
95 |
+
|
96 |
+
|
97 |
+
def sigmoid(z):
|
98 |
+
sig = np.zeros_like(z)
|
99 |
+
sig[z >= 0] = 1 / (1 + np.exp(-z[z >= 0]))
|
100 |
+
sig[z < 0] = np.exp(z[z < 0]) / (1 + np.exp(z[z < 0]))
|
101 |
+
return sig
|
102 |
+
|
103 |
+
def sigmoid_prime(z):
|
104 |
+
return sigmoid(z)*(1-sigmoid(z))
|
105 |
+
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
def load_data():
|
111 |
+
with gzip.open('C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\BP神经网络\\mnist.pkl.gz', 'rb') as f:
|
112 |
+
training_data, validation_data, test_data = pickle.load(f, encoding='latin1')
|
113 |
+
|
114 |
+
return (training_data, validation_data, test_data)
|
115 |
+
|
116 |
+
def load_data_wrapper():
|
117 |
+
tr_d, va_d, te_d = load_data()
|
118 |
+
training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
|
119 |
+
training_results = [vectorized_result(y) for y in tr_d[1]]
|
120 |
+
training_data = list(zip(training_inputs, training_results))
|
121 |
+
validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
|
122 |
+
validation_data = list(zip(validation_inputs, va_d[1]))
|
123 |
+
test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
|
124 |
+
test_results = [vectorized_result(y) for y in te_d[1]]
|
125 |
+
test_data = list(zip(test_inputs, test_results))
|
126 |
+
return (training_data, validation_data, test_data)
|
127 |
+
|
128 |
+
def vectorized_result(j):
|
129 |
+
e = np.zeros((10, 1))
|
130 |
+
e[j] = 1.0
|
131 |
+
return e
|
132 |
+
|
133 |
+
|
134 |
+
training_data, validation_data, test_data = load_data_wrapper()
|
135 |
+
net = Network([784, 41, 10])
|
136 |
+
|
137 |
+
net.SGD(training_data, 3, 8, 3.0, 5, test_data=test_data)
|
test0.py
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
def __init__(self, sizes):
|
7 |
+
self.num_layers = len(sizes)
|
8 |
+
self.sizes = sizes
|
9 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
10 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
11 |
+
|
12 |
+
def feedforward(self, a):
|
13 |
+
for b, w in zip(self.biases, self.weights):
|
14 |
+
a = sigmoid(np.dot(w, a) + b)
|
15 |
+
return a
|
16 |
+
|
17 |
+
def train(self, training_data, epochs, eta):
|
18 |
+
n = len(training_data)
|
19 |
+
for j in range(epochs):
|
20 |
+
np.random.shuffle(training_data)
|
21 |
+
for x, y in training_data:
|
22 |
+
self.update_network(x, y, eta)
|
23 |
+
# print(f"Epoch {j} complete") # 注释掉每个 epoch 完成后的打印
|
24 |
+
|
25 |
+
def update_network(self, x, y, eta):
|
26 |
+
nabla_b, nabla_w = self.backprop(x, y)
|
27 |
+
self.weights = [w - eta * nw for w, nw in zip(self.weights, nabla_w)]
|
28 |
+
self.biases = [b - eta * nb for b, nb in zip(self.biases, nabla_b)]
|
29 |
+
|
30 |
+
def evaluate(self, test_data):
|
31 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
32 |
+
return sum(int(x == y) for (x, y) in test_results)
|
33 |
+
|
34 |
+
def backprop(self, x, y):
|
35 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
36 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
37 |
+
activation = x
|
38 |
+
activations = [x]
|
39 |
+
zs = []
|
40 |
+
for b, w in zip(self.biases, self.weights):
|
41 |
+
z = np.dot(w, activation) + b
|
42 |
+
zs.append(z)
|
43 |
+
activation = sigmoid(z)
|
44 |
+
activations.append(activation)
|
45 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
46 |
+
nabla_b[-1] = delta
|
47 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
48 |
+
for l in range(2, self.num_layers):
|
49 |
+
z = zs[-l]
|
50 |
+
sp = sigmoid_prime(z)
|
51 |
+
delta = np.dot(self.weights[-l + 1].transpose(), delta) * sp
|
52 |
+
nabla_b[-l] = delta
|
53 |
+
nabla_w[-l] = np.dot(delta, activations[-l - 1].transpose())
|
54 |
+
return (nabla_b, nabla_w)
|
55 |
+
|
56 |
+
def cost_derivative(self, output_activations, y):
|
57 |
+
return (output_activations - y)
|
58 |
+
|
59 |
+
def sigmoid(z):
|
60 |
+
return 1.0 / (1.0 + np.exp(-z))
|
61 |
+
|
62 |
+
def sigmoid_prime(z):
|
63 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
64 |
+
|
65 |
+
def k_fold_cross_validation(dataset, k):
|
66 |
+
np.random.shuffle(dataset)
|
67 |
+
fold_size = len(dataset) // k
|
68 |
+
for i in range(k):
|
69 |
+
validation_data = dataset[i * fold_size:(i + 1) * fold_size]
|
70 |
+
training_data = dataset[:i * fold_size] + dataset[(i + 1) * fold_size:]
|
71 |
+
yield training_data, validation_data
|
72 |
+
|
73 |
+
def load_and_preprocess_data(file_path):
|
74 |
+
data = pd.read_excel(file_path, header=None)
|
75 |
+
features = data.iloc[:, :-1]
|
76 |
+
features = (features - features.mean()) / features.std()
|
77 |
+
labels = data.iloc[:, -1]
|
78 |
+
if labels.dtype == object or np.issubdtype(labels.dtype, np.integer):
|
79 |
+
unique_labels = labels.unique()
|
80 |
+
label_mapping = {label: idx for idx, label in enumerate(unique_labels)}
|
81 |
+
labels = labels.map(label_mapping)
|
82 |
+
label_vectors = np.zeros((labels.size, len(unique_labels)))
|
83 |
+
for i, label in enumerate(labels):
|
84 |
+
label_vectors[i, label] = 1
|
85 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features.to_numpy()], [np.reshape(y, (len(y), 1)) for y in label_vectors]))
|
86 |
+
return dataset
|
87 |
+
|
88 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
89 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
90 |
+
|
91 |
+
for file in files:
|
92 |
+
file_path = os.path.join(folder_path, file)
|
93 |
+
dataset = load_and_preprocess_data(file_path)
|
94 |
+
for iteration in range(10): # 外层循环,进行十次交叉验证
|
95 |
+
accuracies = [] # 存储当前次交叉验证的所有准确率
|
96 |
+
for i, (train_data, validation_data) in enumerate(k_fold_cross_validation(dataset, 10)):
|
97 |
+
input_size = len(train_data[0][0])
|
98 |
+
output_size = len(train_data[0][1])
|
99 |
+
net = Network([input_size, 30, output_size])
|
100 |
+
net.train(train_data, 30, 3.0) # 根据需要调整 epochs 和学习率
|
101 |
+
validation_accuracy = net.evaluate(validation_data)
|
102 |
+
accuracies.append(validation_accuracy / len(validation_data))
|
103 |
+
average_accuracy = (sum(accuracies) / len(accuracies)) * 100
|
104 |
+
print(f"\nIteration {iteration + 1} Training on file: {file}")
|
105 |
+
print(f"Average Validation Accuracy: {average_accuracy:.2f}%")
|
win.xls
ADDED
Binary file (41.5 kB). View file
|
|
zoo.xls
ADDED
Binary file (35.8 kB). View file
|
|
神经网络,有留出测试集.py
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
|
6 |
+
class Network(object):
|
7 |
+
def __init__(self, sizes):
|
8 |
+
self.num_layers = len(sizes)
|
9 |
+
self.sizes = sizes
|
10 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
11 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
12 |
+
|
13 |
+
def feedforward(self, a):
|
14 |
+
for b, w in zip(self.biases, self.weights):
|
15 |
+
a = sigmoid(np.dot(w, a) + b)
|
16 |
+
return a
|
17 |
+
|
18 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, k, file_name, test_data):
|
19 |
+
n = len(training_data)
|
20 |
+
for j in range(epochs):
|
21 |
+
np.random.shuffle(training_data)
|
22 |
+
folds = [training_data[i::k] for i in range(k)]
|
23 |
+
|
24 |
+
if j == 0:
|
25 |
+
print(f"\nTraining on file: {file_name}")
|
26 |
+
print(f"\nEpoch {j}:")
|
27 |
+
|
28 |
+
for i in range(k):
|
29 |
+
validation_data = folds[i]
|
30 |
+
train_data = [item for fold in folds if fold is not validation_data for item in fold]
|
31 |
+
|
32 |
+
for mini_batch in [train_data[m:m+mini_batch_size] for m in range(0, len(train_data), mini_batch_size)]:
|
33 |
+
self.update_mini_batch(mini_batch, eta)
|
34 |
+
|
35 |
+
print(f"Fold {i}: {self.evaluate(validation_data)}/{len(validation_data)}")
|
36 |
+
|
37 |
+
test_accuracy = self.evaluate(test_data)
|
38 |
+
print(f"Test Accuracy: {test_accuracy}/{len(test_data)}")
|
39 |
+
|
40 |
+
def update_mini_batch(self, mini_batch, eta):
|
41 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
42 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
43 |
+
for x, y in mini_batch:
|
44 |
+
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
|
45 |
+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
46 |
+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
47 |
+
self.weights = [w - (eta / len(mini_batch)) * nw for w, nw in zip(self.weights, nabla_w)]
|
48 |
+
self.biases = [b - (eta / len(mini_batch)) * nb for b, nb in zip(self.biases, nabla_b)]
|
49 |
+
|
50 |
+
|
51 |
+
def cost_derivative(self, output_activations, y):
|
52 |
+
return output_activations - y
|
53 |
+
|
54 |
+
|
55 |
+
def evaluate(self, test_data):
|
56 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
57 |
+
return sum(int(x == y) for (x, y) in test_results)
|
58 |
+
|
59 |
+
|
60 |
+
def backprop(self, x, y):
|
61 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
62 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
63 |
+
activation = x
|
64 |
+
activations = [x]
|
65 |
+
zs = []
|
66 |
+
|
67 |
+
for b, w in zip(self.biases, self.weights):
|
68 |
+
z = np.dot(w, activation)+b
|
69 |
+
zs.append(z)
|
70 |
+
activation = sigmoid(z)
|
71 |
+
activations.append(activation)
|
72 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
73 |
+
nabla_b[-1] = delta
|
74 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
75 |
+
|
76 |
+
for l in range(2, self.num_layers):
|
77 |
+
z = zs[-l]
|
78 |
+
sp = sigmoid_prime(z)
|
79 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
80 |
+
nabla_b[-l] = delta
|
81 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
82 |
+
return (nabla_b, nabla_w)
|
83 |
+
|
84 |
+
|
85 |
+
def sigmoid(z):
|
86 |
+
return 1.0 / (1.0 + np.exp(-z))
|
87 |
+
|
88 |
+
def sigmoid_prime(z):
|
89 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
90 |
+
|
91 |
+
|
92 |
+
def load_and_preprocess_data(file_path):
|
93 |
+
data = pd.read_excel(file_path, header=None)
|
94 |
+
data.iloc[:, :-1] = (data.iloc[:, :-1] - data.iloc[:, :-1].mean()) / data.iloc[:, :-1].std()
|
95 |
+
|
96 |
+
if data.iloc[:, -1].dtype == object or np.issubdtype(data.iloc[:, -1].dtype, np.integer):
|
97 |
+
label_mapping = {label: idx for idx, label in enumerate(np.unique(data.iloc[:, -1]))}
|
98 |
+
data.iloc[:, -1] = data.iloc[:, -1].map(label_mapping)
|
99 |
+
|
100 |
+
features = data.iloc[:, :-1].values
|
101 |
+
labels = data.iloc[:, -1].values
|
102 |
+
|
103 |
+
unique_labels = len(np.unique(labels))
|
104 |
+
labels = np.array([vectorized_result(label, unique_labels) for label in labels])
|
105 |
+
|
106 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features], labels))
|
107 |
+
|
108 |
+
|
109 |
+
split_index = int(len(dataset) * 0.9)
|
110 |
+
training_data = dataset[:split_index]
|
111 |
+
test_data = dataset[split_index:]
|
112 |
+
|
113 |
+
return training_data, test_data
|
114 |
+
|
115 |
+
|
116 |
+
def vectorized_result(j, size):
|
117 |
+
e = np.zeros((size, 1))
|
118 |
+
e[j] = 1.0
|
119 |
+
return e
|
120 |
+
|
121 |
+
|
122 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
123 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
124 |
+
|
125 |
+
for file in files:
|
126 |
+
file_path = os.path.join(folder_path, file)
|
127 |
+
training_data, test_data = load_and_preprocess_data(file_path)
|
128 |
+
|
129 |
+
input_size = len(training_data[0][0])
|
130 |
+
output_size = len(training_data[0][1])
|
131 |
+
|
132 |
+
net = Network([input_size, 30, output_size])
|
133 |
+
net.SGD(training_data, 5, 10, 3.0, 10, file, test_data)
|
神经网络,没有留出.py
ADDED
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
def __init__(self, sizes):
|
7 |
+
self.num_layers = len(sizes)
|
8 |
+
self.sizes = sizes
|
9 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
10 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
11 |
+
|
12 |
+
def feedforward(self, a):
|
13 |
+
for b, w in zip(self.biases, self.weights):
|
14 |
+
a = sigmoid(np.dot(w, a) + b)
|
15 |
+
return a
|
16 |
+
|
17 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, k, file_name):
|
18 |
+
n = len(training_data)
|
19 |
+
for j in range(epochs):
|
20 |
+
np.random.shuffle(training_data)
|
21 |
+
folds = [training_data[i::k] for i in range(k)]
|
22 |
+
|
23 |
+
print(f"\nTraining on file: {file_name}")
|
24 |
+
print(f"\nEpoch {j}:")
|
25 |
+
|
26 |
+
for i in range(k):
|
27 |
+
validation_data = folds[i]
|
28 |
+
train_data = [item for fold in folds if fold is not validation_data for item in fold]
|
29 |
+
|
30 |
+
for mini_batch in [train_data[m:m+mini_batch_size] for m in range(0, len(train_data), mini_batch_size)]:
|
31 |
+
self.update_mini_batch(mini_batch, eta)
|
32 |
+
|
33 |
+
print(f"Fold {i}: {self.evaluate(validation_data)}/{len(validation_data)}")
|
34 |
+
|
35 |
+
def update_mini_batch(self, mini_batch, eta):
|
36 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
37 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
38 |
+
for x, y in mini_batch:
|
39 |
+
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
|
40 |
+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
41 |
+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
42 |
+
self.weights = [w - (eta / len(mini_batch)) * nw for w, nw in zip(self.weights, nabla_w)]
|
43 |
+
self.biases = [b - (eta / len(mini_batch)) * nb for b, nb in zip(self.biases, nabla_b)]
|
44 |
+
|
45 |
+
|
46 |
+
def cost_derivative(self, output_activations, y):
|
47 |
+
return output_activations - y
|
48 |
+
|
49 |
+
|
50 |
+
def evaluate(self, test_data):
|
51 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
52 |
+
return sum(int(x == y) for (x, y) in test_results)
|
53 |
+
|
54 |
+
|
55 |
+
def backprop(self, x, y):
|
56 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
57 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
58 |
+
activation = x
|
59 |
+
activations = [x]
|
60 |
+
zs = []
|
61 |
+
|
62 |
+
for b, w in zip(self.biases, self.weights):
|
63 |
+
z = np.dot(w, activation)+b
|
64 |
+
zs.append(z)
|
65 |
+
activation = sigmoid(z)
|
66 |
+
activations.append(activation)
|
67 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
68 |
+
nabla_b[-1] = delta
|
69 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
70 |
+
|
71 |
+
for l in range(2, self.num_layers):
|
72 |
+
z = zs[-l]
|
73 |
+
sp = sigmoid_prime(z)
|
74 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
75 |
+
nabla_b[-l] = delta
|
76 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
77 |
+
return (nabla_b, nabla_w)
|
78 |
+
|
79 |
+
|
80 |
+
def sigmoid(z):
|
81 |
+
return 1.0 / (1.0 + np.exp(-z))
|
82 |
+
|
83 |
+
def sigmoid_prime(z):
|
84 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
85 |
+
|
86 |
+
|
87 |
+
def load_and_preprocess_data(file_path):
|
88 |
+
|
89 |
+
data = pd.read_excel(file_path, header=None)
|
90 |
+
|
91 |
+
|
92 |
+
features = data.iloc[:, :-1]
|
93 |
+
features = (features - features.mean()) / features.std()
|
94 |
+
|
95 |
+
|
96 |
+
labels = data.iloc[:, -1]
|
97 |
+
if labels.dtype == object or np.issubdtype(labels.dtype, np.integer):
|
98 |
+
unique_labels = labels.unique()
|
99 |
+
label_mapping = {label: idx for idx, label in enumerate(unique_labels)}
|
100 |
+
labels = labels.map(label_mapping)
|
101 |
+
|
102 |
+
|
103 |
+
label_vectors = np.zeros((labels.size, len(unique_labels)))
|
104 |
+
for i, label in enumerate(labels):
|
105 |
+
label_vectors[i, label] = 1
|
106 |
+
|
107 |
+
|
108 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features.to_numpy()], [np.reshape(y, (len(y), 1)) for y in label_vectors]))
|
109 |
+
|
110 |
+
return dataset
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
def vectorized_result(j, size):
|
115 |
+
e = np.zeros((size, 1))
|
116 |
+
e[j] = 1.0
|
117 |
+
return e
|
118 |
+
|
119 |
+
|
120 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
121 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
122 |
+
|
123 |
+
for file in files:
|
124 |
+
file_path = os.path.join(folder_path, file)
|
125 |
+
dataset = load_and_preprocess_data(file_path)
|
126 |
+
|
127 |
+
input_size = len(dataset[0][0])
|
128 |
+
output_size = len(dataset[0][1])
|
129 |
+
|
130 |
+
net = Network([input_size, 30, output_size])
|
131 |
+
net.SGD(dataset, 5, 10, 3.0, 5, file) # 这里我们只用dataset,不再分出test_data
|
神经网络,添加k折交叉验证.py
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import gzip
|
3 |
+
import pickle
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
class Network(object):
|
8 |
+
|
9 |
+
def __init__(self, sizes):
|
10 |
+
self.num_layers = len(sizes)
|
11 |
+
self.sizes = sizes
|
12 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
13 |
+
self.weights = [np.random.randn(y, x) for x,y in zip(sizes[:-1], sizes[1:])]
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
def feedforward(self, a):
|
22 |
+
|
23 |
+
for b, w in zip(self.biases, self.weights):
|
24 |
+
a = sigmoid(np.dot(w, a) + b)
|
25 |
+
|
26 |
+
return a
|
27 |
+
|
28 |
+
|
29 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, k, test_data=None):
|
30 |
+
if test_data:
|
31 |
+
n_test = len(test_data)
|
32 |
+
|
33 |
+
for j in range(epochs):
|
34 |
+
np.random.shuffle(training_data)
|
35 |
+
k_fold = self.k_fold_split(training_data, k)
|
36 |
+
|
37 |
+
for fold in range(k):
|
38 |
+
validation_data = k_fold[fold]
|
39 |
+
train_data = [item for sublist in k_fold[:fold] + k_fold[fold + 1:] for item in sublist]
|
40 |
+
|
41 |
+
for mini_batch in [train_data[k:k+mini_batch_size] for k in range(0, len(train_data), mini_batch_size)]:
|
42 |
+
self.update_mini_batch(mini_batch, eta)
|
43 |
+
|
44 |
+
print(f"Epoch {j}, Fold {fold}: {self.evaluate(validation_data)}/{len(validation_data)}")
|
45 |
+
|
46 |
+
if test_data:
|
47 |
+
print(f"Epoch {j}: {self.evaluate(test_data)}/{n_test}")
|
48 |
+
|
49 |
+
def k_fold_split(self, data, k):
|
50 |
+
fold_size = len(data) // k
|
51 |
+
return [data[i*fold_size:(i+1)*fold_size] for i in range(k)]
|
52 |
+
|
53 |
+
def update_mini_batch(self, mini_batch, eta):
|
54 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
55 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
56 |
+
|
57 |
+
for x, y in mini_batch:
|
58 |
+
delta_nabla_b, delta_nabla_w = self.backdrop(x, y)
|
59 |
+
|
60 |
+
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
61 |
+
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
62 |
+
|
63 |
+
self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)]
|
64 |
+
self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)]
|
65 |
+
|
66 |
+
def evaluate(self, test_data):
|
67 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
68 |
+
return sum(int(x == y) for (x, y) in test_results)
|
69 |
+
|
70 |
+
def cost_derivative(self, output_activations, y):
|
71 |
+
return output_activations - y
|
72 |
+
|
73 |
+
def backdrop(self, x, y):
|
74 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
75 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
76 |
+
activation = x
|
77 |
+
activations = [x]
|
78 |
+
zs = []
|
79 |
+
|
80 |
+
for b, w in zip(self.biases, self.weights):
|
81 |
+
z = np.dot(w, activation)+b
|
82 |
+
zs.append(z)
|
83 |
+
activation = sigmoid(z)
|
84 |
+
activations.append(activation)
|
85 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
86 |
+
nabla_b[-1] = delta
|
87 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
88 |
+
|
89 |
+
for l in range(2, self.num_layers):
|
90 |
+
z = zs[-l]
|
91 |
+
sp = sigmoid_prime(z)
|
92 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
93 |
+
nabla_b[-l] = delta
|
94 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
95 |
+
return (nabla_b, nabla_w)
|
96 |
+
|
97 |
+
|
98 |
+
def sigmoid(z):
|
99 |
+
sig = np.zeros_like(z)
|
100 |
+
sig[z >= 0] = 1 / (1 + np.exp(-z[z >= 0]))
|
101 |
+
sig[z < 0] = np.exp(z[z < 0]) / (1 + np.exp(z[z < 0]))
|
102 |
+
return sig
|
103 |
+
|
104 |
+
def sigmoid_prime(z):
|
105 |
+
return sigmoid(z)*(1-sigmoid(z))
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
def load_data():
|
112 |
+
with gzip.open('C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\BP神经网络\\mnist.pkl.gz', 'rb') as f:
|
113 |
+
training_data, validation_data, test_data = pickle.load(f, encoding='latin1')
|
114 |
+
|
115 |
+
return (training_data, validation_data, test_data)
|
116 |
+
|
117 |
+
def load_data_wrapper():
|
118 |
+
tr_d, va_d, te_d = load_data()
|
119 |
+
training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
|
120 |
+
training_results = [vectorized_result(y) for y in tr_d[1]]
|
121 |
+
training_data = list(zip(training_inputs, training_results))
|
122 |
+
validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
|
123 |
+
validation_data = list(zip(validation_inputs, va_d[1]))
|
124 |
+
test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
|
125 |
+
test_results = [vectorized_result(y) for y in te_d[1]]
|
126 |
+
test_data = list(zip(test_inputs, test_results))
|
127 |
+
return (training_data, validation_data, test_data)
|
128 |
+
|
129 |
+
def vectorized_result(j):
|
130 |
+
e = np.zeros((10, 1))
|
131 |
+
e[j] = 1.0
|
132 |
+
return e
|
133 |
+
|
134 |
+
|
135 |
+
training_data, validation_data, test_data = load_data_wrapper()
|
136 |
+
net = Network([784, 41, 10])
|
137 |
+
|
138 |
+
net.SGD(training_data, 3, 8, 3.0, 5, test_data=test_data)
|
移除小批量之后的算法.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import gzip
|
3 |
+
import pickle
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
|
7 |
+
def __init__(self, sizes):
|
8 |
+
self.num_layers = len(sizes)
|
9 |
+
self.sizes = sizes
|
10 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
11 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
12 |
+
|
13 |
+
def feedforward(self, a):
|
14 |
+
for b, w in zip(self.biases, self.weights):
|
15 |
+
a = sigmoid(np.dot(w, a) + b)
|
16 |
+
return a
|
17 |
+
|
18 |
+
def SGD(self, training_data, epochs, eta, k, test_data=None):
|
19 |
+
if test_data:
|
20 |
+
n_test = len(test_data)
|
21 |
+
n = len(training_data)
|
22 |
+
|
23 |
+
for j in range(epochs):
|
24 |
+
np.random.shuffle(training_data)
|
25 |
+
k_fold = self.k_fold_split(training_data, k)
|
26 |
+
|
27 |
+
for fold in range(k):
|
28 |
+
train_data = [item for sublist in k_fold[:fold] + k_fold[fold + 1:] for item in sublist]
|
29 |
+
self.update_mini_batch(train_data, eta)
|
30 |
+
|
31 |
+
print(f"Epoch {j}, Fold {fold}: {self.evaluate(k_fold[fold])}/{len(k_fold[fold])}")
|
32 |
+
|
33 |
+
if test_data:
|
34 |
+
print(f"Epoch {j}: {self.evaluate(test_data)}/{n_test}")
|
35 |
+
|
36 |
+
def k_fold_split(self, data, k):
|
37 |
+
fold_size = len(data) // k
|
38 |
+
return [data[i * fold_size:(i + 1) * fold_size] for i in range(k)]
|
39 |
+
|
40 |
+
def update_mini_batch(self, mini_batch, eta):
|
41 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
42 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
43 |
+
|
44 |
+
for x, y in mini_batch:
|
45 |
+
delta_nabla_b, delta_nabla_w = self.backdrop(x, y)
|
46 |
+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
47 |
+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
48 |
+
|
49 |
+
self.weights = [w - (eta / len(mini_batch)) * nw for w, nw in zip(self.weights, nabla_w)]
|
50 |
+
self.biases = [b - (eta / len(mini_batch)) * nb for b, nb in zip(self.biases, nabla_b)]
|
51 |
+
|
52 |
+
def evaluate(self, test_data):
|
53 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
54 |
+
return sum(int(x == y) for (x, y) in test_results)
|
55 |
+
|
56 |
+
def cost_derivative(self, output_activations, y):
|
57 |
+
return output_activations - y
|
58 |
+
|
59 |
+
def backdrop(self, x, y):
|
60 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
61 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
62 |
+
activation = x
|
63 |
+
activations = [x]
|
64 |
+
zs = []
|
65 |
+
|
66 |
+
for b, w in zip(self.biases, self.weights):
|
67 |
+
z = np.dot(w, activation) + b
|
68 |
+
zs.append(z)
|
69 |
+
activation = sigmoid(z)
|
70 |
+
activations.append(activation)
|
71 |
+
|
72 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
73 |
+
nabla_b[-1] = delta
|
74 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
75 |
+
|
76 |
+
for l in range(2, self.num_layers):
|
77 |
+
z = zs[-l]
|
78 |
+
sp = sigmoid_prime(z)
|
79 |
+
delta = np.dot(self.weights[-l + 1].transpose(), delta) * sp
|
80 |
+
nabla_b[-l] = delta
|
81 |
+
nabla_w[-l] = np.dot(delta, activations[-l - 1].transpose())
|
82 |
+
|
83 |
+
return (nabla_b, nabla_w)
|
84 |
+
|
85 |
+
def sigmoid(z):
|
86 |
+
return 1.0 / (1.0 + np.exp(-z))
|
87 |
+
|
88 |
+
def sigmoid_prime(z):
|
89 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
90 |
+
|
91 |
+
def load_data():
|
92 |
+
with gzip.open('C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\BP神经网络\\mnist.pkl.gz', 'rb') as f:
|
93 |
+
training_data, validation_data, test_data = pickle.load(f, encoding='latin1')
|
94 |
+
return (training_data, validation_data, test_data)
|
95 |
+
|
96 |
+
def load_data_wrapper():
|
97 |
+
tr_d, va_d, te_d = load_data()
|
98 |
+
training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
|
99 |
+
training_results = [vectorized_result(y) for y in tr_d[1]]
|
100 |
+
training_data = list(zip(training_inputs, training_results))
|
101 |
+
validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
|
102 |
+
validation_data = list(zip(validation_inputs, va_d[1]))
|
103 |
+
test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
|
104 |
+
test_data = list(zip(test_inputs, te_d[1]))
|
105 |
+
return (training_data, validation_data, test_data)
|
106 |
+
|
107 |
+
def vectorized_result(j):
|
108 |
+
e = np.zeros((10, 1))
|
109 |
+
e[j] = 1.0
|
110 |
+
return e
|
111 |
+
|
112 |
+
training_data, validation_data, test_data = load_data_wrapper()
|
113 |
+
net = Network([784, 41, 10])
|
114 |
+
net.SGD(training_data, 10, 3.0, 5, test_data=test_data)
|
网络,k折,无测集,小批量梯度下降优化算法.py
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
import os
|
4 |
+
|
5 |
+
class Network(object):
|
6 |
+
def __init__(self, sizes):
|
7 |
+
self.num_layers = len(sizes)
|
8 |
+
self.sizes = sizes
|
9 |
+
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
|
10 |
+
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
|
11 |
+
|
12 |
+
def feedforward(self, a):
|
13 |
+
for b, w in zip(self.biases, self.weights):
|
14 |
+
a = sigmoid(np.dot(w, a) + b)
|
15 |
+
return a
|
16 |
+
|
17 |
+
def SGD(self, training_data, epochs, mini_batch_size, eta, file_name):
|
18 |
+
n = len(training_data)
|
19 |
+
for j in range(epochs):
|
20 |
+
np.random.shuffle(training_data)
|
21 |
+
mini_batches = [training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)]
|
22 |
+
for mini_batch in mini_batches:
|
23 |
+
self.update_mini_batch(mini_batch, eta)
|
24 |
+
print(f"Epoch {j} complete")
|
25 |
+
|
26 |
+
def update_mini_batch(self, mini_batch, eta):
|
27 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
28 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
29 |
+
for x, y in mini_batch:
|
30 |
+
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
|
31 |
+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
|
32 |
+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
|
33 |
+
self.weights = [w - (eta / len(mini_batch)) * nw for w, nw in zip(self.weights, nabla_w)]
|
34 |
+
self.biases = [b - (eta / len(mini_batch)) * nb for b, nb in zip(self.biases, nabla_b)]
|
35 |
+
|
36 |
+
|
37 |
+
def cost_derivative(self, output_activations, y):
|
38 |
+
return output_activations - y
|
39 |
+
|
40 |
+
|
41 |
+
def evaluate(self, test_data):
|
42 |
+
test_results = [(np.argmax(self.feedforward(x)), np.argmax(y)) for (x, y) in test_data]
|
43 |
+
return sum(int(x == y) for (x, y) in test_results)
|
44 |
+
|
45 |
+
|
46 |
+
def backprop(self, x, y):
|
47 |
+
nabla_b = [np.zeros(b.shape) for b in self.biases]
|
48 |
+
nabla_w = [np.zeros(w.shape) for w in self.weights]
|
49 |
+
activation = x
|
50 |
+
activations = [x]
|
51 |
+
zs = []
|
52 |
+
|
53 |
+
for b, w in zip(self.biases, self.weights):
|
54 |
+
z = np.dot(w, activation)+b
|
55 |
+
zs.append(z)
|
56 |
+
activation = sigmoid(z)
|
57 |
+
activations.append(activation)
|
58 |
+
delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1])
|
59 |
+
nabla_b[-1] = delta
|
60 |
+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
|
61 |
+
|
62 |
+
for l in range(2, self.num_layers):
|
63 |
+
z = zs[-l]
|
64 |
+
sp = sigmoid_prime(z)
|
65 |
+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
|
66 |
+
nabla_b[-l] = delta
|
67 |
+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
|
68 |
+
return (nabla_b, nabla_w)
|
69 |
+
|
70 |
+
def sigmoid(z):
|
71 |
+
return 1.0 / (1.0 + np.exp(-z))
|
72 |
+
|
73 |
+
def sigmoid_prime(z):
|
74 |
+
return sigmoid(z) * (1 - sigmoid(z))
|
75 |
+
|
76 |
+
def k_fold_cross_validation(dataset, k):
|
77 |
+
fold_size = len(dataset) // k
|
78 |
+
for i in range(k):
|
79 |
+
validation_data = dataset[i*fold_size:(i+1)*fold_size]
|
80 |
+
training_data = dataset[:i*fold_size] + dataset[(i+1)*fold_size:]
|
81 |
+
yield training_data, validation_data
|
82 |
+
|
83 |
+
def load_and_preprocess_data(file_path):
|
84 |
+
|
85 |
+
data = pd.read_excel(file_path, header=None)
|
86 |
+
|
87 |
+
|
88 |
+
features = data.iloc[:, :-1]
|
89 |
+
features = (features - features.mean()) / features.std()
|
90 |
+
|
91 |
+
|
92 |
+
labels = data.iloc[:, -1]
|
93 |
+
if labels.dtype == object or np.issubdtype(labels.dtype, np.integer):
|
94 |
+
unique_labels = labels.unique()
|
95 |
+
label_mapping = {label: idx for idx, label in enumerate(unique_labels)}
|
96 |
+
labels = labels.map(label_mapping)
|
97 |
+
|
98 |
+
|
99 |
+
label_vectors = np.zeros((labels.size, len(unique_labels)))
|
100 |
+
for i, label in enumerate(labels):
|
101 |
+
label_vectors[i, label] = 1
|
102 |
+
|
103 |
+
|
104 |
+
dataset = list(zip([np.reshape(x, (len(x), 1)) for x in features.to_numpy()], [np.reshape(y, (len(y), 1)) for y in label_vectors]))
|
105 |
+
|
106 |
+
return dataset
|
107 |
+
|
108 |
+
def vectorized_result(j, size):
|
109 |
+
e = np.zeros((size, 1))
|
110 |
+
e[j] = 1.0
|
111 |
+
return e
|
112 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
113 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
114 |
+
|
115 |
+
for file in files:
|
116 |
+
file_path = os.path.join(folder_path, file)
|
117 |
+
dataset = load_and_preprocess_data(file_path)
|
118 |
+
|
119 |
+
for i, (train_data, validation_data) in enumerate(k_fold_cross_validation(dataset, 10)):
|
120 |
+
input_size = len(train_data[0][0])
|
121 |
+
output_size = len(train_data[0][1])
|
122 |
+
|
123 |
+
net = Network([input_size, 30, output_size])
|
124 |
+
print(f"\nTraining on file: {file}, Fold: {i+1}")
|
125 |
+
net.SGD(train_data, 5, 10, 3.0, file)
|
126 |
+
validation_accuracy = net.evaluate(validation_data)
|
127 |
+
print(f"Validation Accuracy: {validation_accuracy}/{len(validation_data)}")
|
调包版.py
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
from sklearn.preprocessing import StandardScaler
|
4 |
+
from sklearn.model_selection import KFold, cross_val_score
|
5 |
+
from sklearn.neural_network import MLPClassifier
|
6 |
+
import os
|
7 |
+
|
8 |
+
def load_and_preprocess_data(file_path):
|
9 |
+
data = pd.read_excel(file_path, header=None)
|
10 |
+
features = data.iloc[:, :-1]
|
11 |
+
labels = data.iloc[:, -1]
|
12 |
+
|
13 |
+
if labels.dtype == object or np.issubdtype(labels.dtype, np.integer):
|
14 |
+
labels, unique_labels = pd.factorize(labels)
|
15 |
+
|
16 |
+
scaler = StandardScaler()
|
17 |
+
features_scaled = scaler.fit_transform(features)
|
18 |
+
|
19 |
+
return features_scaled, labels
|
20 |
+
|
21 |
+
folder_path = 'C:\\Users\\tt235\\Desktop\\Code\\code\\代码复现\\算法学习测试数据集'
|
22 |
+
files = [f for f in os.listdir(folder_path) if f.endswith('.xls')]
|
23 |
+
|
24 |
+
for file in files:
|
25 |
+
file_path = os.path.join(folder_path, file)
|
26 |
+
features_scaled, labels = load_and_preprocess_data(file_path)
|
27 |
+
mlp = MLPClassifier(hidden_layer_sizes=(30,), max_iter=10000,learning_rate_init=0.1)
|
28 |
+
|
29 |
+
for i in range(10):
|
30 |
+
kf = KFold(n_splits=10, shuffle=True, random_state=i)
|
31 |
+
scores = cross_val_score(mlp, features_scaled, labels, cv=kf)
|
32 |
+
average_accuracy = scores.mean() * 100
|
33 |
+
print(f"\nIteration {i + 1} Training on file: {file}")
|
34 |
+
print(f"Average Validation Accuracy: {average_accuracy:.2f}%")
|