1 M-P神经元与神经网络前向传输
1.1 训练单个神经元
一个含有两个输入的神经元,指定一个输入x1=x2=1,期望y能输出0.3。要求不断的输入x1=x2=1,然后不断的训练权重w与偏置b值,训练一万次后,再次输入x1与x2输出y的值是否为0.3
# 导入TensorFlow库,并重新命名为tf,以下代码调用TensorFlow时使用tf
import tensorflow as tf
# 声明输入x的占位符,矩阵大小为1行2列
x = tf.placeholder(tf.float32, [1, 2])
# w是图中权重的变量是一个2行1列的矩阵。矩阵的初值为符合正太分布随机值的变量
w = tf.Variable(tf.truncated_normal([2, 1]), name="weight")
# b计算偏置值,初值为的符合正太分布随机值的变量
b = tf.Variable(tf.truncated_normal([1]), name="bias")
# 将加权值加上偏置值传入sigmod激活函数中
y = tf.nn.sigmoid(tf.matmul(x, w) + b)
# 实际的y值,此处仅定义占位。在运算过程中进行赋值
y_ = tf.placeholder(tf.float32, [1])
# 计算实际值与通过w与b计算出的y值做误差计算
cross_entropy = tf.reduce_mean(tf.square(y_ - y))
# 通过误差使用梯度下降更新w与b值
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 初始化所有变量值
init = tf.global_variables_initializer()
# 在会话中运行程序,计算出w与b值
with tf.Session() as sess:
sess.run(init)
for line in range(10000):
sess.run(train_step, feed_dict={x: [[1, 1]], y_: [0.3]})
print(line + 1, sess.run(w, feed_dict={x: [[1, 1]]}))
# 将x1与x2代入经过训练的模型中,并打印出y可与原y值进行比较
print(sess.run(y, feed_dict={x: [[1, 1]]}))
1.2 神经网络前向传输
# 导入tensorflow的类库
import tensorflow as tf
# 声明一个常量
x = tf.constant([[0.7, 0.9]])
# 声明两个权重矩阵
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
# 实现矩阵乘法
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 在会话中运行计算图
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print(sess.run(y))
2训练BP神经网络模型参数
2.1 神经网络前行传输过程
2.2 训练神经网络模型
如有一个判断零件是否合格的神经网络模型,输入零件的长度和质量,从而检测文件是否合格,要求训练一个神经网络模型,最终输出训练后的w值。
# 导入tensorflow库,并重新命名为tf。以下代码调用tensorflow时使用tf
import tensorflow as tf
# numpy工具包生成模拟数据集,使用RandomState获得随机数生成器
from numpy.random import RandomState
######定义神经网络的结构和向前出参数的输出结果。
batch_size = 8
# w1是图中权重的变量是一个2行3列的矩阵。矩阵的初值为符合正太分布随机值的变量
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
# w2是图中权重的变量是一个3行1列的矩阵。矩阵的初值为符合正太分布随机值的变量
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
# x输入值的占位符,此处仅定义占位。在运算过程中进行赋值
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
# 实际的y_值,此处仅定义占位。在运算过程中进行赋值
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
# 前向计算y值
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
######定义损失函数以及选择反向传播优化的算法
# 计算损失,本实训使用均方误差计算损失函数
loss_value = tf.reduce_mean(tf.square(y_ - y))
# 反向优化参数,Adam梯度下降算法根据损失函数
train_step = tf.train.AdamOptimizer(0.001).minimize(loss_value)
######生成会话并且在训练数据上反复进行反向传播优化算法# 利用numpy提供的随机函数生成x数据
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)
# 通过x计算y值
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X] # 列表解析式
# 训练准备工作
with tf.Session() as sess:
init_op = tf.global_variables_initializer() # 初始化变量
sess.run(init_op)
print("*********训练之前的初始权重weights的值:")
print(sess.run(w1))
print(sess.run(w2))
STEPS = 5000
print("*******开始训练**************")
# 将数据分批次进入训练模型中
for i in range(STEPS):
start = (i * batch_size) % dataset_size
end = min(start + batch_size, dataset_size)
# Tensorflow的Session才是真正开始训练的过程,将x与y值送入PlaceHolder(占位符)中
sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
# 每运行1000次后,打印训练结果
if i % 1000 == 0:
loss = sess.run(loss_value, feed_dict={x: X, y_: Y})
print("After %d training step(s) , loss_value on all data is %f" % (i, loss))
print("*********训练之后的权重weights的值:")
print(sess.run(w1))
print(sess.run(w2))
3 激活函数实现非线性化
3.1 使用sigmoid激活函数
定义一个二维张量,通过sigmoid激活函数将其映射到0-1范围内,并输出映射后的值。
# 导入tensorflow类库,简称为tf
import tensorflow as tf
# 定义输入数据
input_data = tf.Variable([[0, 10, -10], [1, 2, 3]], dtype=tf.float32)
# 使用sigmoid激活函数
output = tf.nn.sigmoid(input_data)
init_op = tf.global_variables_initializer()
# 创建会话,并使用上下文管理器管理会话
with tf.Session() as sess:
sess.run(init_op)
# 在会话中运行节点,实现输出
print(sess.run(output))
3.2使用tanh激活函数
定义一个张量,使用tanh激活函数将其映射到-1~1之间,并输出映射后的值。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义输入tensor
input = tf.constant([-2, -8, 2, 8], dtype=tf.float32)
# 使用tanh激活函数
output = tf.nn.tanh(input)
# 创建会话,并在上下文中输出
with tf.Session() as sess:
# 打印输出节点
print(sess.run(output))
3.3使用relu激活函数
定义一个张量[-10,0,4,8],使用relu激活函数使其能自动的忽略负值,并输出映射后的值。
# 导入tensorflow类库,简称为tf
import tensorflow as tf
# 定义输入tensor
input = tf.constant([-10, 0, 4, 8], dtype=tf.float32)
# 使用relu激活函数
output = tf.nn.relu(input)
# 创建会话,并在上下文中输出
with tf.Session() as sess:
# 打印输出节点
print(sess.run(output))
4 损失函数
4.1 分类问题的损失函数
softmax
定义一个张量,通过softmax输出属于各个类别的概率。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义一个常量
s = tf.constant([1, 1, 2, 3, 4, 5, 10], dtype=tf.float32)
# 使用sofmax函数输出类别概率
sm = tf.nn.softmax(s)
# 创建一个会话,使用上下文管理器管理会话
with tf.Session()as sess:
# 在会话中输出结果
print(sess.run(sm))
交叉熵损失函数
计算两个张量之间的交叉熵,并将交叉熵结果输出。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义输入的tensor
input_data = tf.Variable([[0.2, 0.1, 0.9], [0.3, 0.4, 0.6]], dtype=tf.float32)
# 定义标签
labels = tf.constant([[1, 0, 0], [0, 1, 0]], dtype=tf.float32)
# 计算交叉熵
cross_entropy = -tf.reduce_mean(labels * tf.log(tf.clip_by_value(input_data, 1e-10, 1.0)))
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
# 输出两个交叉熵
print(sess.run(cross_entropy))
4.2回归问题的损失函数
均方误差
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义张量a
a = tf.constant([[4.0, 4.0, 4.0], [3.0, 3.0, 3.0], [1.0, 1.0, 1.0]])
# 定义张量b
b = tf.constant([[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [2.0, 2.0, 2.0]])
# 计算均方误差
mse = tf.reduce_mean(tf.square(a - b))
with tf.Session() as sess:
# 输出均方误差的值
print(sess.run(mse))
5 梯度下降
5.1 梯度下降
使用梯度下降法实现y=x2,x初始值为5,求y的最小值。学习率设置为0.001,每1000轮更新一次y的值。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义训练的轮数
TRAINING_STEPS = 10000
# 定义学习率
LEARNING_RATE = 0.001
# 定义x变量
x = tf.Variable(tf.constant(5, dtype=tf.float32), name="x")
# 实现模型
y = tf.square(x)
# 使用随机梯度下降最小化y
train_op = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(y)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(TRAINING_STEPS):
# 输出每一步训练的值
sess.run(train_op)
if i % 1000 == 0:
x_value = sess.run(x)
print("After %s iteration(s): x%s is %f." % (i + 1, i + 1, x_value))
5.2 反向传播
构建房屋预测模型,打印每轮训练的数据。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义网络权重
W = tf.Variable(tf.ones([2, 1]), tf.float32)
# 定义网络偏置项
b = tf.Variable([5.0], tf.float32)
# 定义输入占位符
x = tf.placeholder(tf.float32, [None, 2])
# 定义输出占位符
y = tf.placeholder(tf.float32)
# 定义向前传输模型
y_ = tf.matmul(x, W) + b
# 定义损失函数
loss = tf.reduce_sum(tf.square(y_ - y))
# 定义优化器
optimizer = tf.train.AdamOptimizer(0.01)
train = optimizer.minimize(loss)
# 输入数据
x_train = [[2104, 3], [1600, 3], [2400, 3], [1416, 2], [3000, 4]]
# 输入标签
y_train = [400, 330, 369, 232, 540]
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
# 训练40000轮
for i in range(40000):
curr_W, curr_b, _ = sess.run([W, b, train], {x: x_train, y: y_train})
if i % 500 == 0:
print("Step:%s W: %s b: %s" % (i, curr_W, curr_b,))
# 训练完成后,输出损失函数和w及b
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s" % (curr_W, curr_b, curr_loss))
6 优化模型
6.1指数衰减学习率
使用指数衰减学习率,定义一个全局变量,每训练一次,全局变量的值加1。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
# 定义全局训练的步数
global_step = tf.Variable(0, trainable=False)
# 定义学习率为0.1
initial_learning_rate = 0.1
# 定义指数衰减学习率
learning_rate = tf.train.exponential_decay(learning_rate=initial_learning_rate, global_step=global_step, decay_steps=10,
decay_rate=0.85)
# 使用梯度下降法
op = tf.train.GradientDescentOptimizer(learning_rate)
# 每次训练完成之后加1
add_global = global_step.assign_add(1)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(20):
# 每次训练完成之后打印学习率
g, rate = sess.run([add_global, learning_rate])
print(g, rate)
6.2正则化及正则化集合
L1正则化、L2正则化
定义一个矩阵,利用L1正则化、L2正则化和两者的正则化,打印正则化后的值。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
from tf_slim import l1_regularizer, l2_regularizer, l1_l2_regularizer
tf.disable_eager_execution()
# 声明w为二维矩阵
W = tf.constant([[1.0, -2.0], [-3.0, 4.0]])
# 建立session上下文
with tf.Session() as sess:
# 为L1正则化,(1+2+3+4)*0.5 = 5.0
print(sess.run(l1_regularizer(.5)(W)))
# 为L2正则化,(1+4+9+16)*0.5=7.5
print(sess.run(l2_regularizer(.5)(W)))
# 为L1 + L2正则化,5.0 + 7.5 = 12.5
print(sess.run(l1_l2_regularizer(.5, .5)(W)))
正则化集合:
通过正则化集合的方式将正则化添加到整个神经网络中。
# 导入tensorflow类库,简称为tf
import tensorflow.compat.v1 as tf
from tf_slim import l2_regularizer
tf.disable_eager_execution()
# 获取一层神经网络的权重,并将权重的L2正则化损失加入到集合中
def get_weight(shape, lamda):
# 定义变量
var = tf.Variable(tf.random_normal(shape=shape), dtype=tf.float32)
# 将变量的L2正则化损失添加到集合中
tf.add_to_collection("losses", l2_regularizer(lamda)(var))
return var
if __name__ == "__main__":
# 定义输入节点
x = tf.placeholder(tf.float32, shape=(None, 2))
# 定义输出节点
y_ = tf.placeholder(tf.float32, shape=(None, 1))
# 定义每次迭代数据的大小
batch_size = 8
# 定义五层神经网络,并设置每一层神经网络的节点数目
layer_dimension = [2, 10, 10, 10, 1]
# 获取神经网络的层数
n_layers = len(layer_dimension)
# 定义神经网络第一层的输入
cur_layer = x
# 当前层的节点个数
in_dimension = layer_dimension[0]
# 通过循环来生成5层全连接的神经网络结构
for i in range(1, n_layers):
# 定义神经网络上一层的输出,下一层的输入
out_dimension = layer_dimension[i]
# 定义当前层中权重的变量,并将变量的L2损失添加到计算图的集合中
weight = get_weight([in_dimension, out_dimension], 0.001)
# 定义偏置项
bias = tf.Variable(tf.constant(0.1, shape=[out_dimension]))
# 使用RELU激活函数
cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)
# 定义下一层神经网络的输入节点数
in_dimension = layer_dimension[i]
# 定义均方差的损失函数
mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
# 将均方差孙函数添加到集合
tf.add_to_collection("losses", mse_loss)
# 获取整个模型的损失函数,tf.get_collection("losses")返回集合中定义的损失
# 将整个集合中的损失相加得到整个模型的损失函数
loss = tf.add_n(tf.get_collection("losses"))
7 实例:预测泰坦尼克号生存率
# 导入panda类库
import pandas as pd
# 导入selection类库
from sklearn.model_selection import train_test_split
# 导入tensorflow类库
import tensorflow.compat.v1 as tf
# 导入numpy类库
import numpy as np
tf.disable_eager_execution()
# 读取数据文件
data = pd.read_csv("Titanic数据集/train.csv")
# 对数据文件数据进行预处理
data['Sex'] = data['Sex'].apply(lambda s: 1 if s == 'male' else 0)
data = data.fillna(0)
dataset_X = data[['Sex', 'Age', 'Pclass', 'SibSp', 'Parch', 'Fare']]
dataset_X = dataset_X.values
data['Deceased'] = data['Survived'].apply(lambda s: int(not s))
dataset_Y = data[['Deceased', 'Survived']]
dataset_Y = dataset_Y.values
X_train, X_val, y_train, y_val = train_test_split(dataset_X, dataset_Y, test_size=0.2, random_state=1)
# 声明占位符
X = tf.placeholder(tf.float32, shape=[None, 6])
y = tf.placeholder(tf.float32, shape=[None, 2])
# 声明变量
W = tf.Variable(tf.random_normal([6, 2]), name='weights')
# 声明偏置项目
bias = tf.Variable(tf.zeros([2]), name='bias')
# 实现节点计算
y_pred = tf.nn.softmax(tf.matmul(X, W) + bias)
# 计算交叉熵
cross_entropy = -tf.reduce_sum(y * tf.log(y_pred + 1e-10), reduction_indices=1)
# 计算损失函数
cost = tf.reduce_mean(cross_entropy)
# 使用梯度下降最小化损失函数
train_op = tf.train.GradientDescentOptimizer(0.001).minimize(cost)
# 建立会话
with tf.Session()as sess:
# 初始化所有变量
tf.global_variables_initializer().run()
# 训练100轮
for epoch in range(100):
total_loss = 0.
for i in range(len(X_train)):
# 向神经网络中喂入数据
feed = {X: [X_train[i]], y: [y_train[i]]}
# 计算损失函数
_, loss = sess.run([train_op, cost], feed_dict=feed)
if epoch % 10 == 0:
print('Epoch: %04d, total loss=%.5f' % (epoch + 1, loss))
print('Training complete!')
pred = sess.run(y_pred, feed_dict={X: X_val})
# 计算预测是否正确
correct = np.equal(np.argmax(pred, 1), np.argmax(y_val, 1))
# 计算所有准确率
accuracy = np.mean(correct.astype(np.float32))
print("Accuracy on validation set: %.9f" % accuracy)
Epoch: 0001, total loss=0.01460
Epoch: 0011, total loss=0.00436
Epoch: 0021, total loss=0.00371
Epoch: 0031, total loss=0.00315
Epoch: 0041, total loss=0.00263
Epoch: 0051, total loss=0.00221
Epoch: 0061, total loss=0.00182
Epoch: 0071, total loss=0.00149
Epoch: 0081, total loss=0.00123
Epoch: 0091, total loss=0.00103
Training complete!
Accuracy on validation set: 0.670391083