自然语言处理--keras构建神经网络实现异或问题(非线性)

Keras 是一个高级封装器,封装了面向 Python 的 API。API 接口可以与 3 个不同的后端库相兼容:Theano、谷歌的 TensorFlow 和微软的 CNTK。这几个库都在底层实现了基本的神经网络单元和高度优化的线性代数库,可以用于处理点积,以支持高效的神经网络矩阵乘法运算。

基本感知机有一个固有缺陷,那就是,如果数据不是线性可分的,或者数据之间的关系不能用线性关系来描述,模型将无法收敛,也将不具有任何有效预测的能力,因为它无法准确地预测目标变量。
现在我们使用神经网络来解决异或问题,它的数据集是线性不可分的:

import numpy as np
from keras.models import Sequential  # Kera 的基础模型类
from keras.layers import Dense, Activation  # Dense 是神经元的全连接层
from keras.optimizers import SGD  # 随机梯度下降,Keras 中还有一些其他优化器
import h5py
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

# 为NumPy和TensorFlow设置随机种子以确保可以得到一致的结果
np.random.seed(123)
tf.set_random_seed(123)

# 异或数据
# Our examples for an exclusive OR.
# x_train 是二维特征向量表示的训练样本列表
x_train = np.array([[0, 0],
                    [0, 1],
                    [1, 0],
                    [1, 1]])
# y_train 是每个特征向量样本对应的目标输出值
y_train = np.array([[0],
                    [1],
                    [1],
                    [0]])

# 用Sequential类来初始化一个新模型以实现前馈神经网络
model = Sequential()
num_neurons = 10
# 全连接隐藏层包含 10 个神经元
# 输入的 XOR 样本是二维特征向量,因此 input_dim 设置为 2
model.add(Dense(num_neurons, input_dim=2))
model.add(Activation('tanh'))
# 输出层包含一个神经元,输出结果是二分类值(0 或 1)
model.add(Dense(1))
model.add(Activation('sigmoid'))
# model.summary()提供了网络参数及各阶段权重数的概览
print(model.summary())

# 初始化模型
# 随机梯度下降优化器,模型用它来最小化误差或者损失
# (BGD为批梯度下降,即所有样本计算完毕后才进行梯度更新;
# 而SGD为随机梯度下降,随机计算一次样本就进行梯度下降,所以速度快很多但容易陷入局部最优值。
# 折中的办法是采用小批的梯度下降,即把数据分成若干个批次,一批来进行一次梯度下降,减少随机性,计算量也不是很大。)
# 随机梯度下降作为优化的算法。设置权重衰减常数(decay)和动量学习(momentum)来调整每个迭代的学习速度
#
# lr 是学习速率,与每个权重的误差的导数结合使用,数值越大模型的学习速度越快,但可能会使模型无法找到全
# 局极小值,数值越小越精确,但会增加训练时间,并使模型更容易陷入局部极小值。
sgd = SGD(lr=0.1)
# compile 方法进行编译,此时还未开始训练模型,只对权重进行了初始化
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])

# 用随机初始状态来预测,当然得到的结果只是随机猜测
print( model.predict(x_train))

# 用异或训练集进行模型训练
model.fit(x_train, y_train, epochs=200)

# 预测
print(model.predict_classes(x_train))
print( model.predict(x_train))

# 保存训练好的模型
# 用 Keras 的辅助方法将网络结构导出为 JSON blob 类型
model_structure = model.to_json()
# 第一部分只保存网络结构;在后面重新加载网络结构时必须对其重新实例化,
# 重新实例化模型,这样做预测时不必再去重新训练模型
with open("basic_model.json", "w") as json_file:
    json_file.write(model_structure)
# 训练好的权重必须被单独保存
model.save_weights("basic_weights.h5")

猜你喜欢

转载自blog.csdn.net/fgg1234567890/article/details/112709356