用三层BP神经网络解决字母T和L的识别问题。如图所示,每个字母用3x3的二维二值图表示,令黑方格为1,白方格为0,每个字母有4个样本,包括字母正常位置及旋转90,180和270°的图像。希望输入不同的位置下的T时,网络输出为1,而输入不同位置的L时,网络输出为0。用BP算法求出权系数和阈值。建议:选择网络结构为9-3-1。隐单元非线性函数为,输出单元非线性函为。
1. 数据处理
本次实验数据为上面的字母样本图,每个字母有4个样本,包括字母正常位置及旋转90°,180°和270°的图像。我们令黑方格为1,白方格为0,且按照下图1到9的顺序进行记录,得到数据集矩阵(一列代表一个样本,共八列)。并根据输入不同的位置下的T时,网络输出为1,而输入不同位置的L时,网络输出为0来记录数据标签(八列,每列代表对应样本的输出)。
2. 模型搭建
如下图所示为三层BP神经网络架构,其中第一层到第二层之间权值参数为(大小为3×9)和(大小为3×1),激活函数为,第二层到第三层之间权值参数为(大小为1×3)和(大小为1×1),激活函数为。
3. 编程实现
使用keras框架实现上述模型得训练:
# -*- coding: utf-8 -*-
"""
Author: Angus Cai
Date: 2019-4-19
"""
from keras.layers import Activation, Dense
from keras.models import Sequential
from keras.utils.generic_utils import get_custom_objects
from keras import backend as K
import numpy as np
X = [[1,1,1,0,1,0,0,1,0],
[1,0,0,1,1,1,1,0,0],
[0,1,0,0,1,0,1,1,1],
[0,0,1,1,1,1,0,0,1],
[1,0,0,1,0,0,1,1,1],
[0,0,1,0,0,1,1,1,1],
[1,1,1,0,0,1,0,0,1],
[1,1,1,1,0,0,1,0,0]]
Y = [0,0,0,0,1,1,1,1]
X_train = np.array(X)
Y_train = np.array(Y)
# 隐藏层非线性激活函数
def hidden_activation(X):
return 2 * K.sigmoid(X) - 1
# 输出层非线性激活函数
def output_activation(X):
return K.sigmoid(X)
## custom activation function
get_custom_objects().update({'hidden_activation': Activation(hidden_activation)})
get_custom_objects().update({'output_activation': Activation(output_activation)})
model = Sequential()
model.add(Dense(3, input_dim=9))
model.add(Activation(hidden_activation))
model.add(Dense(1))
model.add(Activation(output_activation))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=250,batch_size=2)
score = model.evaluate(X_train, Y_train, batch_size=2)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
model.save('tl_problem.h5')
训练结果如下:
可以看到,设置训练轮数(epoches)为250,可以使得模型得准确率达到100%。
4. 实验结果
模型测试代码如下:
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 18 16:28:57 2019
@author: angus
"""
from keras.models import load_model
from keras.utils.generic_utils import get_custom_objects
from keras.layers import Activation
from keras import backend as K
import numpy as np
# 隐藏层非线性激活函数
def hidden_activation(X):
return 2 * K.sigmoid(X) - 1
# 输出层非线性激活函数
def output_activation(X):
return K.sigmoid(X)
get_custom_objects().update({'hidden_activation': Activation(hidden_activation)})
get_custom_objects().update({'output_activation': Activation(output_activation)})
model = load_model('tl_problem.h5')
print(model.summary())
weights = []
for layer in model.layers:
weights.append(layer.get_weights())
print("The weight matrix of input_layer to hidden_layer: ")
print(weights[0][0])
print("--------------------------------------------------------")
print("The bias of the hidden layer:")
print(weights[0][1].tolist())
print("--------------------------------------------------------")
print("The weight matrix of hidden_layer to output_layer: ")
print(weights[2][0].tolist())
print("--------------------------------------------------------")
print("The bias of the output layer:")
print(weights[2][1].tolist())
测试结果如下:
打印出了模型得结构、参数个数以及最终训练好得权值系数与阈值。
5. 实验总结
该实验通过搭建三层BP神经网络,通过数据预处理,模型搭建以及训练识别三大模块解决字母T和L的识别问题。最后用这八个样本去检验识别结果,与其标签进行比较,得到100%的识别率。