1 BP公式的推导
- 神经网络的模型
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d1a05312a8cb61b42ccdc2d97c85545a.png)
1.1 激活函数
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/04921bc0b1d3dcb8848237cb2e26dc48.png)
1.1.1 Sigmod
函数导数
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/66fd8facc4f2dd68fae37eed5d72010f.png)
- 注意:Sigmod函数与矩阵相乘的时候是对应位置相乘,对应于
numpy.mutiply()
1.2 损失函数
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/22c750d420fef74114ab47dbbb1209ab.png)
1.3 前向传播
- N为神经网络的输出
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c501657ccb40653f338b90caa7192f6d.png)
1.3 计算误差反向传播
- 矩阵求导时,系数矩阵为导数时,要对其进行求逆
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/258a458499b2be911a925f800b72afea.png)
1.3.1 误差为方差时,输出层误差的计算
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/aeaedd200030ac8c5446f2626ffe7743.png)
1.3.2 误差为方差时,隐层层误差的计算
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/030cc6403bbd35cd07daab404c36d2d2.png)
1.4 调整参数
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f1edb6714d937f2021af31544e698c8b.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d644dbd61777c4fae779fecdebf9447f.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0ff2017c35e70d40e242839f768e7583.png)
2 神经网络设计
import numpy as np
class neuron():
def __init__(self, input_len, output_len, is_output_layer, learning_rate):
self.RANDOM_INT = 10
self.is_output_layer = is_output_layer
self.w = np.random.randint(-self.RANDOM_INT, self.RANDOM_INT, (input_len, output_len)).astype(np.float64) / 10
self.b = np.random.randint(-self.RANDOM_INT, self.RANDOM_INT, (1, output_len)).astype(np.float64) / 10
self.output = 0
self.error = 0
self.learning_rate = learning_rate
self.input_data = 0
def active_function(self, input_z):
return 1 / (1 + np.exp(-input_z))
def forward_propagation(self, input_data):
self.input_data = input_data
self.output = self.active_function(np.dot(self.input_data, self.w).astype(np.float64) - self.b)
return self.output
def get_output(self, input_data):
return self.active_function(np.dot(input_data, self.w).astype(np.float64) - self.b)
pass
def back_propagation(self, error, next_w):
if self.is_output_layer:
self.error = np.multiply((error - self.output), np.multiply(self.output, 1 - self.output))
return self.error
else:
self.error = np.multiply(np.multiply(self.output, 1 - self.output), np.dot(error, np.transpose(next_w)))
return self.error
pass
def adjust_param(self, error):
delta_w = np.dot(np.transpose(self.input_data), error)
delta_b = error
self.w = self.w + self.learning_rate * delta_w
self.b = self.b - self.learning_rate * delta_b
pass
3 使用OpenCV 分割图片
3.1 整张图片资源
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d5ee540d8728850fbb2c39515194fb43.png)
import cv2
import os
def cut_image(src_image, dst_src, row_size, col_size):
img_1 = cv2.imread(src_image)
img = cv2.cvtColor(img_1, cv2.COLOR_BGR2GRAY)
row_num = img.shape[0] // row_size
col_num = img.shape[1] // col_size
print(row_num, col_num)
file_name = 0
file_count = 0
for i in range(row_num):
offset_row = i * row_size
if i % 5 == 0 and i != 0:
file_name += 1
file_count = 0
path = dst_src + "\\" + str(file_name)
if not os.path.exists(path):
os.makedirs(path)
for j in range(col_num):
offset_col = j * col_size
filepath = path + "\\" + str(file_count) + ".jpg"
file_count += 1
im = img[offset_row:offset_row + row_size - 1, offset_col:offset_col + col_size - 1]
'''
function: cv2.imwrite('F:/images',image,[int(cv2.IMWRITE_JPEG_QUALITY),5])
- 三个参数分别对应保存的路径及文件名、图像矩阵、指定格式
- (对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。
- 注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int;对于PNG,第三个参数表示的是压缩级别。
- cv2.IMWRITE_PNG_COMPRESSION,
- 从0到9,压缩级别越高,图像尺寸越小。这个是可选参数)
'''
cv2.imwrite(filepath, im, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
if __name__ == '__main__':
cut_image("test.png", "images_data", 20, 20)
pass
3.2 Mnist数据集
import cv2
import os
def cut_image(image_src, row_size, column_size, output_src):
image = cv2.imread(image_src)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
row_num = image.shape[0] // row_size
col_num = image.shape[1] // column_size
print("图像的行数为: ", row_num, "图像的列数为: ", col_num)
file_num = 0
for i in range(row_num):
offset_row = i * row_size
path = output_src
if not os.path.exists(path):
os.makedirs(path)
for j in range(col_num):
offset_col = j * column_size
file_path = path + "\\" + str(file_num) + ".jpg"
file_num += 1
'''
按照像素的位置取出图像
'''
im = image[offset_row: offset_row + row_size - 1, offset_col: offset_col + column_size - 1]
'''
function: cv2.imwrite(F:/images',image,[int(cv2.IMWRITE_JPEG_QUALITY),5])
- 三个参数分别对应保存的路径及文件名、图像矩阵、指定格式
- (对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。
- 注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int;对于PNG,第三个参数表示的是压缩级别。
- cv2.IMWRITE_PNG_COMPRESSION,
- 从0到9,压缩级别越高,图像尺寸越小。这个是可选参数)
'''
cv2.imwrite(file_path, im, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
if __name__ == '__main__':
cut_image("mnist_test0.jpg", 28, 28, "images/images_test0")
cut_image("mnist_test1.jpg", 28, 28, "images/images_test1")
cut_image("mnist_test2.jpg", 28, 28, "images/images_test2")
cut_image("mnist_test3.jpg", 28, 28, "images/images_test3")
cut_image("mnist_test4.jpg", 28, 28, "images/images_test4")
cut_image("mnist_test5.jpg", 28, 28, "images/images_test5")
cut_image("mnist_test6.jpg", 28, 28, "images/images_test6")
cut_image("mnist_test7.jpg", 28, 28, "images/images_test7")
cut_image("mnist_test8.jpg", 28, 28, "images/images_test8")
cut_image("mnist_test9.jpg", 28, 28, "images/images_test9")
4 进行训练
4.1 读取图片数据,并归一化
- 训练采用灰度图片,读取图片的数据,转化为灰度数据,放入到神经网络中
- 根据图片所在文件夹的顺序,对图片添加分类
def select_label(count):
label = []
for i in range(10):
if i == count:
label.append(1)
else:
label.append(0)
return label
pass
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0b1e993c366dbf250eca1cd38b1e0205.png)
import cv2
def select_label(count):
label = []
for i in range(10):
if i == count:
label.append(1)
else:
label.append(0)
return label
pass
def get_array_image(file, count, num):
url = file + "/images_train" + str(count) + "/" + str(num) + ".jpg"
src_image = cv2.imread(url)
new_image = cv2.resize(src_image, (30, 30))
gray_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)
data_list = []
for i in range(len(gray_image)):
data_list.extend(gray_image[i] / 255)
label_list = select_label(count)
return data_list, label_list
pass
def get_data_label(file_name, file_num, num_start, num_end):
data_set = []
label_set = []
for i in range(file_num):
for j in range(num_start, num_end):
data_row, label_row = get_array_image(file_name, i, j)
data_set.append(data_row)
label_set.append(label_row)
return data_set, label_set
pass
if __name__ == '__main__':
data_row, label_row = get_array_image("train_set_images_cut/train_images/images", 0, 0)
print(data_row)
pass
5.2 对神经网络进行训练,训练好的参数放入Excel文件中
import numpy as np
from neuron import neuron
import data_util
import excel_util
import data_util2
def sigmoid(value):
return 1 / (1 + np.exp(-value))
pass
def get_e(data_test, label, neurons):
data_set_len = len(data_test)
tmp = 0
for i in range(data_set_len):
output = np.mat(data_test[i]).astype(np.float64)
for neuron_item in neurons:
output = neuron_item.get_output(output)
tmp += np.multiply((output - label[i]), (output - label[i]).T)
return tmp / data_set_len
pass
def predict_test(data_test, label_test, neurons):
right_cnt = 0
test_set_len = len(data_test)
for i in range(test_set_len):
output = np.mat(data_test[i]).astype(np.float64)
for neuron_item in neurons:
output = neuron_item.get_output(output)
predict_class = 1000
for row in range(output.shape[0]):
for col in range(output.shape[1]):
if output[row, col] >= 0.5:
predict_class = col
break
label_class = 1000
for index in range(len(label_test[i])):
if label_test[i][index] == 1:
label_class = index
break
print("第", i + 1, "次预测:predict: ", output, ", \n真实: ", label_test[i])
print("第", i + 1, "次预测:predict: ", predict_class, ", \n真实: ", label_class)
if predict_class == label_class != 1000:
right_cnt += 1
return right_cnt / test_set_len
def plot_e(a_list):
import matplotlib.pyplot as plt
x = np.arange(1, len(a_list) + 1)
y = np.array(a_list)
print("最后误差:", y[-1])
plt.plot(x, y)
plt.xlabel("practiseTime")
plt.ylabel("variance")
plt.show()
pass
def main():
file_num = 10
train_num_start = 0
train_num_end = 300
data_set, label_set = data_util2.get_data_label("train_set_images_cut/train_images/images", file_num, train_num_start, train_num_end)
input_len = len(data_set[0])
hidden_one_len = 50
output_len = len(label_set[0])
hidden_one_layer = neuron(input_len, hidden_one_len, False, 0.01)
output_layer = neuron(hidden_one_len, output_len, True, 0.01)
a_list = []
for num in range(150):
for j in range(len(data_set)):
hidden_one_output = hidden_one_layer.forward_propagation(np.mat(data_set[j]).astype(np.float64))
output_one_later = output_layer.forward_propagation(hidden_one_output)
error_2 = output_layer.back_propagation(label_set[j], 1)
error_1 = hidden_one_layer.back_propagation(error_2, output_layer.w)
output_layer.adjust_param(error_2)
hidden_one_layer.adjust_param(error_1)
e = get_e(data_set, label_set, [hidden_one_layer, output_layer])
e_value = 0
for row in range(len(e)):
for col in range(len(e[0])):
e_value = e_value + e[row, col]
a_list.append(abs(e_value))
excel_util.save_matrix2excel(hidden_one_layer.w, "excel_param/hidden_one_layer_w1.xlsx")
excel_util.save_matrix2excel(hidden_one_layer.b, "excel_param/hidden_one_layer_b1.xlsx")
excel_util.save_matrix2excel(output_layer.w, "excel_param/output_layer_w1.xlsx")
excel_util.save_matrix2excel(output_layer.b, "excel_param/output_layer_b1.xlsx")
plot_e(a_list)
test_num_start = 100
test_num_end = 120
data_set_test, label_set_test = data_util2.get_data_label("train_set_images_cut/train_images/images", file_num, test_num_start, test_num_end)
rate = predict_test(data_set_test, label_set_test, [hidden_one_layer, output_layer])
print("预测的正确率为: ", rate * 100, "%")
pass
if __name__ == '__main__':
main()
6 进行预测
6.1 存取excel工具
import pandas as pd
import numpy as np
def save_matrix2excel(mat, dst_path):
data = pd.DataFrame(mat)
data.to_excel(dst_path)
pass
def read_excel2matrix(url):
sheet = pd.read_excel(url)
return np.mat(sheet)[:, 1:]
pass
if __name__ == '__main__':
data = read_excel2matrix("test.xlsx")
print(data)
pass
6.2 读取参数后进行预测
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/519ebd96774d6573cdb20c7a132eb876.png)
import cv2
def select_label(count):
label = []
for i in range(10):
if i == count:
label.append(1)
else:
label.append(0)
return label
pass
def get_array_image(file, count, num, row_size, col_size):
url = file + "/images_test" + str(count) + "/" + str(num) + ".jpg"
src_image = cv2.imread(url)
new_image = cv2.resize(src_image, (row_size, col_size))
gray_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2GRAY)
data_list = []
for i in range(len(gray_image)):
data_list.extend(gray_image[i])
label_list = select_label(count)
return data_list, label_list
pass
def get_data_label(file_name, file_num, num_start, num_end, row_size, col_size):
data_set = []
label_set = []
for i in range(file_num):
for j in range(num_start, num_end):
data_row, label_row = get_array_image(file_name, i, j, row_size, col_size)
data_set.append(data_row)
label_set.append(label_row)
return data_set, label_set
pass
if __name__ == '__main__':
data_row, label_row = get_array_image("images", 0, 0)
print(data_row)
pass
from neuron import neuron
import numpy as np
import excel_util
import data_util
def predict_test(data_test, label_test, neurons):
right_cnt = 0
test_set_len = len(data_test)
for i in range(test_set_len):
output = np.mat(data_test[i]).astype(np.float64)
for neuron_item in neurons:
output = neuron_item.get_output(output)
predict_class = 1000
for row in range(output.shape[0]):
for col in range(output.shape[1]):
if output[row, col] >= 0.5:
predict_class = col
break
label_class = 1000
for index in range(len(label_test[i])):
if label_test[i][index] == 1:
label_class = index
break
print("第", i + 1, "次预测:predict: ", output, ", \n真实: ", label_test[i])
print("第", i + 1, "次预测:predict: ", predict_class, ", \n真实: ", label_class)
if predict_class == label_class != 1000:
right_cnt += 1
return right_cnt / test_set_len
def main():
hidden_one_layer_w = excel_util.read_excel2matrix("excel_param/hidden_one_layer_w.xlsx")
hidden_one_layer_b = excel_util.read_excel2matrix("excel_param/hidden_one_layer_b.xlsx")
output_layer_w = excel_util.read_excel2matrix("excel_param/output_layer_w.xlsx")
output_layer_b = excel_util.read_excel2matrix("excel_param/output_layer_b.xlsx")
print(hidden_one_layer_w.shape)
print(hidden_one_layer_b.shape)
print(output_layer_w.shape)
print(output_layer_b.shape)
hidden_one_layer = neuron(hidden_one_layer_w.shape[0], hidden_one_layer_w.shape[1], False, 0.01)
output_layer = neuron(hidden_one_layer_w.shape[1], output_layer_w.shape[1], True, 0.01)
hidden_one_layer.w = hidden_one_layer_w
hidden_one_layer.b = hidden_one_layer_b
output_layer.w = output_layer_w
output_layer.b = output_layer_b
file_num = 10
test_num_start = 0
test_num_end = 200
data_set_test, label_set_test = data_util.get_data_label("predict_images", file_num, test_num_start, test_num_end, 30, 30)
rate = predict_test(data_set_test, label_set_test, [hidden_one_layer, output_layer])
print("预测的正确率为: ", rate * 100, "%")
pass
if __name__ == '__main__':
main()
pass
6.3 误差
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/09a814daca7969fb2510a8d18dcb63e0.png)
6.4 预测结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8300303573b48d7036da74241d0fba1a.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9be515928b56994966458ba1e0480f3b.png)