【4】tf实现神经网络模型

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小镇躺不平家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值