​ 用三层BP神经网络解决字母T和L的识别问题。如图所示,每个字母用3x3的二维二值图表示,令黑方格为1,白方格为0,每个字母有4个样本,包括字母正常位置及旋转90,180和270°的图像。希望输入不同的位置下的T时,网络输出为1,而输入不同位置的L时,网络输出为0。用BP算法求出权系数和阈值。建议:选择网络结构为9-3-1。隐单元非线性函数为f(x)=21+eax1f(x)=\frac{2}{1+e^{-ax}}-1​,输出单元非线性函为f(x)=11+eaxf(x)=\dfrac{1}{1+e^{-ax}}​

1. 数据处理

本次实验数据为上面的字母样本图,每个字母有4个样本,包括字母正常位置及旋转90°,180°和270°的图像。我们令黑方格为1,白方格为0,且按照下图1到9的顺序进行记录,得到数据集矩阵(一列代表一个样本,共八列)。并根据输入不同的位置下的T时,网络输出为1,而输入不同位置的L时,网络输出为0来记录数据标签(八列,每列代表对应样本的输出)。

2. 模型搭建

如下图所示为三层BP神经网络架构,其中第一层到第二层之间权值参数为W1W_1(大小为3×9)和b1b_1(大小为3×1),激活函数为f1(x)=21+eax1f_1(x)=\dfrac{2}{1+e^{-ax}}-1,第二层到第三层之间权值参数为W2W_2(大小为1×3)和b2b_2(大小为1×1),激活函数为f2(x)=11+eaxf_2(x)=\dfrac{1}{1+e^{-ax}}

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%的识别率。