Tensorflow1.9全连接网络
一、全连接神经网络理论基础
1.生物神经元与人工神经元模型
2.人工神经元模型的组成部分
3.全连接网络的结构
二.激活函数
- 激活函数在线性模型的基础上加入非线性因素
常见的激活函数包括:
- 阈值激活函数
- ReLU函数
- Sigmoid函数
- tanh函数
- Softmax函数
1.Sigmod
- Logistic函数是一种常见的S形函数,又称为Sigmoid函数
- 取值范围为(O,1)
- 函数的导数为o(z)’= o(z)(1一o(z))
主要特点
- 容易导致梯度过饱和
- 均值不为0
2.tanh
- 公式为
- 取值范围为(-1,1)
主要特点: - 相比Sigmoid不容易导致梯度过饱和
- 均值为0
3.Relu
- 公式:
- 取值范围为[0,+oo)
主要特点: - 收敛速度快
- 容易梯度弥散
4.Softmax
- 公式
- 将一个K维的任意实数向量映射成另一个K维的实数向量,其中向量中的每个元素取值都介于(0,1)之间
三.损失函数
- 损失函数是神经网络优化的目标函数
- 反应神经网络对数据集的拟合程度,拟合越差,损失函数值越大
- 损失函数比较大时,其对应的梯度也要比较大,这样可以更快速地更新模型参数,也就是神经网络的权重
神经网络的损失函数特征 - 非负性
- 预测值和真实值接近时,损失函数值趋于零
1.均方误差
- 均方误差损失函数的直观意义明确: 预测值和真实值的欧式距离越大,损失就越大,反之就越小
- 均方误差损失函数常用于回归问题中
- 均方误差损失函数的数学表达式
2.交叉熵
- 交叉嫡(cross-entropy)损失函数
- 来源于信息论中熵的概念
- 神经网络处理分类问题常用的损失函数
- 训练数据固定时,最小化交叉熵等价于极大似然估计
四.反向传播算法
五、利用TensorFlow进行全连接网络的训练
1.实例1
# -*- coding: utf-8 -*-
# In[]
# 载入必要库
import tensorflow as tf
import numpy as np
# 定义训练集,二分类数据集,标签为{0,1}
def train_data():
# x的维度为(11, 1)
x = [[0.2], [0.4], [0.7], [1.2],
[1.4], [1.8], [1.9], [2], [0.11],
[0.16], [0.5]]
# y已经过One-Hot编码处理
y = [[1, 0],[1, 0],[1, 0],[0, 1],
[0, 1],[0, 1],[0, 1],[1, 0],[1, 0],
[1, 0],[1, 0]]
return (x, y)
# In[]
# 定义测试集
def tes_data():
# x的维度为(5, 1)
x = [[0.3], [0.6], [0.8], [1.3], [1.5]]
# y已经过One-Hot编码处理
y = [[1, 0],[1, 0],[1, 0],[0, 1],[0, 1]]
return (x, y)
# In[]
# 定义生成权重W的函数,形参为W的维度,权重采用正态分布初始化
num_w = 0
def weight_variable(shape):
# 定义全局变量,方便连续为权重命名
global num_w
name = 'weight' + str(num_w)
w = tf.get_variable(name, shape = shape,
initializer = tf.random_normal_initializer(stddev = 1, dtype = tf.float32))
#stddev为随机初始化
# 下一层权重命名的序号
num_w = num_w + 1
return w
# In[]
# 定义生成偏置b的函数,形参为b的维度,偏置采用正态分布初始化
num_b = 0
def bias_variable(shape):
# 定义全局变量,方便连续为偏置命名
global num_b
name = 'biase' + str(num_b)
b = tf.get_variable(name, shape = shape,
initializer = tf.random_normal_initializer(stddev = 1, dtype = tf.float32))
# 下一层的偏置命名的序号
num_b = num_b + 1
return b
# In[]
x = tf.placeholder(dtype = tf.float32, shape = [None, 1], name = 'x-input')
y_ = tf.placeholder(dtype = tf.float32, shape = [None, 2], name = 'y-input')
# In[]
# 定义两层网络的权重和偏置
# 隐层
# 3个神经元,共1×3个权重
w1 = weight_variable([1, 3])
# 3个偏置
b1 = weight_variable([3])
# 输出层
# 2个神经元,共3×2个权重
w2 = weight_variable([3, 2])
# 2个偏置
b2 = weight_variable([2])
# In[]
# 定义计算过程
# 隐层权重w1和偏置b1,激活函数为sigmoid
layer1 = tf.nn.sigmoid(tf.matmul(x, w1) + b1)
# 输出层权重w2和偏置b2 无激活函数
y = tf.matmul(layer1, w2) + b2
# In[]
# 定义损失函数为l2损失
loss = tf.nn.l2_loss(y - y_)
# In[]
# 定义优化方法为梯度下降,学习率为0.001,优化目标为最小化损失函数
train_op = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
# In[]
# 以分类正确率做为评价标准
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
# In[]
# 训练模型
with tf.Session() as sess:
# 变量初始化
sess.run(tf.global_variables_initializer())
# 定义训练数据与标签
x_train = train_data()[0]
y_train = train_data()[1]
# 给占位符喂数据并进行10000轮训练,
for i in range(10000):
sess.run(train_op, feed_dict={x: x_train, y_: y_train})
if i%1000 == 0:
print("epoch:", i, "test accuracy:", sess.run(accuracy, feed_dict={x: tes_data()[0], y_: tes_data()[1]}))
# 训练结束后,在测试集上做预测并输出分类正确率
print("test accuracy:",sess.run(accuracy, feed_dict={x: tes_data()[0], y_: tes_data()[1]}))
2.实例2
数据集下载地址:https://www.kaggle.com/datasets/dsrivastava2020/concretecsv
# 导入需要的包
import tensorflow as tf
from sklearn.model_selection import train_test_split
import pandas as pd
# 读取数据集
concrete = pd.read_csv("concrete.csv")
# 进行数据的归一化
concrete = concrete.apply(lambda x: (x-x.min())/(x.max()-x.min()))
X = concrete.drop('strength', axis = 1).values
y = concrete['strength'].values
# 将数据集分为训练集和测试集,测试集的比例为0.15
X_train,X_test,y_train,y_test = train_test_split(X, y, train_size=0.85, random_state=10)
# 设置学习率
learning_rate = 0.000001
# 设置训练轮数
training_epochs = 1000
## 每50轮展示当前模型的损失
display_step = 50
# 定义输入输出的张量占位符
x_ = tf.placeholder(shape=[None, 8], dtype=tf.float32, name="X_train")
y_ = tf.placeholder(shape=[None], dtype=tf.float32, name="y_train")
# 定义权重和偏置
with tf.variable_scope("DNN", reuse=tf.AUTO_REUSE):
# 设置模型的权重和偏置
W1 = tf.get_variable(initializer=tf.truncated_normal(shape=[8, 16], stddev=0.1), name="weight1") # 生成权重
b1 = tf.get_variable(initializer=tf.truncated_normal(shape=[16], stddev=0.1), name="bias1") # 生成偏置
W2 = tf.get_variable(initializer=tf.truncated_normal(shape=[16, 1], stddev=0.1), name="weight2") # 生成权重
b2 = tf.get_variable(initializer=tf.truncated_normal(shape=[1], stddev=0.1), name="bias2") # 生成偏置
layer1 = tf.nn.relu(tf.matmul(x_, W1)+b1)
y = tf.matmul(layer1, W2) + b2
# 定义损失,使用的是 l2 损失
loss = tf.nn.l2_loss(y-y_);
# 定义训练的优化方法,优化方法使用Adam,优化目标为最小化损失函数
with tf.variable_scope("Adam", reuse=tf.AUTO_REUSE):
train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)
# 建立会话运行程序
with tf.Session() as sess:
# 初始化变量
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 拟合训练数据
for epoch in range(training_epochs):
# 带入数据进行训练模型
_, cost = sess.run([train_op, loss], feed_dict={x_: X_train, y_: y_train})
# 展示训练的日志,输出损失
if (epoch + 1) % display_step == 0:
print("Epoch:", '%4d' % (epoch+1), "loss=", "{:.3f}".format(cost**0.5))
print("Optimization Finished!")
# 输出测试集预测结果
y_pred = sess.run(y, feed_dict={x_: X_test, y_:y_test})
# 计算最终损失函数
testing_loss = sess.run(loss, feed_dict={x_: X_train, y_: y_train})
print("Testing loss = %.3f" % testing_loss **0.5)