# -*- coding= UTF-8 -*-
import tensorflow as tf
#通过Numpy工具包生成模拟数据集
from numpy.random import RandomState
#定义数据训练batch大小
batch_size = 8
#定义神经网络参数
w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))
#定义placeholder作为存放输入数据的地方,这里的维度也不一定要定义。
"""
在shape的一个维度上使用None可以方便使用不同的batch大小。在训练时需要把数据分成比较小的batch,但是在测试时,可以一次性使用全部的数据。当数据集比较小时这样比较方便测试,但是数据集比较大时,将大量数据放入一个batch可能会导致内存溢出
"""
x = tf.placeholder(tf.float32, shape=(None,2), name="x-input")
y_ = tf.placeholder(tf.float32, shape=(None,1), name="y-input")
#定义一个前向传播网络,未加激活函数,因此现在是线性模式。
"""
线性模型存在的问题是,解决问题的能力有限。
添加非线性激活函数和偏置项
a = tf.nn.relu(tf.matmul(x,w1) + biases1)
y = tf.nn.relu(tf.matmul(a,w2) + biases2)
"""
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
#损失函数
y = tf.sigmoid(y)
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)) + (1-y_)*tf.log(tf.clip_by_value(1-y, 1e-10, 1.0))) #1e-10是指数形式表示,表示的值为十的负十次幂
#学习率
learning_rate = 0.01
#定义反向传播算法来优化模型参数
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy) #AdamOptimizer:自适应优化器
#随机生成一个模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size,2)
#定义规则给定样本的标签,如果x1+x2 <1视为正样本,其他视为负样本
Y = [[int((x1+x2) < 1)] for (x1,x2) in X]
#创建一个会话来运行TensorFlow程序
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
#初始化变量
sess.run(init_op)
print("原始")
print(sess.run(w1))
print(sess.run(w2))
print("原始")
#设定迭代次数
steps = 5000
for i in range(steps):
#每次选取batch_size个样本进行训练
start = (i * batch_size) % dataset_size
end = min(start+batch_size, dataset_size)
#通过选取的样本训练神经网络并跟新参数
sess.run(train_step, feed_dict={x : X[start:end], y_ : Y[start:end]})
if i % 100 == 0:
#每隔一段时间计算在所有数据上的交叉熵并输出
total_cross_entropy = sess.run(
cross_entropy, feed_dict={x : X, y_ : Y})
print("After %d training step, cross entropy on all data is %g" %(i, total_cross_entropy))
print("结束")
print(sess.run(w1))
print(sess.run(w2))
print("结束")
学习记录:
TensorFlow中的所有运算的输入、输出都是张量,张量本身并不存储任何数据,它只是对运算结果的引用。包括三种属性:名字(name)、维度(shape)、类型(type)
在运行中犯的错误:设定迭代次数这一步骤开始,直接在Session会话外执行的,表现的形式是:steps = 5000 往后的代码没有缩进,直接与with tf.Session() as sess: 对齐了 导致运行报错:RuntimeError: Attempted to use a closed Session.
原因:网络模型的所有运算都需要在会话中进行计算, 使用with语句运行一次后,会话会自动关闭,后续计算需要重新打开会话。
以上代码来自书籍TensorFlow实战Google深度学习框架。
整体流程:
1、定义神经网络结构和前向传播的输出结果
2、定义损失函数以及选择反向传播优化算法
3、生成会话并在数据集上反复运行反向传播优化算法
关于正则化添加:
"""
添加L2正则化
"""
import tensorflow as tf
#获取一层神经网络边上的权重,并将这个权重的L2正则化损失函数加入名称为“losses”集合中
def get_weight(shape, lambda1):
#生成一个变量
var = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
#add_to_collection函数将这个新生成变量的L2正则化损失项加入集合。
#这个函数的第一个参数“losses”是集合的名字,第二个参数是要加入这个集合的内容。
tf.add_to_collection(
'losses',tf.contrib.layers.l2_regularizer(lambda1)(var))
#返回生成的变量
return var
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):
#layer_dimension[i]为下一层的节点个数
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]
#定义神经网络前向传播的同时已经将所有的L2正则化损失加入了图的集合,
#这里只需要计算刻画模型在训练数据上表现的损失函数。
mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
#将均方误差损失函数加入损失集合。
tf.add_to_collection('losses', mse_loss)
#get_collection返回一个列表,这个列表是所有这个集合中的元素。在这个样例中,
#这些元素就是损失函数的不同部分,将他们加起来就可以得到最终的损失函数
loss = tf.add_n(tf.get_collection('losses'))
print(loss)
正则化思想就是在损失函数中家兔刻画模型复杂程度的指标。假设用于刻画模型在训练数据上表现的损失函数为,那么在优化时不是直接优化
,而是优化
。其中
刻画的是模型的复杂程度,而
表示模型复杂损失在总损失中的比例。
L1正则化: L2正则表达式:
L1正则化会让参数变得更稀疏,L2不会。所谓参数变得更稀疏是指挥有更多的参数变为0,这样可以达到类似特征选取的功能。